^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Rockchip USB2.0 PHY with Innosilicon IP block driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/extcon-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/rockchip/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/usb/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/usb/otg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/usb/role.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/usb/typec_mux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/wakelock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define BIT_WRITEABLE_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SCHEDULE_DELAY (60 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define OTG_SCHEDULE_DELAY (1 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define BYPASS_SCHEDULE_DELAY (2 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define FILTER_COUNTER 0xF4240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct rockchip_usb2phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) enum rockchip_usb2phy_port_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) USB2PHY_PORT_OTG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) USB2PHY_PORT_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) USB2PHY_NUM_PORTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) enum rockchip_usb2phy_host_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) PHY_STATE_HS_ONLINE = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) PHY_STATE_DISCONNECT = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) PHY_STATE_CONNECT = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) PHY_STATE_FS_LS_ONLINE = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * enum usb_chg_state - Different states involved in USB charger detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @USB_CHG_STATE_UNDEFINED: USB charger is not connected or detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * process is not yet started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @USB_CHG_STATE_WAIT_FOR_DCD: Waiting for Data pins contact.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @USB_CHG_STATE_DCD_DONE: Data pin contact is detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @USB_CHG_STATE_PRIMARY_DONE: Primary detection is completed (Detects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * between SDP and DCP/CDP).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * @USB_CHG_STATE_SECONDARY_DONE: Secondary detection is completed (Detects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * between DCP and CDP).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @USB_CHG_STATE_DETECTED: USB charger type is determined.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) enum usb_chg_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) USB_CHG_STATE_UNDEFINED = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) USB_CHG_STATE_WAIT_FOR_DCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) USB_CHG_STATE_DCD_DONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) USB_CHG_STATE_PRIMARY_DONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) USB_CHG_STATE_SECONDARY_DONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) USB_CHG_STATE_DETECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static const unsigned int rockchip_usb2phy_extcon_cable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) EXTCON_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) EXTCON_USB_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) EXTCON_USB_VBUS_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) EXTCON_CHG_USB_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) EXTCON_CHG_USB_CDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) EXTCON_CHG_USB_DCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) EXTCON_CHG_USB_SLOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) EXTCON_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct usb2phy_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned int bitend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned int bitstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned int disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned int enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * struct rockchip_chg_det_reg - usb charger detect registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @cp_det: charging port detected successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @dcp_det: dedicated charging port detected successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @dp_det: assert data pin connect successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @idm_sink_en: open dm sink curren.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @idp_sink_en: open dp sink current.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @idp_src_en: open dm source current.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @rdm_pdwn_en: open dm pull down resistor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @vdm_src_en: open dm voltage source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @vdp_src_en: open dp voltage source.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @chg_mode: set phy in charge detection mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct rockchip_chg_det_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct usb2phy_reg cp_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct usb2phy_reg dcp_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct usb2phy_reg dp_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct usb2phy_reg idm_sink_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct usb2phy_reg idp_sink_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct usb2phy_reg idp_src_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct usb2phy_reg rdm_pdwn_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct usb2phy_reg vdm_src_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct usb2phy_reg vdp_src_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct usb2phy_reg chg_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * struct rockchip_usb2phy_port_cfg - usb-phy port configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @phy_sus: phy suspend register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @pipe_phystatus: select pipe phystatus from grf or phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @bvalid_det_en: vbus valid rise detection enable register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * @bvalid_det_st: vbus valid rise detection status register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * @bvalid_det_clr: vbus valid rise detection clear register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * @bvalid_grf_con: vbus valid software control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @bvalid_grf_sel: vbus valid software control select.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @bvalid_phy_con: vbus valid external select and enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @bypass_dm_en: usb bypass uart DM enable register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @bypass_sel: usb bypass uart select register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @bypass_iomux: usb bypass uart GRF iomux register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @bypass_bc: bypass battery charging module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @bypass_otg: bypass otg module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @bypass_host: bypass host module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * @disfall_en: host disconnect fall edge detection enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * @disfall_st: host disconnect fall edge detection state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * @disfall_clr: host disconnect fall edge detection clear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * @disrise_en: host disconnect rise edge detection enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @disrise_st: host disconnect rise edge detection state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @disrise_clr: host disconnect rise edge detection clear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * @ls_det_en: linestate detection enable register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @ls_det_st: linestate detection state register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * @ls_det_clr: linestate detection clear register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * @iddig_output: iddig output from grf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @iddig_en: utmi iddig select between grf and phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * 0: from phy; 1: from grf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @idfall_det_en: id fall detection enable register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @idfall_det_st: id fall detection state register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @idfall_det_clr: id fall detection clear register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @idrise_det_en: id rise detection enable register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @idrise_det_st: id rise detection state register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @idrise_det_clr: id rise detection clear register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @utmi_avalid: utmi vbus avalid status register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @utmi_bvalid: utmi vbus bvalid status register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * @utmi_iddig: otg port id pin status register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * @utmi_ls: utmi linestate state register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * @utmi_hstdet: utmi host disconnect register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * @vbus_det_en: vbus detect function power down register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct rockchip_usb2phy_port_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct usb2phy_reg phy_sus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct usb2phy_reg pipe_phystatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct usb2phy_reg bvalid_det_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct usb2phy_reg bvalid_det_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct usb2phy_reg bvalid_det_clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct usb2phy_reg bvalid_grf_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct usb2phy_reg bvalid_grf_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct usb2phy_reg bvalid_phy_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct usb2phy_reg bypass_dm_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct usb2phy_reg bypass_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct usb2phy_reg bypass_iomux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct usb2phy_reg bypass_bc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct usb2phy_reg bypass_otg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct usb2phy_reg bypass_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct usb2phy_reg disfall_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct usb2phy_reg disfall_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct usb2phy_reg disfall_clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct usb2phy_reg disrise_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct usb2phy_reg disrise_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct usb2phy_reg disrise_clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct usb2phy_reg ls_det_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct usb2phy_reg ls_det_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct usb2phy_reg ls_det_clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct usb2phy_reg iddig_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct usb2phy_reg iddig_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct usb2phy_reg idfall_det_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct usb2phy_reg idfall_det_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct usb2phy_reg idfall_det_clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct usb2phy_reg idrise_det_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct usb2phy_reg idrise_det_st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct usb2phy_reg idrise_det_clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct usb2phy_reg utmi_avalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct usb2phy_reg utmi_bvalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct usb2phy_reg utmi_iddig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct usb2phy_reg utmi_ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct usb2phy_reg utmi_hstdet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct usb2phy_reg vbus_det_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * struct rockchip_usb2phy_cfg - usb-phy configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * @reg: the address offset of grf for usb-phy config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * @num_ports: specify how many ports that the phy has.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * @phy_tuning: phy default parameters tuning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * @vbus_detect: vbus voltage level detection function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * @clkout_ctl: keep on/turn off output clk of phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * @ls_filter_con: set linestate filter time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * @port_cfgs: usb-phy port configurations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * @ls_filter_con: set linestate filter time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * @chg_det: charger detection registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct rockchip_usb2phy_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned int num_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int (*phy_tuning)(struct rockchip_usb2phy *rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int (*vbus_detect)(struct rockchip_usb2phy *rphy, bool en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct usb2phy_reg clkout_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct usb2phy_reg ls_filter_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) const struct rockchip_chg_det_reg chg_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * struct rockchip_usb2phy_port - usb-phy port data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @phy: generic phy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * @port_id: flag for otg port or host port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * @low_power_en: enable enter low power when suspend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * @perip_connected: flag for periphyeral connect status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * @prev_iddig: previous otg port id pin status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @sel_pipe_phystatus: select pipe phystatus from grf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * @suspended: phy suspended flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * @typec_vbus_det: Type-C otg vbus detect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @utmi_avalid: utmi avalid status usage flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * true - use avalid to get vbus status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * false - use bvalid to get vbus status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * @vbus_attached: otg device vbus status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * @vbus_always_on: otg vbus is always powered on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @vbus_enabled: vbus regulator status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * @bypass_uart_en: usb bypass uart enable, passed from DT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * @host_disconnect: usb host disconnect status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * @ls_irq: IRQ number assigned for linestate detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * @id_irq: IRQ number assigned for id fall or rise detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * irqs to one irq in otg-port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * @mutex: for register updating in sm_work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * @chg_work: charge detect work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * @bypass_uart_work: usb bypass uart work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * @otg_sm_work: OTG state machine work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * @sm_work: HOST state machine work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * @vbus: vbus regulator supply on few rockchip boards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @sw: orientation switch, communicate with TCPM (Type-C Port Manager).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * @port_cfg: port register configuration, assigned by driver data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * @event_nb: hold event notification callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @state: define OTG enumeration states before device reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * @mode: the dr_mode of the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct rockchip_usb2phy_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned int port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) bool low_power_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) bool perip_connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) bool prev_iddig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) bool sel_pipe_phystatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) bool suspended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) bool typec_vbus_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) bool utmi_avalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) bool vbus_attached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) bool vbus_always_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) bool vbus_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) bool bypass_uart_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) bool host_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int bvalid_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int ls_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int id_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int otg_mux_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct delayed_work bypass_uart_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct delayed_work chg_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct delayed_work otg_sm_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct delayed_work sm_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct regulator *vbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct typec_switch *sw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) const struct rockchip_usb2phy_port_cfg *port_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct notifier_block event_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct wake_lock wakelock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) enum usb_otg_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) enum usb_dr_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * struct rockchip_usb2phy - usb2.0 phy driver data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * @dev: pointer to device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * @grf: General Register Files regmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * @usbgrf: USB General Register Files regmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * @usbctrl_grf: USB Controller General Register Files regmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * *phy_base: the base address of USB PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * @phy_reset: phy reset control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * @clks: array of phy input clocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * @clk480m: clock struct of phy output clk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * @clk480m_hw: clock struct of phy output clk management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * @num_clks: number of phy input clocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * @chg_state: states involved in USB charger detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * @chg_type: USB charger types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * @dcd_retries: The retry count used to track Data contact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * detection process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * @primary_retries: The retry count used for charger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * detection primary phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * @phy_sus_cfg: Store the phy current suspend configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * @edev_self: represent the source of extcon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * @irq: IRQ number assigned for phy which combined irqs of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * otg port and host port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * @edev: extcon device for notification registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * @phy_cfg: phy register configuration, assigned by driver data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * @ports: phy port instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct rockchip_usb2phy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct regmap *grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct regmap *usbgrf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct regmap *usbctrl_grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) void __iomem *phy_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct reset_control *phy_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct clk_bulk_data *clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct clk *clk480m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct clk_hw clk480m_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int num_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) enum usb_chg_state chg_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) enum power_supply_type chg_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) u8 dcd_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u8 primary_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned int phy_sus_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) bool edev_self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct extcon_dev *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) const struct rockchip_usb2phy_cfg *phy_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static inline int property_enable(struct regmap *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) const struct usb2phy_reg *reg, bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned int val, mask, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) tmp = en ? reg->enable : reg->disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) mask = GENMASK(reg->bitend, reg->bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return regmap_write(base, reg->offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static inline bool property_enabled(struct regmap *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) const struct usb2phy_reg *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) unsigned int tmp, orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ret = regmap_read(base, reg->offset, &orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) tmp = (orig & mask) >> reg->bitstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return tmp == reg->enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static inline void phy_clear_bits(void __iomem *reg, u32 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) u32 tmp = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) tmp &= ~bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) writel(tmp, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static inline void phy_set_bits(void __iomem *reg, u32 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) u32 tmp = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) tmp |= bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) writel(tmp, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static inline void phy_update_bits(void __iomem *reg, u32 mask, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u32 tmp = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) tmp &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) tmp |= val & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) writel(tmp, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (!rphy->phy_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ret = reset_control_assert(rphy->phy_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ret = reset_control_deassert(rphy->phy_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct rockchip_usb2phy *rphy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) container_of(hw, struct rockchip_usb2phy, clk480m_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* turn on 480m clk output if it is off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* waiting for the clk become stable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) usleep_range(1200, 1300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct rockchip_usb2phy *rphy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) container_of(hw, struct rockchip_usb2phy, clk480m_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* turn off 480m clk output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct rockchip_usb2phy *rphy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) container_of(hw, struct rockchip_usb2phy, clk480m_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return 480000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static const struct clk_ops rockchip_usb2phy_clkout_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .prepare = rockchip_usb2phy_clk480m_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .unprepare = rockchip_usb2phy_clk480m_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .is_prepared = rockchip_usb2phy_clk480m_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static void rockchip_usb2phy_clk480m_unregister(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct rockchip_usb2phy *rphy = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) of_clk_del_provider(rphy->dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) clk_unregister(rphy->clk480m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct device_node *node = rphy->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct clk_init_data init = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct clk *refclk = of_clk_get_by_name(node, "phyclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) const char *clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) init.name = "clk_usbphy_480m";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) init.ops = &rockchip_usb2phy_clkout_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* optional override of the clockname */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) of_property_read_string(node, "clock-output-names", &init.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!IS_ERR(refclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) clk_name = __clk_get_name(refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) init.parent_names = &clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) init.parent_names = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) init.num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) rphy->clk480m_hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* register the clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) rphy->clk480m = clk_register(rphy->dev, &rphy->clk480m_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (IS_ERR(rphy->clk480m)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ret = PTR_ERR(rphy->clk480m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ret = of_clk_add_provider(node, of_clk_src_simple_get, rphy->clk480m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) goto err_clk_provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ret = devm_add_action(rphy->dev, rockchip_usb2phy_clk480m_unregister,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) goto err_unreg_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) err_unreg_action:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) of_clk_del_provider(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) err_clk_provider:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) clk_unregister(rphy->clk480m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) err_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct device_node *node = rphy->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct extcon_dev *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (of_property_read_bool(node, "extcon")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) edev = extcon_get_edev_by_phandle(rphy->dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (IS_ERR(edev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (PTR_ERR(edev) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dev_err(rphy->dev, "Invalid or missing extcon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return PTR_ERR(edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* Initialize extcon device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) edev = devm_extcon_dev_allocate(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) rockchip_usb2phy_extcon_cable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (IS_ERR(edev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ret = devm_extcon_dev_register(rphy->dev, edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) dev_err(rphy->dev, "failed to register extcon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) rphy->edev_self = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) rphy->edev = edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* The caller must hold rport->mutex lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static int rockchip_usb2phy_enable_id_irq(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ret = property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) ret = property_enable(rphy->grf, &rport->port_cfg->idfall_det_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) ret = property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ret = property_enable(rphy->grf, &rport->port_cfg->idrise_det_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* The caller must hold rport->mutex lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static int rockchip_usb2phy_enable_vbus_irq(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ret = property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ret = property_enable(rphy->grf, &rport->port_cfg->bvalid_det_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static int rockchip_usb2phy_enable_line_irq(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ret = property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ret = property_enable(rphy->grf, &rport->port_cfg->ls_det_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int rockchip_usb2phy_enable_host_disc_irq(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ret = property_enable(rphy->grf, &rport->port_cfg->disfall_clr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ret = property_enable(rphy->grf, &rport->port_cfg->disfall_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ret = property_enable(rphy->grf, &rport->port_cfg->disrise_clr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ret = property_enable(rphy->grf, &rport->port_cfg->disrise_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static int rockchip_usb_bypass_uart(struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) const struct usb2phy_reg *iomux = &rport->port_cfg->bypass_iomux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (en == property_enabled(base, &rport->port_cfg->bypass_sel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) dev_info(&rport->phy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) "bypass uart %s is already set\n", en ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) dev_info(&rport->phy->dev, "bypass uart %s\n", en ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * To use UART function:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * 1. Put the USB PHY in suspend mode and opmode is normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * 2. Set bypasssel to 1'b1 and bypassdmen to 1'b1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * Note: Although the datasheet requires that put USB PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * in non-driving mode to disable resistance when use USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * bypass UART function, but actually we find that if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * set phy in non-driving mode, it will cause UART to print
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * random codes. So just put USB PHY in normal mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ret |= property_enable(base, &rport->port_cfg->bypass_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ret |= property_enable(base, &rport->port_cfg->bypass_dm_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* Some platforms required to set iomux of bypass uart */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (iomux->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret |= property_enable(rphy->grf, iomux, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* just disable bypass, and resume phy in phy power_on later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ret |= property_enable(base, &rport->port_cfg->bypass_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ret |= property_enable(base, &rport->port_cfg->bypass_dm_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* Some platforms required to set iomux of bypass uart */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (iomux->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ret |= property_enable(rphy->grf, iomux, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static void rockchip_usb_bypass_uart_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct rockchip_usb2phy_port *rport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) container_of(work, struct rockchip_usb2phy_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) bypass_uart_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) bool vbus, iddig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) iddig = property_enabled(rphy->grf, &rport->port_cfg->utmi_iddig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (rport->utmi_avalid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) vbus = property_enabled(rphy->grf, &rport->port_cfg->utmi_avalid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) vbus = property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * If the vbus is low and iddig is high, it indicates that usb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * otg is not working, then we can enable usb to bypass uart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * otherwise schedule the work until the conditions (vbus is low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * and iddig is high) are matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!vbus && iddig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ret = rockchip_usb_bypass_uart(rport, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) dev_warn(&rport->phy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) "failed to enable bypass uart\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) schedule_delayed_work(&rport->bypass_uart_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) BYPASS_SCHEDULE_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int rockchip_usb2phy_init(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) unsigned int ul, ul_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (rport->port_id == USB2PHY_PORT_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) (rport->mode == USB_DR_MODE_PERIPHERAL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) rport->mode == USB_DR_MODE_OTG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /* clear id status and enable id detect irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (rport->id_irq > 0 || rport->otg_mux_irq > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) rphy->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ret = rockchip_usb2phy_enable_id_irq(rphy, rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) dev_err(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) "failed to enable id irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* clear bvalid status and enable bvalid detect irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if ((rport->bvalid_irq > 0 || rport->otg_mux_irq > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) rphy->irq > 0) && !rport->vbus_always_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ret = rockchip_usb2phy_enable_vbus_irq(rphy, rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) dev_err(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) "failed to enable bvalid irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) schedule_delayed_work(&rport->otg_sm_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) rport->typec_vbus_det ? 0 : OTG_SCHEDULE_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) } else if (rport->port_id == USB2PHY_PORT_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (rport->port_cfg->disfall_en.offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) rport->port_cfg->utmi_ls.bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) rport->host_disconnect = (ul & ul_mask) == 0 ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ret = rockchip_usb2phy_enable_host_disc_irq(rphy, rport, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dev_err(rphy->dev, "failed to enable disconnect irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* clear linestate and enable linestate detect irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ret = rockchip_usb2phy_enable_line_irq(rphy, rport, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) dev_err(rphy->dev, "failed to enable linestate irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) static int rockchip_usb2phy_power_on(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) dev_dbg(&rport->phy->dev, "port power on\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (rport->bypass_uart_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) ret = rockchip_usb_bypass_uart(rport, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dev_warn(&rport->phy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) "failed to disable bypass uart\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (!rport->suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ret = clk_prepare_enable(rphy->clk480m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (rport->sel_pipe_phystatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) property_enable(rphy->usbctrl_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) &rport->port_cfg->pipe_phystatus, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) ret = property_enable(base, &rport->port_cfg->phy_sus, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * For rk3588, it needs to reset phy when exit from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * suspend mode with common_on_n 1'b1(aka REFCLK_LOGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * Bias, and PLL blocks are powered down) for lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * power consumption. If you don't want to reset phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * please keep the common_on_n 1'b0 to set these blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * remain powered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (rport->port_id == USB2PHY_PORT_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) of_device_is_compatible(rphy->dev->of_node, "rockchip,rk3588-usb2phy")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) ret = rockchip_usb2phy_reset(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /* waiting for the utmi_clk to become stable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) usleep_range(1500, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) rport->suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /* Enable bypass uart in the bypass_uart_work. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (rport->bypass_uart_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) schedule_delayed_work(&rport->bypass_uart_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static int rockchip_usb2phy_power_off(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) dev_dbg(&rport->phy->dev, "port power off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (rport->suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) ret = property_enable(base, &rport->port_cfg->phy_sus, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) rport->suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) clk_disable_unprepare(rphy->clk480m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* Enable bypass uart in the bypass_uart_work. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (rport->bypass_uart_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) schedule_delayed_work(&rport->bypass_uart_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static int rockchip_usb2phy_exit(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (rport->port_id == USB2PHY_PORT_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) cancel_delayed_work_sync(&rport->sm_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) else if (rport->port_id == USB2PHY_PORT_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) rport->otg_sm_work.work.func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) flush_delayed_work(&rport->otg_sm_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static int rockchip_set_vbus_power(struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (!rport->vbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (en && !rport->vbus_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ret = regulator_enable(rport->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) dev_err(&rport->phy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) "Failed to enable VBUS supply\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) } else if (!en && rport->vbus_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ret = regulator_disable(rport->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) rport->vbus_enabled = en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) static int rockchip_usb2phy_set_mode(struct phy *phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) enum phy_mode mode, int submode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) bool vbus_det_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (rport->port_id != USB2PHY_PORT_OTG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) case PHY_MODE_USB_OTG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (rphy->edev_self && submode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (submode == USB_ROLE_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) extcon_set_state(rphy->edev, EXTCON_USB, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) } else if (submode == USB_ROLE_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) extcon_set_state(rphy->edev, EXTCON_USB_HOST, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) extcon_set_state(rphy->edev, EXTCON_USB, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * In case of using vbus to detect connect state by u2phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * enable vbus detect on otg mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) case PHY_MODE_USB_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* Disable VBUS supply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) rockchip_set_vbus_power(rport, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /* For vbus always on, set EXTCON_USB to true. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (rport->vbus_always_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) extcon_set_state(rphy->edev, EXTCON_USB, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) rport->perip_connected = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) vbus_det_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) case PHY_MODE_USB_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) /* Enable VBUS supply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ret = rockchip_set_vbus_power(rport, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) dev_err(&rport->phy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) "Failed to set host mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /* For vbus always on, deinit EXTCON_USB to false. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (rport->vbus_always_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) extcon_set_state(rphy->edev, EXTCON_USB, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) rport->perip_connected = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) case PHY_MODE_INVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) vbus_det_en = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dev_info(&rport->phy->dev, "illegal mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (rphy->phy_cfg->vbus_detect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) rphy->phy_cfg->vbus_detect(rphy, vbus_det_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) ret = property_enable(rphy->grf, &rport->port_cfg->vbus_det_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) vbus_det_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static const struct phy_ops rockchip_usb2phy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) .init = rockchip_usb2phy_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .exit = rockchip_usb2phy_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .power_on = rockchip_usb2phy_power_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) .power_off = rockchip_usb2phy_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .set_mode = rockchip_usb2phy_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* Show & store the current value of otg mode for otg port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static ssize_t otg_mode_show(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct rockchip_usb2phy *rphy = dev_get_drvdata(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) struct rockchip_usb2phy_port *rport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) rport = &rphy->ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (rport->port_id == USB2PHY_PORT_OTG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (!rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) dev_err(rphy->dev, "Fail to get otg port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) } else if (rport->port_id != USB2PHY_PORT_OTG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) dev_err(rphy->dev, "No support otg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) switch (rport->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) case USB_DR_MODE_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return sprintf(buf, "host\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) case USB_DR_MODE_PERIPHERAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return sprintf(buf, "peripheral\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) case USB_DR_MODE_OTG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return sprintf(buf, "otg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) case USB_DR_MODE_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return sprintf(buf, "UNKNOWN\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static ssize_t otg_mode_store(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct rockchip_usb2phy *rphy = dev_get_drvdata(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct rockchip_usb2phy_port *rport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) enum usb_dr_mode new_dr_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) int rc = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) rport = &rphy->ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (rport->port_id == USB2PHY_PORT_OTG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (!rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) dev_err(rphy->dev, "Fail to get otg port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) } else if (rport->port_id != USB2PHY_PORT_OTG ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) rport->mode == USB_DR_MODE_UNKNOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) dev_err(rphy->dev, "No support otg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) goto err0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (!strncmp(buf, "0", 1) || !strncmp(buf, "otg", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) new_dr_mode = USB_DR_MODE_OTG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) } else if (!strncmp(buf, "1", 1) || !strncmp(buf, "host", 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) new_dr_mode = USB_DR_MODE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) } else if (!strncmp(buf, "2", 1) || !strncmp(buf, "peripheral", 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) new_dr_mode = USB_DR_MODE_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) dev_err(rphy->dev, "Error mode! Input 'otg' or 'host' or 'peripheral'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (rport->mode == new_dr_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) dev_warn(rphy->dev, "Same as current mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) rport->mode = new_dr_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) switch (rport->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) case USB_DR_MODE_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) property_enable(base, &rport->port_cfg->iddig_output, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) property_enable(base, &rport->port_cfg->iddig_en, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) case USB_DR_MODE_PERIPHERAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_DEVICE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) property_enable(base, &rport->port_cfg->iddig_output, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) property_enable(base, &rport->port_cfg->iddig_en, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) case USB_DR_MODE_OTG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_OTG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) property_enable(base, &rport->port_cfg->iddig_output, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) property_enable(base, &rport->port_cfg->iddig_en, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) err0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static DEVICE_ATTR_RW(otg_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /* Group all the usb2 phy attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static struct attribute *usb2_phy_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) &dev_attr_otg_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) static struct attribute_group usb2_phy_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .name = NULL, /* we want them in the same directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .attrs = usb2_phy_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct rockchip_usb2phy_port *rport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) container_of(work, struct rockchip_usb2phy_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) otg_sm_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static unsigned int cable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) unsigned long delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) bool sch_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (rport->port_cfg->bvalid_grf_con.enable && rport->typec_vbus_det)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) rport->vbus_attached =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) property_enabled(rphy->grf, &rport->port_cfg->bvalid_grf_con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) else if (rport->utmi_avalid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) rport->vbus_attached =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) property_enabled(rphy->grf, &rport->port_cfg->utmi_avalid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) rport->vbus_attached =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) sch_work = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) delay = OTG_SCHEDULE_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) dev_dbg(&rport->phy->dev, "%s otg sm work\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) usb_otg_state_string(rport->state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) switch (rport->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) case OTG_STATE_UNDEFINED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) rport->state = OTG_STATE_B_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (!rport->vbus_attached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) rockchip_usb2phy_power_off(rport->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) case OTG_STATE_B_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) extcon_get_state(rphy->edev, EXTCON_USB_VBUS_EN) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) dev_dbg(&rport->phy->dev, "usb otg host connect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) rport->state = OTG_STATE_A_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) rphy->chg_state = USB_CHG_STATE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) rockchip_usb2phy_power_on(rport->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) } else if (rport->vbus_attached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) dev_dbg(&rport->phy->dev, "vbus_attach\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) switch (rphy->chg_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) case USB_CHG_STATE_UNDEFINED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) schedule_delayed_work(&rport->chg_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) case USB_CHG_STATE_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) switch (rphy->chg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) case POWER_SUPPLY_TYPE_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) wake_lock(&rport->wakelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) cable = EXTCON_CHG_USB_SDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) rockchip_usb2phy_power_on(rport->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) rport->state = OTG_STATE_B_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) rport->perip_connected = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) sch_work = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) case POWER_SUPPLY_TYPE_USB_DCP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) cable = EXTCON_CHG_USB_DCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) sch_work = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) case POWER_SUPPLY_TYPE_USB_CDP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) wake_lock(&rport->wakelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) cable = EXTCON_CHG_USB_CDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) rockchip_usb2phy_power_on(rport->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) rport->state = OTG_STATE_B_PERIPHERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) rport->perip_connected = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) sch_work = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) rphy->chg_state = USB_CHG_STATE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) rockchip_usb2phy_power_off(rport->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) case OTG_STATE_B_PERIPHERAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) sch_work = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) extcon_get_state(rphy->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) EXTCON_USB_VBUS_EN) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) dev_dbg(&rport->phy->dev, "usb otg host connect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) rport->state = OTG_STATE_A_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) rphy->chg_state = USB_CHG_STATE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) rport->perip_connected = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) sch_work = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) wake_unlock(&rport->wakelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) } else if (!rport->vbus_attached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dev_dbg(&rport->phy->dev, "usb disconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) rport->state = OTG_STATE_B_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) rport->perip_connected = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) rphy->chg_state = USB_CHG_STATE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) delay = OTG_SCHEDULE_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) wake_unlock(&rport->wakelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) case OTG_STATE_A_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) rport->state = OTG_STATE_B_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) sch_work = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (extcon_get_state(rphy->edev, cable) != rport->vbus_attached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) extcon_set_state_sync(rphy->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) cable, rport->vbus_attached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (!rport->vbus_attached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) cable = EXTCON_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) } else if (rport->state == OTG_STATE_A_HOST &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) extcon_get_state(rphy->edev, cable)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * If plug in OTG host cable when the rport state is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) * OTG_STATE_B_PERIPHERAL, the vbus voltage will stay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) * in high, so the rport->vbus_attached may not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) * changed. We need to set cable state here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) extcon_set_state_sync(rphy->edev, cable, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) cable = EXTCON_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (rphy->edev_self &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) (extcon_get_state(rphy->edev, EXTCON_USB) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) rport->perip_connected)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) extcon_set_state_sync(rphy->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) EXTCON_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) rport->perip_connected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) extcon_sync(rphy->edev, EXTCON_USB_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (sch_work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) schedule_delayed_work(&rport->otg_sm_work, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) static const char *chg_to_string(enum power_supply_type chg_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) switch (chg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) case POWER_SUPPLY_TYPE_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return "USB_SDP_CHARGER";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) case POWER_SUPPLY_TYPE_USB_DCP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return "USB_DCP_CHARGER";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) case POWER_SUPPLY_TYPE_USB_CDP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return "USB_CDP_CHARGER";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) return "INVALID_CHARGER";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) #define CHG_DCD_POLL_TIME (100 * HZ / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) #define CHG_DCD_MAX_RETRIES 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) #define CHG_PRIMARY_DET_TIME (40 * HZ / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) #define CHG_SECONDARY_DET_TIME (40 * HZ / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) static void rockchip_chg_detect_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) struct rockchip_usb2phy_port *rport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) container_of(work, struct rockchip_usb2phy_port, chg_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) const struct usb2phy_reg *phy_sus_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) bool is_dcd, tmout, vout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) unsigned long delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) rphy->chg_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * The conditions for charger detection:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * 1. Set the PHY in normal mode to keep the UTMI_CLK on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * 2. Set the utmi_opmode in non-driving mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * 3. Set the utmi_xcvrselect to FS speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * 4. Set the utmi_termselect to FS speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * 5. Enable the DP/DM pulldown resistor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) switch (rphy->chg_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) case USB_CHG_STATE_UNDEFINED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) /* Store the PHY current suspend configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) phy_sus_reg = &rport->port_cfg->phy_sus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) ret = regmap_read(base, phy_sus_reg->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) &rphy->phy_sus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) dev_err(&rport->phy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) "Fail to read phy_sus reg offset 0x%x, ret %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) phy_sus_reg->offset, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) /* Set the PHY in charger detection mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) property_enable(base, &rphy->phy_cfg->chg_det.chg_mode, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) /* Start DCD processing stage 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) rockchip_chg_enable_dcd(rphy, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) rphy->dcd_retries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) rphy->primary_retries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) delay = CHG_DCD_POLL_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) case USB_CHG_STATE_WAIT_FOR_DCD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /* get data contact detection status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) is_dcd = property_enabled(rphy->grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) &rphy->phy_cfg->chg_det.dp_det);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) /* stage 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (is_dcd || tmout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* stage 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /* Turn off DCD circuitry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) rockchip_chg_enable_dcd(rphy, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) /* Voltage Source on DP, Probe on DM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) rockchip_chg_enable_primary_det(rphy, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) delay = CHG_PRIMARY_DET_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) rphy->chg_state = USB_CHG_STATE_DCD_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) /* stage 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) delay = CHG_DCD_POLL_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case USB_CHG_STATE_DCD_DONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) vout = property_enabled(rphy->grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) &rphy->phy_cfg->chg_det.cp_det);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) rockchip_chg_enable_primary_det(rphy, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (vout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) /* Voltage Source on DM, Probe on DP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) rockchip_chg_enable_secondary_det(rphy, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) delay = CHG_SECONDARY_DET_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) rphy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (rphy->dcd_retries == CHG_DCD_MAX_RETRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) /* floating charger found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) rphy->chg_state = USB_CHG_STATE_DETECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (rphy->primary_retries < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) /* Turn off DCD circuitry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) rockchip_chg_enable_dcd(rphy, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /* Voltage Source on DP, Probe on DM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) rockchip_chg_enable_primary_det(rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) delay = CHG_PRIMARY_DET_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) rphy->chg_state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) USB_CHG_STATE_DCD_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) rphy->primary_retries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) /* break USB_CHG_STATE_DCD_DONE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) rphy->chg_type = POWER_SUPPLY_TYPE_USB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) rphy->chg_state = USB_CHG_STATE_DETECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) case USB_CHG_STATE_PRIMARY_DONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) vout = property_enabled(rphy->grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) &rphy->phy_cfg->chg_det.dcp_det);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /* Turn off voltage source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) rockchip_chg_enable_secondary_det(rphy, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (vout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) case USB_CHG_STATE_SECONDARY_DONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) rphy->chg_state = USB_CHG_STATE_DETECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) case USB_CHG_STATE_DETECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (rphy->phy_cfg->chg_det.chg_mode.offset !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) rport->port_cfg->phy_sus.offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) property_enable(base, &rphy->phy_cfg->chg_det.chg_mode, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /* Restore the PHY suspend configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) phy_sus_reg = &rport->port_cfg->phy_sus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) mask = GENMASK(phy_sus_reg->bitend, phy_sus_reg->bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) ret = regmap_write(base, phy_sus_reg->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) (rphy->phy_sus_cfg | (mask << BIT_WRITEABLE_SHIFT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) dev_err(&rport->phy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) "Fail to set phy_sus reg offset 0x%x, ret %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) phy_sus_reg->offset, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) dev_dbg(&rport->phy->dev, "charger = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) chg_to_string(rphy->chg_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * Hold the mutex lock during the whole charger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * detection stage, and release it after detect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * the charger type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) schedule_delayed_work(&rport->chg_work, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) * The function manage host-phy port state and suspend/resume phy port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) * to save power.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * we rely on utmi_linestate and utmi_hostdisconnect to identify whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) * devices is disconnect or not. Besides, we do not need care it is FS/LS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * disconnected or HS disconnected, actually, we just only need get the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) * device is disconnected at last through rearm the delayed work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) * to suspend the phy port in _PHY_STATE_DISCONNECT_ case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * NOTE: It may invoke *phy_powr_off or *phy_power_on which will invoke
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) * some clk related APIs, so do not invoke it from interrupt context directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) static void rockchip_usb2phy_sm_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) struct rockchip_usb2phy_port *rport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) container_of(work, struct rockchip_usb2phy_port, sm_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) unsigned int sh, ul, uhd, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) unsigned int ul_mask, uhd_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (!rport->port_cfg->utmi_ls.offset ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) (!rport->port_cfg->utmi_hstdet.offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) !rport->port_cfg->disfall_en.offset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) dev_dbg(&rport->phy->dev, "some property may not be specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) goto next_schedule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) rport->port_cfg->utmi_ls.bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if (rport->port_cfg->utmi_hstdet.offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) goto next_schedule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) rport->port_cfg->utmi_hstdet.bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) sh = rport->port_cfg->utmi_hstdet.bitend -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) rport->port_cfg->utmi_hstdet.bitstart + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) /* stitch on utmi_ls and utmi_hstdet as phy state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) state = ((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << 1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) rport->host_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) case PHY_STATE_HS_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) dev_dbg(&rport->phy->dev, "HS online\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) case PHY_STATE_FS_LS_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * For FS/LS device, the online state share with connect state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) * from utmi_ls and utmi_hstdet register, so we distinguish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) * them via suspended flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) * Plus, there are two cases, one is D- Line pull-up, and D+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) * line pull-down, the state is 4; another is D+ line pull-up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * and D- line pull-down, the state is 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (!rport->suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) /* D- line pull-up, D+ line pull-down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) dev_dbg(&rport->phy->dev, "FS/LS online\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) case PHY_STATE_CONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) if (rport->suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) dev_dbg(&rport->phy->dev, "Connected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) rockchip_usb2phy_power_on(rport->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) rport->suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) /* D+ line pull-up, D- line pull-down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) dev_dbg(&rport->phy->dev, "FS/LS online\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) case PHY_STATE_DISCONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (!rport->suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) dev_dbg(&rport->phy->dev, "Disconnected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) rockchip_usb2phy_power_off(rport->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) rport->suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) * activate the linestate detection to get the next device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) * plug-in irq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) rockchip_usb2phy_enable_line_irq(rphy, rport, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) * we don't need to rearm the delayed work when the phy port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) * is suspended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) dev_dbg(&rport->phy->dev, "unknown phy state %d\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) next_schedule:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) struct rockchip_usb2phy_port *rport = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) !property_enabled(rphy->grf, &rport->port_cfg->ls_det_en))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) dev_dbg(&rport->phy->dev, "linestate interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) /* disable linestate detect irq and clear its status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) rockchip_usb2phy_enable_line_irq(rphy, rport, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) * For host port, it may miss disc irq when device is connected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) * in this case, we can clear host_disconnect state depend on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) * the linestate irq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (rport->port_id == USB2PHY_PORT_HOST && rport->port_cfg->disfall_en.offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) rport->host_disconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) * In this case for host phy port, a new device is plugged in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) * meanwhile, if the phy port is suspended, we need rearm the work to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) * resume it and mange its states; otherwise, we do nothing about that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) if (rport->suspended && rport->port_id == USB2PHY_PORT_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) rockchip_usb2phy_sm_work(&rport->sm_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct rockchip_usb2phy_port *rport = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) /* clear bvalid detect irq pending status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (rport->bypass_uart_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) rockchip_usb_bypass_uart(rport, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (rport->otg_sm_work.work.func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) cancel_delayed_work_sync(&rport->otg_sm_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) struct rockchip_usb2phy_port *rport = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) bool cable_vbus_state = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if (!property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) !property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) /* clear id fall or rise detect irq pending status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) if (property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) cable_vbus_state = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) } else if (property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) cable_vbus_state = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) extcon_set_state(rphy->edev, EXTCON_USB_HOST, cable_vbus_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, cable_vbus_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) extcon_sync(rphy->edev, EXTCON_USB_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) extcon_sync(rphy->edev, EXTCON_USB_VBUS_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) rockchip_set_vbus_power(rport, cable_vbus_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) static irqreturn_t rockchip_usb2phy_host_disc_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) struct rockchip_usb2phy_port *rport = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if (!property_enabled(rphy->grf, &rport->port_cfg->disfall_st) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) !property_enabled(rphy->grf, &rport->port_cfg->disrise_st))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) /* clear disconnect fall or rise detect irq pending status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) if (property_enabled(rphy->grf, &rport->port_cfg->disfall_st)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) property_enable(rphy->grf, &rport->port_cfg->disfall_clr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) rport->host_disconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) } else if (property_enabled(rphy->grf, &rport->port_cfg->disrise_st)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) property_enable(rphy->grf, &rport->port_cfg->disrise_clr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) rport->host_disconnect = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) ret = rockchip_usb2phy_id_irq(irq, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) ret |= rockchip_usb2phy_bvalid_irq(irq, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) ret |= rockchip_usb2phy_linestate_irq(irq, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) struct rockchip_usb2phy *rphy = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) struct rockchip_usb2phy_port *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) bool force_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) rport = &rphy->ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if (!rport->phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) * Handle disc irq before linestate irq to set the disc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) * state for sm work scheduled in the linestate irq handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (rport->port_id == USB2PHY_PORT_HOST &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) rport->port_cfg->disfall_en.offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) ret |= rockchip_usb2phy_host_disc_irq(irq, rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) /* Handle linestate irq for both otg port and host port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) ret |= rockchip_usb2phy_linestate_irq(irq, rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) * Handle bvalid irq and id irq for otg port which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) * is assigned to otg controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (rport->port_id == USB2PHY_PORT_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) rport->mode != USB_DR_MODE_UNKNOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (rport->mode == USB_DR_MODE_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) * If otg port work as usb host mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) * force_mode is true, it means that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) * otg port is forced to host mode by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) * grf plug iddig indicator via the sys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) * interface "otg_mode". We need to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) * the bvalid irq and id irq in this case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) force_mode = property_enabled(rphy->grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) &rport->port_cfg->iddig_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (!force_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (!rport->vbus_always_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) ret |= rockchip_usb2phy_bvalid_irq(irq, rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) ret |= rockchip_usb2phy_id_irq(irq, rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) struct device_node *child_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) * If the usb2 phy used combined irq for otg and host port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) * don't need to init otg and host port irq separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (rphy->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) * Some SoCs (e.g. RV1108) use one combined irq for all of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * the irqs of otg port. So probe the otg-mux interrupt first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * if not found, then init the regular irqs one by one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (rport->otg_mux_irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) rockchip_usb2phy_otg_mux_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) "rockchip_usb2phy_otg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) dev_err(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) "failed to request otg-mux irq handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) /* Init linestate irq for both otg port and host port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) rport->ls_irq = of_irq_get_byname(child_np, "linestate");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) if (rport->ls_irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) dev_err(rphy->dev, "no linestate irq provided\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) rockchip_usb2phy_linestate_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) "rockchip_usb2phy_ls", rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) dev_err(rphy->dev, "failed to request linestate irq handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) * If it's host port or it's otg port but only support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) * host mode, return immediately without init the bvalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) * and id irqs/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (rport->port_id == USB2PHY_PORT_HOST ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) rport->mode == USB_DR_MODE_HOST ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) rport->mode == USB_DR_MODE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) /* Init the bvalid irq for otg port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) if (!rport->vbus_always_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) rport->bvalid_irq = of_irq_get_byname(child_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) "otg-bvalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) if (rport->bvalid_irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) dev_err(rphy->dev, "no bvalid irq provided\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) ret = devm_request_threaded_irq(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) rport->bvalid_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) rockchip_usb2phy_bvalid_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) "rockchip_usb2phy_bvalid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) dev_err(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) "failed to request otg-bvalid irq handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) /* Init the id irq for otg port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (rphy->edev_self) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) rport->id_irq = of_irq_get_byname(child_np, "otg-id");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) if (rport->id_irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) dev_err(rphy->dev, "no otg id irq provided\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) ret = devm_request_threaded_irq(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) rport->id_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) rockchip_usb2phy_id_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) "rockchip_usb2phy_id",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) dev_err(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) "failed to request otg-id irq handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) static void rockchip_usb2phy_usb_bvalid_enable(struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) u8 enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) const struct rockchip_usb2phy_port_cfg *cfg = rport->port_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) if (cfg->bvalid_phy_con.enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) property_enable(rphy->grf, &cfg->bvalid_phy_con, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if (cfg->bvalid_grf_con.enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) property_enable(rphy->grf, &cfg->bvalid_grf_con, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) static int rockchip_usb2phy_orien_sw_set(struct typec_switch *sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) enum typec_orientation orien)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) struct rockchip_usb2phy_port *rport = typec_switch_get_drvdata(sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) dev_dbg(&rport->phy->dev, "type-c orientation: %d\n", orien);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) rockchip_usb2phy_usb_bvalid_enable(rport, orien != TYPEC_ORIENTATION_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) rockchip_usb2phy_setup_orien_switch(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) struct rockchip_usb2phy_port *rport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) struct typec_switch_desc sw_desc = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) struct device *dev = rphy->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) sw_desc.drvdata = rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) sw_desc.fwnode = dev_fwnode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) sw_desc.set = rockchip_usb2phy_orien_sw_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) rport->sw = typec_switch_register(dev, &sw_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (IS_ERR(rport->sw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) dev_err(dev, "Error register typec orientation switch: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) PTR_ERR(rport->sw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) return PTR_ERR(rport->sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) static void rockchip_usb2phy_orien_switch_unregister(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) struct rockchip_usb2phy_port *rport = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) typec_switch_unregister(rport->sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) struct device_node *child_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) rport->port_id = USB2PHY_PORT_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) /* enter lower power state when suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) rport->low_power_en =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) of_property_read_bool(child_np, "rockchip,low-power-mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) mutex_init(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) dev_err(rphy->dev, "failed to init irq for host port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) * Let us put phy-port into suspend mode here for saving power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) * consumption, and usb controller will resume it during probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) * time if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) ret = property_enable(base, &rport->port_cfg->phy_sus, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) rport->suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) static int rockchip_otg_event(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) struct rockchip_usb2phy_port *rport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) container_of(nb, struct rockchip_usb2phy_port, event_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) struct device_node *child_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) int iddig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) struct regmap *base = get_reg_base(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) rport->port_id = USB2PHY_PORT_OTG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) rport->state = OTG_STATE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) rport->vbus_attached = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) rport->vbus_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) rport->perip_connected = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) rport->prev_iddig = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) mutex_init(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) /* bypass uart function is only used in debug stage. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) rport->bypass_uart_en =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) of_property_read_bool(child_np, "rockchip,bypass-uart");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) rport->vbus_always_on =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) of_property_read_bool(child_np, "rockchip,vbus-always-on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) rport->utmi_avalid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) of_property_read_bool(child_np, "rockchip,utmi-avalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) /* enter lower power state when suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) rport->low_power_en =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) of_property_read_bool(child_np, "rockchip,low-power-mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) /* For type-c with vbus_det always pull up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) rport->typec_vbus_det =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) of_property_read_bool(child_np, "rockchip,typec-vbus-det");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) rport->sel_pipe_phystatus =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) of_property_read_bool(child_np, "rockchip,sel-pipe-phystatus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) if (rport->sel_pipe_phystatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) rphy->usbctrl_grf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) syscon_regmap_lookup_by_phandle(rphy->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) "rockchip,usbctrl-grf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) if (IS_ERR(rphy->usbctrl_grf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) dev_err(rphy->dev, "Failed to map usbctrl-grf\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) return PTR_ERR(rphy->usbctrl_grf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) /* Get Vbus regulators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) rport->vbus = devm_regulator_get_optional(&rport->phy->dev, "vbus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) if (IS_ERR(rport->vbus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) ret = PTR_ERR(rport->vbus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) if (ret == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (rport->mode == USB_DR_MODE_OTG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) dev_warn(&rport->phy->dev, "No vbus specified for otg port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) rport->vbus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) iddig = property_enabled(rphy->grf, &rport->port_cfg->utmi_iddig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) if (rphy->edev_self && (rport->mode == USB_DR_MODE_HOST ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) rport->mode == USB_DR_MODE_UNKNOWN || !iddig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) /* Enable VBUS supply for otg port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) extcon_set_state(rphy->edev, EXTCON_USB, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) extcon_set_state(rphy->edev, EXTCON_USB_HOST, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) extcon_set_state(rphy->edev, EXTCON_USB_VBUS_EN, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) ret = rockchip_set_vbus_power(rport, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) dev_err(rphy->dev, "failed to init irq for otg port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) if (IS_REACHABLE(CONFIG_TYPEC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) device_property_present(rphy->dev, "orientation-switch")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) ret = rockchip_usb2phy_setup_orien_switch(rphy, rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) ret = devm_add_action_or_reset(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) rockchip_usb2phy_orien_switch_unregister,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) * Set the utmi bvalid come from the usb phy or grf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) * For most of Rockchip SoCs, them have VBUSDET pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) * for the usb phy to detect the USB VBUS and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) * the bvalid signal, so select the bvalid from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) * usb phy by default. And for those SoCs which don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) * have VBUSDET pin (e.g. RV1103), it needs to select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) * the bvaid from the grf and set bvalid to be valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) * (high) by default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) if (rport->port_cfg->bvalid_grf_sel.enable != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (of_machine_is_compatible("rockchip,rv1103"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) property_enable(base, &rport->port_cfg->bvalid_grf_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) property_enable(base, &rport->port_cfg->bvalid_grf_sel, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (rport->vbus_always_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) extcon_set_state(rphy->edev, EXTCON_USB, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) if (rport->vbus_always_on || rport->mode == USB_DR_MODE_HOST ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) rport->mode == USB_DR_MODE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) INIT_DELAYED_WORK(&rport->bypass_uart_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) rockchip_usb_bypass_uart_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (!IS_ERR(rphy->edev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) rport->event_nb.notifier_call = rockchip_otg_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) EXTCON_USB_HOST, &rport->event_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) dev_err(rphy->dev, "register USB HOST notifier failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) * Let us put phy-port into suspend mode here for saving power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) * consumption, and usb controller will resume it during probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) * time if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) ret = property_enable(base, &rport->port_cfg->phy_sus, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) rport->suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) wake_lock_destroy(&rport->wakelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) static int rockchip_usb2phy_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) struct device_node *child_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) struct phy_provider *provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) struct rockchip_usb2phy *rphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) const struct rockchip_usb2phy_cfg *phy_cfgs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) if (!rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) match = of_match_device(dev->driver->of_match_table, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) if (!match || !match->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) dev_err(dev, "phy configs are not assigned!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (!dev->parent || !dev->parent->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) dev_err(dev, "missing memory resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) rphy->phy_base = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (IS_ERR(rphy->phy_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) return PTR_ERR(rphy->phy_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) rphy->grf = syscon_regmap_lookup_by_phandle(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) "rockchip,usbgrf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if (IS_ERR(rphy->grf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) return PTR_ERR(rphy->grf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) reg = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) if (IS_ERR(rphy->grf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return PTR_ERR(rphy->grf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) rphy->usbgrf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) syscon_regmap_lookup_by_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) "rockchip,usbgrf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) if (IS_ERR(rphy->usbgrf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) return PTR_ERR(rphy->usbgrf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) rphy->usbgrf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) if (of_property_read_u32(np, "reg", ®)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) dev_err(dev, "missing reg property in %s node\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) np->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) rphy->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) phy_cfgs = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) rphy->chg_state = USB_CHG_STATE_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) rphy->edev_self = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) rphy->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) platform_set_drvdata(pdev, rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) ret = rockchip_usb2phy_extcon_register(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) /* find out a proper config which can be matched with dt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (phy_cfgs[index].reg == reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) rphy->phy_cfg = &phy_cfgs[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) ++index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) } while (phy_cfgs[index].reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) if (!rphy->phy_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) dev_err(dev, "no phy-config can be matched with %pOFn node\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) rphy->phy_reset = devm_reset_control_get_optional(dev, "phy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) if (IS_ERR(rphy->phy_reset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) return PTR_ERR(rphy->phy_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) ret = devm_clk_bulk_get_all(dev, &rphy->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) if (ret == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) /* Clocks are optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) rphy->num_clks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) rphy->num_clks = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) if (rphy->phy_cfg->phy_tuning) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) ret = rphy->phy_cfg->phy_tuning(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) goto disable_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) for_each_available_child_of_node(np, child_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) struct rockchip_usb2phy_port *rport = &rphy->ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) /* This driver aims to support both otg-port and host-port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (!of_node_name_eq(child_np, "host-port") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) !of_node_name_eq(child_np, "otg-port"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) goto next_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) if (IS_ERR(phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) dev_err(dev, "failed to create phy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) ret = PTR_ERR(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) goto put_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) rport->phy = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) phy_set_drvdata(rport->phy, rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) /* initialize otg/host port separately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) if (of_node_name_eq(child_np, "host-port")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) ret = rockchip_usb2phy_host_port_init(rphy, rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) child_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) goto put_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) ret = rockchip_usb2phy_otg_port_init(rphy, rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) child_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) goto put_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) next_child:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) /* to prevent out of boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) if (++index >= rphy->phy_cfg->num_ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) if (IS_ERR(provider)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) dev_err(dev, "Failed to register phy provider\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) ret = PTR_ERR(provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) goto put_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) /* Attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) ret = sysfs_create_group(&dev->kobj, &usb2_phy_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) dev_err(dev, "Cannot create sysfs group: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) goto put_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) ret = rockchip_usb2phy_clk480m_register(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) dev_err(dev, "failed to register 480m output clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) goto put_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) if (rphy->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) rockchip_usb2phy_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) "rockchip_usb2phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) dev_err(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) "failed to request usb2 phy irq handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) goto put_child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) if (of_property_read_bool(np, "wakeup-source"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) device_init_wakeup(rphy->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) device_init_wakeup(rphy->dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) put_child:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) of_node_put(child_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) disable_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) pm_runtime_put_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) static int __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) rockchip_usb2phy_low_power_enable(struct rockchip_usb2phy *rphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) struct rockchip_usb2phy_port *rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) bool value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) if (!rport->low_power_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) if (rport->port_id == USB2PHY_PORT_OTG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) dev_info(&rport->phy->dev, "set otg port low power state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) ret = property_enable(rphy->grf, &rport->port_cfg->bypass_bc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) ret = property_enable(rphy->grf, &rport->port_cfg->bypass_otg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) ret = property_enable(rphy->grf, &rport->port_cfg->vbus_det_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) !value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) } else if (rport->port_id == USB2PHY_PORT_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) dev_info(&rport->phy->dev, "set host port low power state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) ret = property_enable(rphy->grf, &rport->port_cfg->bypass_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) static int rk312x_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) /* Turn off differential receiver in suspend mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) ret = regmap_write(rphy->grf, 0x298, 0x00040000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) static int rk3228_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) /* Open pre-emphasize in non-chirp state for PHY0 otg port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) if (rphy->phy_cfg->reg == 0x760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) ret = regmap_write(rphy->grf, 0x76c, 0x00070004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) static int rk3308_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) if (soc_is_rk3308bs()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) /* Turn off differential receiver in suspend mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) ret = regmap_update_bits(rphy->grf, 0x30, BIT(2), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) /* Enable otg port pre-emphasis during non-chirp phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) ret = regmap_update_bits(rphy->grf, 0, GENMASK(2, 0), BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) /* Set otg port squelch trigger point configure to 100mv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) ret = regmap_update_bits(rphy->grf, 0x004, GENMASK(7, 5), 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) ret = regmap_update_bits(rphy->grf, 0x008, BIT(0), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) /* Enable host port pre-emphasis during non-chirp phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) ret = regmap_update_bits(rphy->grf, 0x400, GENMASK(2, 0), BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) /* Set host port squelch trigger point configure to 100mv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) ret = regmap_update_bits(rphy->grf, 0x404, GENMASK(7, 5), 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) ret = regmap_update_bits(rphy->grf, 0x408, BIT(0), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) /* Open pre-emphasize in non-chirp state for otg port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) ret = regmap_write(rphy->grf, 0x0, 0x00070004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) /* Open pre-emphasize in non-chirp state for host port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) ret = regmap_write(rphy->grf, 0x30, 0x00070004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) /* Turn off differential receiver in suspend mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) ret = regmap_write(rphy->grf, 0x18, 0x00040000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) static int rk3328_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) if (soc_is_px30s()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) /* Enable otg port pre-emphasis during non-chirp phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) ret = regmap_update_bits(rphy->grf, 0x8000, GENMASK(2, 0), BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) /* Set otg port squelch trigger point configure to 100mv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) ret = regmap_update_bits(rphy->grf, 0x8004, GENMASK(7, 5), 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) ret = regmap_update_bits(rphy->grf, 0x8008, BIT(0), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) /* Turn off otg port differential reciver in suspend mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) ret = regmap_update_bits(rphy->grf, 0x8030, BIT(2), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) /* Enable host port pre-emphasis during non-chirp phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) ret = regmap_update_bits(rphy->grf, 0x8400, GENMASK(2, 0), BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) /* Set host port squelch trigger point configure to 100mv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) ret = regmap_update_bits(rphy->grf, 0x8404, GENMASK(7, 5), 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) ret = regmap_update_bits(rphy->grf, 0x8408, BIT(0), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) /* Turn off host port differential reciver in suspend mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) ret = regmap_update_bits(rphy->grf, 0x8430, BIT(2), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) /* Open debug mode for tuning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) ret = regmap_write(rphy->grf, 0x2c, 0xffff0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) /* Open pre-emphasize in non-chirp state for otg port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) ret = regmap_write(rphy->grf, 0x0, 0x00070004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) /* Open pre-emphasize in non-chirp state for host port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) ret = regmap_write(rphy->grf, 0x30, 0x00070004);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) /* Turn off differential receiver in suspend mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) ret = regmap_write(rphy->grf, 0x18, 0x00040000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) static int rk3366_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) unsigned int open_pre_emphasize = 0xffff851f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) unsigned int eye_height_tuning = 0xffff68c8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) unsigned int compensation_tuning = 0xffff026e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) /* open HS pre-emphasize to expand HS slew rate for each port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) ret |= regmap_write(rphy->grf, 0x0780, open_pre_emphasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) ret |= regmap_write(rphy->grf, 0x079c, eye_height_tuning);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) ret |= regmap_write(rphy->grf, 0x07b0, open_pre_emphasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) ret |= regmap_write(rphy->grf, 0x07cc, eye_height_tuning);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) /* compensate default tuning reference relate to ODT and etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) ret |= regmap_write(rphy->grf, 0x078c, compensation_tuning);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) static int rk3399_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) struct device_node *node = rphy->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) if (rphy->phy_cfg->reg == 0xe450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) * Disable the pre-emphasize in eop state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) * and chirp state to avoid mis-trigger the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) * disconnect detection and also avoid hs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) * handshake fail for PHY0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) ret |= regmap_write(rphy->grf, 0x4480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) GENMASK(17, 16) | 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) ret |= regmap_write(rphy->grf, 0x44b4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) GENMASK(17, 16) | 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) * Disable the pre-emphasize in eop state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) * and chirp state to avoid mis-trigger the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) * disconnect detection and also avoid hs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) * handshake fail for PHY1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) ret |= regmap_write(rphy->grf, 0x4500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) GENMASK(17, 16) | 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) ret |= regmap_write(rphy->grf, 0x4534,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) GENMASK(17, 16) | 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) if (!of_property_read_bool(node, "rockchip,u2phy-tuning"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) if (rphy->phy_cfg->reg == 0xe450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) * Set max ODT compensation voltage and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) * current tuning reference for PHY0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) ret |= regmap_write(rphy->grf, 0x448c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) GENMASK(23, 16) | 0xe3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) /* Set max pre-emphasis level for PHY0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) ret |= regmap_write(rphy->grf, 0x44b0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) GENMASK(18, 16) | 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) * Set PHY0 A port squelch trigger point to 125mv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) ret |= regmap_write(rphy->grf, 0x4480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) GENMASK(30, 30) | 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) * Set max ODT compensation voltage and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) * current tuning reference for PHY1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) ret |= regmap_write(rphy->grf, 0x450c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) GENMASK(23, 16) | 0xe3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) /* Set max pre-emphasis level for PHY1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) ret |= regmap_write(rphy->grf, 0x4530,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) GENMASK(18, 16) | 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) * Set PHY1 A port squelch trigger point to 125mv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) ret |= regmap_write(rphy->grf, 0x4500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) GENMASK(30, 30) | 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) static int rk3568_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) /* Turn off differential receiver by default to save power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) phy_clear_bits(rphy->phy_base + 0x30, BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) /* Enable otg port pre-emphasis during non-chirp phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) phy_update_bits(rphy->phy_base, GENMASK(2, 0), 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) /* Enable host port pre-emphasis during non-chirp phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) phy_update_bits(rphy->phy_base + 0x0400, GENMASK(2, 0), 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) if (rphy->phy_cfg->reg == 0xfe8a0000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) /* Set otg port HS eye height to 437.5mv(default is 400mv) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) phy_update_bits(rphy->phy_base + 0x30, GENMASK(6, 4), (0x06 << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) * Set the bvalid filter time to 10ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) * based on the usb2 phy grf pclk 100MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) ret |= regmap_write(rphy->grf, 0x0048, FILTER_COUNTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) * Set the id filter time to 10ms based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) * on the usb2 phy grf pclk 100MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) ret |= regmap_write(rphy->grf, 0x004c, FILTER_COUNTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) /* Enable host port (usb3 host1 and usb2 host1) wakeup irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) ret |= regmap_write(rphy->grf, 0x000c, 0x80008000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) static int rv1106_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) /* Always enable pre-emphasis in SOF & EOP & chirp & non-chirp state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) phy_update_bits(rphy->phy_base + 0x30, GENMASK(2, 0), 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) if (rockchip_get_cpu_version()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) /* Set Tx HS pre_emphasize strength to 3'b001 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) phy_update_bits(rphy->phy_base + 0x40, GENMASK(5, 3), (0x01 << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) /* Set Tx HS pre_emphasize strength to 3'b011 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) phy_update_bits(rphy->phy_base + 0x40, GENMASK(5, 3), (0x03 << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) /* Set RX Squelch trigger point configure to 4'b0000(112.5 mV) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) phy_update_bits(rphy->phy_base + 0x64, GENMASK(6, 3), (0x00 << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) /* Turn off differential receiver by default to save power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) phy_clear_bits(rphy->phy_base + 0x100, BIT(6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) /* Set 45ohm HS ODT value to 5'b10111 to increase driver strength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) phy_update_bits(rphy->phy_base + 0x11c, GENMASK(4, 0), 0x17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) /* Set Tx HS eye height tuning to 3'b011(462 mV)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) phy_update_bits(rphy->phy_base + 0x124, GENMASK(4, 2), (0x03 << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) /* Bypass Squelch detector calibration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) phy_update_bits(rphy->phy_base + 0x1a4, GENMASK(7, 4), (0x01 << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) phy_update_bits(rphy->phy_base + 0x1b4, GENMASK(7, 4), (0x01 << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) static int rk3568_vbus_detect_control(struct rockchip_usb2phy *rphy, bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) if (en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) /* Enable vbus voltage level detection function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) phy_clear_bits(rphy->phy_base + 0x3c, BIT(7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /* Disable vbus voltage level detection function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) phy_set_bits(rphy->phy_base + 0x3c, BIT(7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) /* Read the SIDDQ control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) ret = regmap_read(rphy->grf, 0x0008, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) if (reg & BIT(13)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) /* Deassert SIDDQ to power on analog block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) ret = regmap_write(rphy->grf, 0x0008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) GENMASK(29, 29) | 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) /* Do reset after exit IDDQ mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) ret = rockchip_usb2phy_reset(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) if (rphy->phy_cfg->reg == 0x0000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) * Set USB2 PHY0 suspend configuration for USB3_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) * 1. Set utmi_termselect to 1'b1 (en FS terminations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) * 2. Set utmi_xcvrselect to 2'b01 (FS transceiver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) * 3. Set utmi_opmode to 2'b01 (no-driving)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) ret |= regmap_write(rphy->grf, 0x000c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) GENMASK(20, 16) | 0x0015);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) ret |= regmap_write(rphy->grf, 0x0004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) GENMASK(27, 24) | 0x0900);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) ret |= regmap_write(rphy->grf, 0x0008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) GENMASK(20, 19) | 0x0010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) /* Pullup iddig pin for USB3_0 OTG mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) ret |= regmap_write(rphy->grf, 0x0010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) GENMASK(17, 16) | 0x0003);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) } else if (rphy->phy_cfg->reg == 0x4000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) * Set USB2 PHY1 suspend configuration for USB3_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) * 1. Set utmi_termselect to 1'b1 (en FS terminations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) * 2. Set utmi_xcvrselect to 2'b01(FS transceiver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) * 3. Set utmi_opmode to 2'b01 (no-driving)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) ret |= regmap_write(rphy->grf, 0x000c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) GENMASK(20, 16) | 0x0015);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) ret |= regmap_write(rphy->grf, 0x0004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) GENMASK(27, 24) | 0x0900);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) ret |= regmap_write(rphy->grf, 0x0008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) GENMASK(20, 19) | 0x0010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) /* Pullup iddig pin for USB3_1 OTG mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) ret |= regmap_write(rphy->grf, 0x0010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) GENMASK(17, 16) | 0x0003);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) } else if (rphy->phy_cfg->reg == 0x8000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) * Set USB2 PHY2 suspend configuration for USB2_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) * 1. Set utmi_termselect to 1'b1 (en FS terminations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) * 2. Set utmi_xcvrselect to 2'b01(FS transceiver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) * 3. Set utmi_opmode to 2'b00 (normal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) ret |= regmap_write(rphy->grf, 0x000c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) GENMASK(20, 16) | 0x0014);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) ret |= regmap_write(rphy->grf, 0x0004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) GENMASK(27, 24) | 0x0900);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) ret |= regmap_write(rphy->grf, 0x0008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) GENMASK(20, 19) | 0x0010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) } else if (rphy->phy_cfg->reg == 0xc000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) * Set USB2 PHY3 suspend configuration for USB2_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) * 1. Set utmi_termselect to 1'b1 (en FS terminations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) * 2. Set utmi_xcvrselect to 2'b01(FS transceiver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) * 3. Set utmi_opmode to 2'b00 (normal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) ret |= regmap_write(rphy->grf, 0x000c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) GENMASK(20, 16) | 0x0014);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) ret |= regmap_write(rphy->grf, 0x0004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) GENMASK(27, 24) | 0x0900);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) ret |= regmap_write(rphy->grf, 0x0008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) GENMASK(20, 19) | 0x0010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) static int rockchip_usb2phy_pm_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) struct rockchip_usb2phy *rphy = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) const struct rockchip_usb2phy_cfg *phy_cfg = rphy->phy_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) struct rockchip_usb2phy_port *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) bool wakeup_enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) if (device_may_wakeup(rphy->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) wakeup_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) * Set the linestate filter time to 1ms based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) * on the usb2 phy grf pclk 32KHz on suspend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) if (phy_cfg->ls_filter_con.enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) ret = regmap_write(rphy->grf, phy_cfg->ls_filter_con.offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) phy_cfg->ls_filter_con.enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) dev_err(rphy->dev, "failed to set ls filter %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) for (index = 0; index < phy_cfg->num_ports; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) rport = &rphy->ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) if (!rport->phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) if (rport->port_id == USB2PHY_PORT_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) (rport->id_irq > 0 || rphy->irq > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) rport->prev_iddig = property_enabled(rphy->grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) &rport->port_cfg->utmi_iddig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) ret = rockchip_usb2phy_enable_id_irq(rphy, rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) dev_err(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) "failed to disable id irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) if (rport->port_id == USB2PHY_PORT_OTG && wakeup_enable &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) rport->bvalid_irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) enable_irq_wake(rport->bvalid_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) /* activate the linestate to detect the next interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) ret = rockchip_usb2phy_enable_line_irq(rphy, rport, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) dev_err(rphy->dev, "failed to enable linestate irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) if (wakeup_enable && rport->ls_irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) enable_irq_wake(rport->ls_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) /* enter low power state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) rockchip_usb2phy_low_power_enable(rphy, rport, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) if (wakeup_enable && rphy->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) enable_irq_wake(rphy->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) static int rockchip_usb2phy_pm_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) struct rockchip_usb2phy *rphy = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) const struct rockchip_usb2phy_cfg *phy_cfg = rphy->phy_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) struct rockchip_usb2phy_port *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) bool iddig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) bool wakeup_enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) if (device_may_wakeup(rphy->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) wakeup_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) * PHY lost power in suspend, it needs to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) * PHY to recovery clock to usb controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) if (!wakeup_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) rockchip_usb2phy_reset(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) if (phy_cfg->phy_tuning)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) ret = phy_cfg->phy_tuning(rphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) if (phy_cfg->ls_filter_con.disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) ret = regmap_write(rphy->grf, phy_cfg->ls_filter_con.offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) phy_cfg->ls_filter_con.disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) dev_err(rphy->dev, "failed to set ls filter %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) for (index = 0; index < phy_cfg->num_ports; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) rport = &rphy->ports[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) if (!rport->phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) if (rport->port_id == USB2PHY_PORT_OTG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) (rport->id_irq > 0 || rphy->irq > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) mutex_lock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) iddig = property_enabled(rphy->grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) &rport->port_cfg->utmi_iddig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) ret = rockchip_usb2phy_enable_id_irq(rphy, rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) mutex_unlock(&rport->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) dev_err(rphy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) "failed to enable id irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) if (iddig != rport->prev_iddig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) dev_dbg(&rport->phy->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) "iddig changed during resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) rport->prev_iddig = iddig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) extcon_set_state_sync(rphy->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) EXTCON_USB_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) !iddig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) extcon_set_state_sync(rphy->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) EXTCON_USB_VBUS_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) !iddig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) ret = rockchip_set_vbus_power(rport, !iddig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) if (rport->port_id == USB2PHY_PORT_OTG && wakeup_enable &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) rport->bvalid_irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) disable_irq_wake(rport->bvalid_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) if (wakeup_enable && rport->ls_irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) disable_irq_wake(rport->ls_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) /* exit low power state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) rockchip_usb2phy_low_power_enable(rphy, rport, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) if (wakeup_enable && rphy->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) disable_irq_wake(rphy->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) static const struct dev_pm_ops rockchip_usb2phy_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) SET_SYSTEM_SLEEP_PM_OPS(rockchip_usb2phy_pm_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) rockchip_usb2phy_pm_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) #define ROCKCHIP_USB2PHY_DEV_PM (&rockchip_usb2phy_dev_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) #define ROCKCHIP_USB2PHY_DEV_PM NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) static const struct rockchip_usb2phy_cfg rk1808_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) .reg = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) .clkout_ctl = { 0x108, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) .bvalid_det_en = { 0x0110, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) .bvalid_det_st = { 0x0114, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) .bypass_dm_en = { 0x0108, 2, 2, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) .bypass_sel = { 0x0108, 3, 3, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) .iddig_output = { 0x0100, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) .iddig_en = { 0x0100, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) .idfall_det_en = { 0x0110, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) .idfall_det_st = { 0x0114, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) .idfall_det_clr = { 0x0118, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) .idrise_det_en = { 0x0110, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) .idrise_det_st = { 0x0114, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) .idrise_det_clr = { 0x0118, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) .ls_det_en = { 0x0110, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) .ls_det_st = { 0x0114, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) .ls_det_clr = { 0x0118, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) .utmi_avalid = { 0x0120, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) .utmi_bvalid = { 0x0120, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) .utmi_iddig = { 0x0120, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) .utmi_ls = { 0x0120, 5, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) .vbus_det_en = { 0x001c, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) .phy_sus = { 0x104, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) .ls_det_en = { 0x110, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) .ls_det_st = { 0x114, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) .ls_det_clr = { 0x118, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) .utmi_ls = { 0x120, 17, 16, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) .utmi_hstdet = { 0x120, 19, 19, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) .chg_mode = { 0x0100, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) .cp_det = { 0x0120, 24, 24, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) .dcp_det = { 0x0120, 23, 23, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) .dp_det = { 0x0120, 25, 25, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) .idm_sink_en = { 0x0108, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) .idp_sink_en = { 0x0108, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) .idp_src_en = { 0x0108, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) static const struct rockchip_usb2phy_cfg rk312x_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) .reg = 0x17c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) .phy_tuning = rk312x_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) .clkout_ctl = { 0x0190, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) .phy_sus = { 0x017c, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) .bvalid_det_en = { 0x017c, 14, 14, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) .bvalid_det_st = { 0x017c, 15, 15, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) .bvalid_det_clr = { 0x017c, 15, 15, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) .bypass_dm_en = { 0x0190, 12, 12, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) .bypass_sel = { 0x0190, 13, 13, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) .iddig_output = { 0x017c, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) .iddig_en = { 0x017c, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) .idfall_det_en = { 0x01a0, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) .idfall_det_st = { 0x01a0, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) .idfall_det_clr = { 0x01a0, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) .idrise_det_en = { 0x01a0, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) .idrise_det_st = { 0x01a0, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) .idrise_det_clr = { 0x01a0, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) .ls_det_en = { 0x017c, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) .ls_det_st = { 0x017c, 13, 13, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) .ls_det_clr = { 0x017c, 13, 13, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) .utmi_bvalid = { 0x014c, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) .utmi_iddig = { 0x014c, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) .utmi_ls = { 0x014c, 7, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) .phy_sus = { 0x0194, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) .ls_det_en = { 0x0194, 14, 14, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) .ls_det_st = { 0x0194, 15, 15, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) .ls_det_clr = { 0x0194, 15, 15, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) .chg_mode = { 0x017c, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) .cp_det = { 0x02c0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) .dcp_det = { 0x02c0, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) .dp_det = { 0x02c0, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) .idm_sink_en = { 0x0184, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) .idp_sink_en = { 0x0184, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) .idp_src_en = { 0x0184, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) .rdm_pdwn_en = { 0x0184, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) .vdm_src_en = { 0x0184, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) .vdp_src_en = { 0x0184, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) .reg = 0x760,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) .phy_tuning = rk3228_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) .clkout_ctl = { 0x0768, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) .phy_sus = { 0x0760, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) .bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) .bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) .iddig_output = { 0x0760, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) .iddig_en = { 0x0760, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) .idfall_det_en = { 0x0680, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) .idfall_det_st = { 0x0690, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) .idfall_det_clr = { 0x06a0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) .idrise_det_en = { 0x0680, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) .idrise_det_st = { 0x0690, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) .idrise_det_clr = { 0x06a0, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) .ls_det_en = { 0x0680, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) .ls_det_st = { 0x0690, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) .ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) .utmi_bvalid = { 0x0480, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) .utmi_iddig = { 0x0480, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) .utmi_ls = { 0x0480, 3, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) .vbus_det_en = { 0x0788, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) .phy_sus = { 0x0764, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) .ls_det_en = { 0x0680, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) .ls_det_st = { 0x0690, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) .ls_det_clr = { 0x06a0, 4, 4, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) .chg_mode = { 0x0760, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) .cp_det = { 0x0884, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) .dcp_det = { 0x0884, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) .dp_det = { 0x0884, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) .idm_sink_en = { 0x0768, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) .idp_sink_en = { 0x0768, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) .idp_src_en = { 0x0768, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) .rdm_pdwn_en = { 0x0768, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) .vdm_src_en = { 0x0768, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) .vdp_src_en = { 0x0768, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) .reg = 0x800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) .clkout_ctl = { 0x0808, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) .phy_sus = { 0x804, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) .ls_det_en = { 0x0684, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) .ls_det_st = { 0x0694, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) .ls_det_clr = { 0x06a4, 1, 1, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) .phy_sus = { 0x800, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) .ls_det_en = { 0x0684, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) .ls_det_st = { 0x0694, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) .ls_det_clr = { 0x06a4, 0, 0, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) .reg = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) .phy_tuning = rk3308_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) .clkout_ctl = { 0x0108, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) .bvalid_det_en = { 0x3020, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) .bvalid_det_st = { 0x3024, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) .bvalid_det_clr = { 0x3028, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) .iddig_output = { 0x0100, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) .iddig_en = { 0x0100, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) .idfall_det_en = { 0x3020, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) .idfall_det_st = { 0x3024, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) .idfall_det_clr = { 0x3028, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) .idrise_det_en = { 0x3020, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) .idrise_det_st = { 0x3024, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) .idrise_det_clr = { 0x3028, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) .ls_det_en = { 0x3020, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) .ls_det_st = { 0x3024, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) .ls_det_clr = { 0x3028, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) .utmi_avalid = { 0x0120, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) .utmi_bvalid = { 0x0120, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) .utmi_iddig = { 0x0120, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) .utmi_ls = { 0x0120, 5, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) .vbus_det_en = { 0x001c, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) .phy_sus = { 0x0104, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) .ls_det_en = { 0x3020, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) .ls_det_st = { 0x3024, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) .ls_det_clr = { 0x3028, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) .utmi_ls = { 0x120, 17, 16, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) .utmi_hstdet = { 0x120, 19, 19, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) .chg_mode = { 0x0100, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) .cp_det = { 0x0120, 24, 24, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) .dcp_det = { 0x0120, 23, 23, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) .dp_det = { 0x0120, 25, 25, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) .idm_sink_en = { 0x0108, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) .idp_sink_en = { 0x0108, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) .idp_src_en = { 0x0108, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) .reg = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) .phy_tuning = rk3328_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) .clkout_ctl = { 0x108, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) .bvalid_det_en = { 0x0110, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) .bvalid_det_st = { 0x0114, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) .bypass_bc = { 0x0008, 14, 14, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) .bypass_otg = { 0x0018, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) .iddig_output = { 0x0100, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) .iddig_en = { 0x0100, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) .idfall_det_en = { 0x0110, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) .idfall_det_st = { 0x0114, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) .idfall_det_clr = { 0x0118, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) .idrise_det_en = { 0x0110, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) .idrise_det_st = { 0x0114, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) .idrise_det_clr = { 0x0118, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) .ls_det_en = { 0x0110, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) .ls_det_st = { 0x0114, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) .ls_det_clr = { 0x0118, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) .utmi_avalid = { 0x0120, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) .utmi_bvalid = { 0x0120, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) .utmi_iddig = { 0x0120, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) .utmi_ls = { 0x0120, 5, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) .vbus_det_en = { 0x001c, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) .phy_sus = { 0x104, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) .bypass_host = { 0x048, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) .ls_det_en = { 0x110, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) .ls_det_st = { 0x114, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) .ls_det_clr = { 0x118, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) .utmi_ls = { 0x120, 17, 16, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) .utmi_hstdet = { 0x120, 19, 19, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) .chg_mode = { 0x0100, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) .cp_det = { 0x0120, 24, 24, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) .dcp_det = { 0x0120, 23, 23, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) .dp_det = { 0x0120, 25, 25, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) .idm_sink_en = { 0x0108, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) .idp_sink_en = { 0x0108, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) .idp_src_en = { 0x0108, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) .reg = 0x700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) .phy_tuning = rk3366_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) .clkout_ctl = { 0x0724, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) .phy_sus = { 0x0728, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) .ls_det_en = { 0x0680, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) .ls_det_st = { 0x0690, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) .ls_det_clr = { 0x06a0, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) .utmi_ls = { 0x049c, 14, 13, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) .utmi_hstdet = { 0x049c, 12, 12, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) static const struct rockchip_usb2phy_cfg rk3368_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) .reg = 0x700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) .clkout_ctl = { 0x0724, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) .phy_sus = { 0x0700, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) .bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) .bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) .iddig_output = { 0x0700, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) .iddig_en = { 0x0700, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) .idfall_det_en = { 0x0680, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) .idfall_det_st = { 0x0690, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) .idfall_det_clr = { 0x06a0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) .idrise_det_en = { 0x0680, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) .idrise_det_st = { 0x0690, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) .idrise_det_clr = { 0x06a0, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) .ls_det_en = { 0x0680, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) .ls_det_st = { 0x0690, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) .ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) .utmi_bvalid = { 0x04bc, 23, 23, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) .utmi_iddig = { 0x04bc, 26, 26, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) .utmi_ls = { 0x04bc, 25, 24, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) .vbus_det_en = { 0x079c, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) .phy_sus = { 0x0728, 15, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) .ls_det_en = { 0x0680, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) .ls_det_st = { 0x0690, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) .ls_det_clr = { 0x06a0, 4, 4, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) .chg_mode = { 0x0700, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) .cp_det = { 0x04b8, 30, 30, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) .dcp_det = { 0x04b8, 29, 29, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) .dp_det = { 0x04b8, 31, 31, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) .idm_sink_en = { 0x0718, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) .idp_sink_en = { 0x0718, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) .idp_src_en = { 0x0718, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) .rdm_pdwn_en = { 0x0718, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) .vdm_src_en = { 0x0718, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) .vdp_src_en = { 0x0718, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) .reg = 0xe450,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) .phy_tuning = rk3399_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) .clkout_ctl = { 0xe450, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) .phy_sus = { 0xe454, 8, 0, 0x052, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) .bvalid_det_en = { 0xe3c0, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) .bvalid_det_st = { 0xe3e0, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) .bypass_dm_en = { 0xe450, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) .bypass_sel = { 0xe450, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) .iddig_output = { 0xe454, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) .iddig_en = { 0xe454, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) .idfall_det_en = { 0xe3c0, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) .idfall_det_st = { 0xe3e0, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) .idfall_det_clr = { 0xe3d0, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) .idrise_det_en = { 0xe3c0, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) .idrise_det_st = { 0xe3e0, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) .idrise_det_clr = { 0xe3d0, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) .ls_det_en = { 0xe3c0, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) .ls_det_st = { 0xe3e0, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) .ls_det_clr = { 0xe3d0, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) .utmi_avalid = { 0xe2ac, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) .utmi_bvalid = { 0xe2ac, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) .utmi_iddig = { 0xe2ac, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) .utmi_ls = { 0xe2ac, 14, 13, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) .vbus_det_en = { 0x449c, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) .phy_sus = { 0xe458, 1, 0, 0x2, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) .ls_det_en = { 0xe3c0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) .ls_det_st = { 0xe3e0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) .ls_det_clr = { 0xe3d0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) .utmi_ls = { 0xe2ac, 22, 21, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) .utmi_hstdet = { 0xe2ac, 23, 23, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) .chg_mode = { 0xe454, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) .cp_det = { 0xe2ac, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) .dcp_det = { 0xe2ac, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) .dp_det = { 0xe2ac, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) .idm_sink_en = { 0xe450, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) .idp_sink_en = { 0xe450, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) .idp_src_en = { 0xe450, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) .rdm_pdwn_en = { 0xe450, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) .vdm_src_en = { 0xe450, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) .vdp_src_en = { 0xe450, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) .reg = 0xe460,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) .phy_tuning = rk3399_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) .clkout_ctl = { 0xe460, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) .phy_sus = { 0xe464, 8, 0, 0x052, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) .bvalid_det_en = { 0xe3c0, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) .bvalid_det_st = { 0xe3e0, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) .iddig_output = { 0xe464, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) .iddig_en = { 0xe464, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) .idfall_det_en = { 0xe3c0, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) .idfall_det_st = { 0xe3e0, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) .idfall_det_clr = { 0xe3d0, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) .idrise_det_en = { 0xe3c0, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) .idrise_det_st = { 0xe3e0, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) .idrise_det_clr = { 0xe3d0, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) .ls_det_en = { 0xe3c0, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) .ls_det_st = { 0xe3e0, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) .ls_det_clr = { 0xe3d0, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) .utmi_avalid = { 0xe2ac, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) .utmi_bvalid = { 0xe2ac, 16, 16, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) .utmi_iddig = { 0xe2ac, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) .utmi_ls = { 0xe2ac, 18, 17, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) .vbus_det_en = { 0x451c, 15, 15, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) .phy_sus = { 0xe468, 1, 0, 0x2, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) .ls_det_en = { 0xe3c0, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) .ls_det_st = { 0xe3e0, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) .ls_det_clr = { 0xe3d0, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) .utmi_ls = { 0xe2ac, 26, 25, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) .utmi_hstdet = { 0xe2ac, 27, 27, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) .chg_mode = { 0xe464, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) .cp_det = { 0xe2ac, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) .dcp_det = { 0xe2ac, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) .dp_det = { 0xe2ac, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) .idm_sink_en = { 0xe460, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) .idp_sink_en = { 0xe460, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) .idp_src_en = { 0xe460, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) .rdm_pdwn_en = { 0xe460, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) .vdm_src_en = { 0xe460, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) .vdp_src_en = { 0xe460, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) .reg = 0xfe8a0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) .phy_tuning = rk3568_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) .vbus_detect = rk3568_vbus_detect_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) .clkout_ctl = { 0x0008, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) .phy_sus = { 0x0000, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) .bvalid_det_en = { 0x0080, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) .bvalid_det_st = { 0x0084, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) .bvalid_det_clr = { 0x0088, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) .bvalid_grf_sel = { 0x0008, 15, 14, 0, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) .bypass_dm_en = { 0x0008, 2, 2, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) .bypass_sel = { 0x0008, 3, 3, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) .iddig_output = { 0x0000, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) .iddig_en = { 0x0000, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) .idfall_det_en = { 0x0080, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) .idfall_det_st = { 0x0084, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) .idfall_det_clr = { 0x0088, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) .idrise_det_en = { 0x0080, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) .idrise_det_st = { 0x0084, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) .idrise_det_clr = { 0x0088, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) .ls_det_en = { 0x0080, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) .ls_det_st = { 0x0084, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) .utmi_avalid = { 0x00c0, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) .utmi_iddig = { 0x00c0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) .utmi_ls = { 0x00c0, 5, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) /* Select suspend control from controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) .ls_det_en = { 0x0080, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) .ls_det_st = { 0x0084, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) .ls_det_clr = { 0x0088, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) .utmi_ls = { 0x00c0, 17, 16, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) .chg_mode = { 0x0000, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) .cp_det = { 0x00c0, 24, 24, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) .dcp_det = { 0x00c0, 23, 23, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) .dp_det = { 0x00c0, 25, 25, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) .idm_sink_en = { 0x0008, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) .idp_sink_en = { 0x0008, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) .idp_src_en = { 0x0008, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) .rdm_pdwn_en = { 0x0008, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) .vdm_src_en = { 0x0008, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) .vdp_src_en = { 0x0008, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) .reg = 0xfe8b0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) .phy_tuning = rk3568_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) .clkout_ctl = { 0x0008, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) .phy_sus = { 0x0000, 8, 0, 0x1d2, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) .ls_det_en = { 0x0080, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) .ls_det_st = { 0x0084, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) .utmi_ls = { 0x00c0, 5, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) .utmi_hstdet = { 0x00c0, 7, 7, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) .ls_det_en = { 0x0080, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) .ls_det_st = { 0x0084, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) .ls_det_clr = { 0x0088, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) .utmi_ls = { 0x00c0, 17, 16, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) .reg = 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) .phy_tuning = rk3588_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) .clkout_ctl = { 0x0000, 0, 0, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) .phy_sus = { 0x000c, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) .pipe_phystatus = { 0x001c, 3, 2, 0, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) .bvalid_det_en = { 0x0080, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) .bvalid_det_st = { 0x0084, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) .bvalid_det_clr = { 0x0088, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) .bvalid_grf_sel = { 0x0010, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) .bvalid_grf_con = { 0x0010, 3, 2, 2, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) .bvalid_phy_con = { 0x0008, 1, 0, 2, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) .bypass_dm_en = { 0x000c, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) .bypass_sel = { 0x000c, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) .iddig_output = { 0x0010, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) .iddig_en = { 0x0010, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) .idfall_det_en = { 0x0080, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) .idfall_det_st = { 0x0084, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) .idfall_det_clr = { 0x0088, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) .idrise_det_en = { 0x0080, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) .idrise_det_st = { 0x0084, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) .idrise_det_clr = { 0x0088, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) .ls_det_en = { 0x0080, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) .ls_det_st = { 0x0084, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) .disfall_en = { 0x0080, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) .disfall_st = { 0x0084, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) .disfall_clr = { 0x0088, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) .disrise_en = { 0x0080, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) .disrise_st = { 0x0084, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) .disrise_clr = { 0x0088, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) .utmi_avalid = { 0x00c0, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) .utmi_bvalid = { 0x00c0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) .utmi_iddig = { 0x00c0, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) .utmi_ls = { 0x00c0, 10, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) .chg_mode = { 0x0008, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) .cp_det = { 0x00c0, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) .dcp_det = { 0x00c0, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) .dp_det = { 0x00c0, 1, 1, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) .idm_sink_en = { 0x0008, 5, 5, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) .idp_sink_en = { 0x0008, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) .idp_src_en = { 0x0008, 14, 14, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) .rdm_pdwn_en = { 0x0008, 14, 14, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) .vdm_src_en = { 0x0008, 7, 6, 0, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) .vdp_src_en = { 0x0008, 7, 6, 0, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) .reg = 0x4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) .phy_tuning = rk3588_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) .clkout_ctl = { 0x0000, 0, 0, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) .phy_sus = { 0x000c, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) .pipe_phystatus = { 0x0034, 3, 2, 0, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) .bvalid_det_en = { 0x0080, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) .bvalid_det_st = { 0x0084, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) .bvalid_det_clr = { 0x0088, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) .bvalid_grf_sel = { 0x0010, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) .bvalid_grf_con = { 0x0010, 3, 2, 2, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) .bvalid_phy_con = { 0x0008, 1, 0, 2, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) .bypass_dm_en = { 0x000c, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) .bypass_sel = { 0x000c, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) .iddig_output = { 0x0010, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) .iddig_en = { 0x0010, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) .idfall_det_en = { 0x0080, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) .idfall_det_st = { 0x0084, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) .idfall_det_clr = { 0x0088, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) .idrise_det_en = { 0x0080, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) .idrise_det_st = { 0x0084, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) .idrise_det_clr = { 0x0088, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) .ls_det_en = { 0x0080, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) .ls_det_st = { 0x0084, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) .disfall_en = { 0x0080, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) .disfall_st = { 0x0084, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) .disfall_clr = { 0x0088, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) .disrise_en = { 0x0080, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) .disrise_st = { 0x0084, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) .disrise_clr = { 0x0088, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) .utmi_avalid = { 0x00c0, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) .utmi_bvalid = { 0x00c0, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) .utmi_iddig = { 0x00c0, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) .utmi_ls = { 0x00c0, 10, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) .chg_mode = { 0x0008, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) .cp_det = { 0x00c0, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) .dcp_det = { 0x00c0, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) .dp_det = { 0x00c0, 1, 1, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) .idm_sink_en = { 0x0008, 5, 5, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) .idp_sink_en = { 0x0008, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) .idp_src_en = { 0x0008, 14, 14, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) .rdm_pdwn_en = { 0x0008, 14, 14, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) .vdm_src_en = { 0x0008, 7, 6, 0, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) .vdp_src_en = { 0x0008, 7, 6, 0, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) .reg = 0x8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) .phy_tuning = rk3588_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) .clkout_ctl = { 0x0000, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) .phy_sus = { 0x0008, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) .ls_det_en = { 0x0080, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) .ls_det_st = { 0x0084, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) .disfall_en = { 0x0080, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) .disfall_st = { 0x0084, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) .disfall_clr = { 0x0088, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) .disrise_en = { 0x0080, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) .disrise_st = { 0x0084, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) .disrise_clr = { 0x0088, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) .utmi_ls = { 0x00c0, 10, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) .reg = 0xc000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) .phy_tuning = rk3588_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) .clkout_ctl = { 0x0000, 0, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) .phy_sus = { 0x0008, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) .ls_det_en = { 0x0080, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) .ls_det_st = { 0x0084, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) .disfall_en = { 0x0080, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) .disfall_st = { 0x0084, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) .disfall_clr = { 0x0088, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) .disrise_en = { 0x0080, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) .disrise_st = { 0x0084, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) .disrise_clr = { 0x0088, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) .utmi_ls = { 0x00c0, 10, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) static const struct rockchip_usb2phy_cfg rv1106_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) .reg = 0xff3e0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) .num_ports = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) .phy_tuning = rv1106_usb2phy_tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) .clkout_ctl = { 0x0058, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) .phy_sus = { 0x0050, 8, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) .bvalid_det_en = { 0x0100, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) .bvalid_det_st = { 0x0104, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) .bvalid_det_clr = { 0x0108, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) .bvalid_grf_sel = { 0x0058, 15, 14, 0, 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) .iddig_output = { 0x0050, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) .iddig_en = { 0x0050, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) .idfall_det_en = { 0x0100, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) .idfall_det_st = { 0x0104, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) .idfall_det_clr = { 0x0108, 5, 5, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) .idrise_det_en = { 0x0100, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) .idrise_det_st = { 0x0104, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) .idrise_det_clr = { 0x0108, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) .ls_det_en = { 0x0100, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) .ls_det_st = { 0x0104, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) .ls_det_clr = { 0x0108, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) .utmi_avalid = { 0x0060, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) .utmi_bvalid = { 0x0060, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) .utmi_iddig = { 0x0060, 6, 6, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) .utmi_ls = { 0x0060, 5, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) .chg_mode = { 0x0050, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) .cp_det = { 0x0060, 13, 13, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) .dcp_det = { 0x0060, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) .dp_det = { 0x0060, 14, 14, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) .idm_sink_en = { 0x0058, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) .idp_sink_en = { 0x0058, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) .idp_src_en = { 0x0058, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) .rdm_pdwn_en = { 0x0058, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) .vdm_src_en = { 0x0058, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) .vdp_src_en = { 0x0058, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) .reg = 0x100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) .num_ports = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) .clkout_ctl = { 0x108, 4, 4, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) .port_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) [USB2PHY_PORT_OTG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) .phy_sus = { 0x0100, 15, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) .bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) .bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) .ls_det_en = { 0x0680, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) .ls_det_st = { 0x0690, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) .ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) .utmi_bvalid = { 0x0804, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) .utmi_ls = { 0x0804, 13, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) [USB2PHY_PORT_HOST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) .phy_sus = { 0x0104, 15, 0, 0, 0x1d1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) .ls_det_en = { 0x0680, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) .ls_det_st = { 0x0690, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) .ls_det_clr = { 0x06a0, 4, 4, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) .utmi_ls = { 0x0804, 9, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) .utmi_hstdet = { 0x0804, 7, 7, 0, 1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) .chg_det = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) .chg_mode = { 0x0100, 8, 0, 0, 0x1d7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) .cp_det = { 0x0804, 1, 1, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) .dcp_det = { 0x0804, 0, 0, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) .dp_det = { 0x0804, 2, 2, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) .idm_sink_en = { 0x0108, 8, 8, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) .idp_sink_en = { 0x0108, 7, 7, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) .idp_src_en = { 0x0108, 9, 9, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) static const struct of_device_id rockchip_usb2phy_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) #ifdef CONFIG_CPU_PX30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) { .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) #ifdef CONFIG_CPU_RK1808
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) { .compatible = "rockchip,rk1808-usb2phy", .data = &rk1808_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) #ifdef CONFIG_CPU_RK312X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) { .compatible = "rockchip,rk3128-usb2phy", .data = &rk312x_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) #ifdef CONFIG_CPU_RK322X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) { .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) #ifdef CONFIG_CPU_RK3308
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) { .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) #ifdef CONFIG_CPU_RK3328
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) #ifdef CONFIG_CPU_RK3366
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) #ifdef CONFIG_CPU_RK3368
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) { .compatible = "rockchip,rk3368-usb2phy", .data = &rk3368_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) #ifdef CONFIG_CPU_RK3399
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) #ifdef CONFIG_CPU_RK3568
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) #ifdef CONFIG_CPU_RK3588
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) { .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) #ifdef CONFIG_CPU_RV1106
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) { .compatible = "rockchip,rv1106-usb2phy", .data = &rv1106_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) #ifdef CONFIG_CPU_RV1108
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) static struct platform_driver rockchip_usb2phy_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) .probe = rockchip_usb2phy_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) .name = "rockchip-usb2phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) .pm = ROCKCHIP_USB2PHY_DEV_PM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) .of_match_table = rockchip_usb2phy_dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) module_platform_driver(rockchip_usb2phy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) MODULE_DESCRIPTION("Rockchip USB2.0 PHY driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) MODULE_LICENSE("GPL v2");