usb: dwc2: Updates for new core v5.00a
Subsystems (2)
cover usb: dwc2: Updates for new core v5.00a
Patch series includes updates for new core v5.00a
Minas Harutyunyan (7):
usb: dwc2: Add core new versions definition
usb: dwc2: New bit definition in GOTGCTL register
usb: dwc2: Add new parameter eusb2_disc
usb: dwc2: Add eUSB2 PHY disconnect flow support
usb: dwc2: New bit definition in GPWRDN register
usb: dwc2: Add hibernation updates for ULPI PHY
usb: dwc2: New bitfield definition and programming in GRSTCTL
drivers/usb/dwc2/core.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/usb/dwc2/core.h | 8 +++++++ drivers/usb/dwc2/core_intr.c | 26 +++++++++++++++++++--- drivers/usb/dwc2/debugfs.c | 1 + drivers/usb/dwc2/gadget.c | 28 +++++++++++++++++++++++- drivers/usb/dwc2/hcd.c | 10 +++++++++ drivers/usb/dwc2/hw.h | 14 ++++++++++++ drivers/usb/dwc2/params.c | 22 +++++++++++++++++++ 8 files changed, 147 insertions(+), 4 deletions(-)
base-commit: 13bd5583e987e8bb0b95dd7607b17e5938bf42b3
Signature · 1 line
2.41.0
PATCH 1/7 usb: dwc2: Add core new versions definition
Added new versions definition for HSOTG core v5.00a and IOT HS device core v5.00.
--- drivers/usb/dwc2/core.h | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/dwc2/core.h +2 -0
@@ -1097,8 +1097,10 @@ struct dwc2_hsotg {#define DWC2_CORE_REV_3_10a 0x4f54310a#define DWC2_CORE_REV_4_00a 0x4f54400a#define DWC2_CORE_REV_4_20a 0x4f54420a +#define DWC2_CORE_REV_5_00a 0x4f54500a#define DWC2_FS_IOT_REV_1_00a 0x5531100a#define DWC2_HS_IOT_REV_1_00a 0x5532100a +#define DWC2_HS_IOT_REV_5_00a 0x5532500a#define DWC2_CORE_REV_MASK 0x0000ffff/* DWC OTG HW Core ID */
Signature · 1 line
2.41.0
PATCH 2/7 usb: dwc2: New bit definition in GOTGCTL register
In reply to Minas HarutyunyanAdded new bit EUSB2_DISC_SUPP in GOTGCTL register. This bit applicable in device mode of HSOTG and HS IOT cores v5.00 or higher.
This bit used for Device Disconnect detection with eUSB2 PHY.
--- drivers/usb/dwc2/hw.h | 1 + 1 file changed, 1 insertion(+)
drivers/usb/dwc2/hw.h +1 -0
@@ -11,6 +11,7 @@#define HSOTG_REG (x) (x)#define GOTGCTL HSOTG_REG(0x000) +#define GOTGCTL_EUSB2_DISC_SUPP BIT(28)#define GOTGCTL_CHIRPEN BIT(27)#define GOTGCTL_MULT_VALID_BC_MASK (0x1f << 22)#define GOTGCTL_MULT_VALID_BC_SHIFT 22
Signature · 1 line
2.41.0
PATCH 3/7 usb: dwc2: Add new parameter eusb2_disc
In reply to Minas HarutyunyanAdded new parameter eusb2_disc to list of core parameters which specify whether eUSB2 PHY disconnect support flow applicable or no. Set to false as default value and checked core version if set to true. This parameter applicable in device mode of HSOTG and HS IOT cores v5.00 or higher.
Added print this parameter in show parameters of debugfs.
--- drivers/usb/dwc2/core.h | 6 ++++++ drivers/usb/dwc2/debugfs.c | 1 + drivers/usb/dwc2/params.c | 22 ++++++++++++++++++++++ 3 files changed, 29 insertions(+)
drivers/usb/dwc2/core.h +6 -0
@@ -288,6 +288,11 @@ enum dwc2_ep0_state {* core has been configured to work at either data path * width. * 8 or 16 (default 16 if available) +* @eusb2_disc: Specifies whether eUSB2 PHY disconnect support flow +* applicable or no. Applicable in device mode of HSOTG +* and HS IOT cores v5.00 or higher. +* 0 - eUSB2 PHY disconnect support flow not applicable +* 1 - eUSB2 PHY disconnect support flow applicable * @phy_ulpi_ddr: Specifies whether the ULPI operates at double or single * data rate. This parameter is only applicable if phy_type * is ULPI.
@@ -442,6 +447,7 @@ struct dwc2_core_params {#define DWC2_SPEED_PARAM_LOW 2u8 phy_utmi_width; +bool eusb2_disc;bool phy_ulpi_ddr;bool phy_ulpi_ext_vbus;bool enable_dynamic_fifo;
drivers/usb/dwc2/debugfs.c +1 -0
@@ -686,6 +686,7 @@ static int params_show(struct seq_file *seq, void *v)print_param (seq, p, host_channels);print_param (seq, p, phy_type);print_param (seq, p, phy_utmi_width); +print_param (seq, p, eusb2_disc);print_param (seq, p, phy_ulpi_ddr);print_param (seq, p, phy_ulpi_ext_vbus);print_param (seq, p, i2c_enable);
drivers/usb/dwc2/params.c +22 -0
@@ -475,6 +475,7 @@ static void dwc2_set_default_params(struct dwc2_hsotg *hsotg)dwc2_set_param_lpm (hsotg); p->phy_ulpi_ddr = false; p->phy_ulpi_ext_vbus = false; + p->eusb2_disc = false; p->enable_dynamic_fifo = hw->enable_dynamic_fifo; p->en_multiple_tx_fifo = hw->en_multiple_tx_fifo;
@@ -737,6 +738,25 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg) } } +static void dwc2_check_param_eusb2_disc (struct dwc2_hsotg *hsotg) +{ +u32 gsnpsid; + +if (!hsotg->params.eusb2_disc) +return ; + gsnpsid =dwc2_readl (hsotg,GSNPSID ); +/* +* eusb2_disc not supported by FS IOT devices. +* For other cores, it supported starting from version 5.00a +*/ +if ((gsnpsid & ~DWC2_CORE_REV_MASK ) ==DWC2_FS_IOT_ID || + (gsnpsid &DWC2_CORE_REV_MASK ) < + (DWC2_CORE_REV_5_00a &DWC2_CORE_REV_MASK )) { + hsotg->params.eusb2_disc = false; +return ; + } +} +#define CHECK_RANGE (_param, _min, _max, _def) do { \ if ((int)(hsotg->params._param) < (_min) || \ (hsotg->params._param) > (_max)) { \
@@ -765,6 +785,8 @@ static void dwc2_check_params(struct dwc2_hsotg *hsotg)dwc2_check_param_speed (hsotg);dwc2_check_param_phy_utmi_width (hsotg);dwc2_check_param_power_down (hsotg); +dwc2_check_param_eusb2_disc (hsotg); +CHECK_BOOL (enable_dynamic_fifo, hw->enable_dynamic_fifo);CHECK_BOOL (en_multiple_tx_fifo, hw->en_multiple_tx_fifo);CHECK_BOOL (i2c_enable, hw->i2c_enable);
Signature · 1 line
2.41.0
PATCH 4/7 usb: dwc2: Add eUSB2 PHY disconnect flow support
In reply to Minas HarutyunyanTo support eUSB2 PHY disconnect flow required in Soft disconnect state set GOTGCTL_EUSB2_DISC_SUPP bit, if applicable.
On Session End Detected interrupt clear PCGCTL_GATEHCLK and PCGCTL_STOPPCLK bits if eusb2_disc parameter true.
--- drivers/usb/dwc2/core_intr.c | 21 ++++++++++++++++++--- drivers/usb/dwc2/gadget.c | 5 ++++- 2 files changed, 22 insertions(+), 4 deletions(-)
drivers/usb/dwc2/core_intr.c +18 -3
@@ -84,6 +84,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)u32 gotgint;u32 gotgctl;u32 gintmsk; +u32 pcgctl; gotgint =dwc2_readl (hsotg,GOTGINT ); gotgctl =dwc2_readl (hsotg,GOTGCTL );
@@ -96,8 +97,22 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) dwc2_op_state_str(hsotg)); gotgctl =dwc2_readl (hsotg,GOTGCTL ); -if (dwc2_is_device_mode (hsotg)) +if (dwc2_is_device_mode (hsotg)) { +if (hsotg->params.eusb2_disc) { +/* Clear the Gate hclk. */ + pcgctl =dwc2_readl (hsotg,PCGCTL ); + pcgctl &= ~PCGCTL_GATEHCLK ; +dwc2_writel (hsotg, pcgctl,PCGCTL ); +udelay (5 ); + +/* Clear Phy Clock bit. */ + pcgctl =dwc2_readl (hsotg,PCGCTL ); + pcgctl &= ~PCGCTL_STOPPCLK ; +dwc2_writel (hsotg, pcgctl,PCGCTL ); +udelay (5 ); + }dwc2_hsotg_disconnect (hsotg); + }if (hsotg->op_state ==OTG_STATE_B_HOST ) { hsotg->op_state =OTG_STATE_B_PERIPHERAL ;
@@ -117,7 +132,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)* disconnected */ /* Reset to a clean state */ - hsotg->lx_state =DWC2_L0 ; + hsotg->lx_state =DWC2_L3 ; } gotgctl =dwc2_readl (hsotg,GOTGCTL );
@@ -286,7 +301,7 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) hsotg->lx_state);if (dwc2_is_device_mode (hsotg)) { -if (hsotg->lx_state ==DWC2_L2 ) { +if (hsotg->lx_state !=DWC2_L0 ) {if (hsotg->in_ppd) { ret =dwc2_exit_partial_power_down (hsotg,0 , true);
drivers/usb/dwc2/gadget.c +4 -1
@@ -3420,8 +3420,11 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,dwc2_hsotg_init_fifo (hsotg); -if (!is_usb_reset) +if (!is_usb_reset) {dwc2_set_bit (hsotg,DCTL ,DCTL_SFTDISCON ); +if (hsotg->params.eusb2_disc) +dwc2_set_bit (hsotg,GOTGCTL ,GOTGCTL_EUSB2_DISC_SUPP ); + } dcfg |=DCFG_EPMISCNT (1 );
Signature · 1 line
2.41.0
PATCH 5/7 usb: dwc2: New bit definition in GPWRDN register
In reply to Minas HarutyunyanAdded new bit ULPI_LATCH_EN_DURING_HIB_ENTRY in GPWRDN register. This bit applicable HSOTG cores v5.00 or higher.
Affects Hibernation Entry and Exit sequence (for both Host and Device) when using ULPI PHY.
--- drivers/usb/dwc2/hw.h | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/dwc2/hw.h +2 -0
@@ -333,6 +333,8 @@#define GLPMCFG_LPMCAP BIT(0)#define GPWRDN HSOTG_REG(0x0058) + +#define GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY BIT(29)#define GPWRDN_MULT_VAL_ID_BC_MASK (0x1f << 24)#define GPWRDN_MULT_VAL_ID_BC_SHIFT 24#define GPWRDN_ADP_INT BIT(23)
Signature · 1 line
2.41.0
PATCH 6/7 usb: dwc2: Add hibernation updates for ULPI PHY
In reply to Minas HarutyunyanAdded programmming of ULPI_LATCH_EN_DURING_HIB_ENTRY bit in GPWRDN register when using ULPI PHY during entry/exit to/from hibernation. This bit set to 1 during entering to hibernation if ULPI PHY used. On exiting from hibernation this bit reset to 0. Applicable for both host and device modes.
--- drivers/usb/dwc2/core.c | 5 +++++ drivers/usb/dwc2/core_intr.c | 5 +++++ drivers/usb/dwc2/gadget.c | 23 +++++++++++++++++++++++ drivers/usb/dwc2/hcd.c | 10 ++++++++++ 4 files changed, 43 insertions(+)
drivers/usb/dwc2/core.c +5 -0
@@ -249,6 +249,11 @@ void dwc2_hib_restore_common(struct dwc2_hsotg *hsotg, int rem_wakeup,dwc2_writel (hsotg, gpwrdn,GPWRDN );udelay (10 ); +/* Reset ULPI latch */ + gpwrdn =dwc2_readl (hsotg,GPWRDN ); + gpwrdn &= ~GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY ; +dwc2_writel (hsotg, gpwrdn,GPWRDN ); +/* Disable PMU interrupt */ gpwrdn =dwc2_readl (hsotg,GPWRDN ); gpwrdn &= ~GPWRDN_PMUINTSEL ;
drivers/usb/dwc2/core_intr.c +5 -0
@@ -705,6 +705,11 @@ static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg, gpwrdn_tmp &= ~GPWRDN_PMUINTSEL ;dwc2_writel (hsotg, gpwrdn_tmp,GPWRDN ); +/* Reset ULPI latch */ + gpwrdn =dwc2_readl (hsotg,GPWRDN ); + gpwrdn &= ~GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY ; +dwc2_writel (hsotg, gpwrdn,GPWRDN ); +/* De-assert Wakeup Logic */ gpwrdn_tmp =dwc2_readl (hsotg,GPWRDN ); gpwrdn_tmp &= ~GPWRDN_PMUACTV ;
drivers/usb/dwc2/gadget.c +23 -0
@@ -5309,6 +5309,8 @@ void dwc2_gadget_program_ref_clk(struct dwc2_hsotg *hsotg)int dwc2_gadget_enter_hibernation (struct dwc2_hsotg *hsotg) {u32 gpwrdn; +u32 gusbcfg; +u32 pcgcctl;int ret =0 ;/* Change to L2(suspend) state */
@@ -5328,6 +5330,22 @@ int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg) } gpwrdn =GPWRDN_PWRDNRSTN ; +udelay (10 ); + gusbcfg =dwc2_readl (hsotg,GUSBCFG ); +if (gusbcfg &GUSBCFG_ULPI_UTMI_SEL ) { +/* ULPI interface */ + gpwrdn |=GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY ; + } +dwc2_writel (hsotg, gpwrdn,GPWRDN ); +udelay (10 ); + +/* Suspend the Phy Clock */ + pcgcctl =dwc2_readl (hsotg,PCGCTL ); + pcgcctl |=PCGCTL_STOPPCLK ; +dwc2_writel (hsotg, pcgcctl,PCGCTL ); +udelay (10 ); + + gpwrdn =dwc2_readl (hsotg,GPWRDN ); gpwrdn |=GPWRDN_PMUACTV ;dwc2_writel (hsotg, gpwrdn,GPWRDN );udelay (10 );
@@ -5428,6 +5446,11 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,if (reset)dwc2_clear_bit (hsotg,DCFG ,DCFG_DEVADDR_MASK ); +/* Reset ULPI latch */ + gpwrdn =dwc2_readl (hsotg,GPWRDN ); + gpwrdn &= ~GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY ; +dwc2_writel (hsotg, gpwrdn,GPWRDN ); +/* De-assert Wakeup Logic */ gpwrdn =dwc2_readl (hsotg,GPWRDN ); gpwrdn &= ~GPWRDN_PMUACTV ;
drivers/usb/dwc2/hcd.c +10 -0
@@ -5503,6 +5503,11 @@ int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg) gusbcfg =dwc2_readl (hsotg,GUSBCFG );if (gusbcfg &GUSBCFG_ULPI_UTMI_SEL ) {/* ULPI interface */ +udelay (10 ); + gpwrdn =dwc2_readl (hsotg,GPWRDN ); + gpwrdn |=GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY ; +dwc2_writel (hsotg, gpwrdn,GPWRDN ); +udelay (10 );/* Suspend the Phy Clock */ pcgcctl =dwc2_readl (hsotg,PCGCTL ); pcgcctl |=PCGCTL_STOPPCLK ;
@@ -5609,6 +5614,11 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,dwc2_writel (hsotg, gr->gusbcfg,GUSBCFG );dwc2_writel (hsotg, hr->hcfg,HCFG ); +/* Reset ULPI latch */ + gpwrdn =dwc2_readl (hsotg,GPWRDN ); + gpwrdn &= ~GPWRDN_ULPI_LATCH_EN_DURING_HIB_ENTRY ; +dwc2_writel (hsotg, gpwrdn,GPWRDN ); +/* De-assert Wakeup Logic */ gpwrdn =dwc2_readl (hsotg,GPWRDN ); gpwrdn &= ~GPWRDN_PMUACTV ;
Signature · 1 line
2.41.0
PATCH 7/7 usb: dwc2: New bitfield definition and programming in GRSTCTL
In reply to Minas HarutyunyanAdded new bitfield GRSTCTL_CLOCK_SWITH_TIMER in GRSTCTL register. This bitfield applicable HSOTG cores v5.00 or higher and not applicable to HS/FS IOT devices.
This bitfield must be programmed to 3'b010 if core will be used in Low-speed and core configured for any HS/FS PHY interface. This bitfield must be programmed to 3'b111 if core configured to use either:
- HS PHY interface UTMI or ULPI
- FS PHY any interface
--- drivers/usb/dwc2/core.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/usb/dwc2/hw.h | 11 +++++++++++ 2 files changed, 48 insertions(+)
drivers/usb/dwc2/core.c +37 -0
@@ -980,6 +980,41 @@ void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)dwc2_writel (hsotg, hcfg,HCFG ); } +static void dwc2_set_clock_switch_timer (struct dwc2_hsotg *hsotg) +{ +u32 grstctl, gsnpsid, val =0 ; + + gsnpsid =dwc2_readl (hsotg,GSNPSID ); + +/* +* Applicable only to HSOTG core v5.00a or higher. +* Not applicable to HS/FS IOT devices. +*/ +if ((gsnpsid & ~DWC2_CORE_REV_MASK ) !=DWC2_OTG_ID || + gsnpsid < DWC2_CORE_REV_5_00a) +return ; + +if ((hsotg->hw_params.hs_phy_type ==GHWCFG2_HS_PHY_TYPE_UTMI && + hsotg->hw_params.fs_phy_type ==GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED ) || + (hsotg->hw_params.hs_phy_type ==GHWCFG2_HS_PHY_TYPE_ULPI && + hsotg->hw_params.fs_phy_type ==GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED ) || + (hsotg->hw_params.hs_phy_type ==GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED && + hsotg->hw_params.fs_phy_type !=GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED )) { + val =GRSTCTL_CLOCK_SWITH_TIMER_VALUE_DIS ; + } + +if (hsotg->params.speed ==DWC2_SPEED_PARAM_LOW && + hsotg->hw_params.hs_phy_type !=GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED && + hsotg->hw_params.fs_phy_type !=GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED ) { + val =GRSTCTL_CLOCK_SWITH_TIMER_VALUE_147 ; + } + + grstctl =dwc2_readl (hsotg,GRSTCTL ); + grstctl &= ~GRSTCTL_CLOCK_SWITH_TIMER_MASK ; + grstctl |=GRSTCTL_CLOCK_SWITH_TIMER (val); +dwc2_writel (hsotg, grstctl,GRSTCTL ); +} +static int dwc2_fs_phy_init (struct dwc2_hsotg *hsotg,bool select_phy) {u32 usbcfg, ggpio, i2cctl;
@@ -997,6 +1032,8 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) usbcfg |=GUSBCFG_PHYSEL ;dwc2_writel (hsotg, usbcfg,GUSBCFG ); +dwc2_set_clock_switch_timer (hsotg); +/* Reset after a PHY select */ retval =dwc2_core_reset (hsotg, false);
drivers/usb/dwc2/hw.h +11 -0
@@ -99,6 +99,17 @@#define GRSTCTL_AHBIDLE BIT(31)#define GRSTCTL_DMAREQ BIT(30)#define GRSTCTL_CSFTRST_DONE BIT(29) +#define GRSTCTL_CLOCK_SWITH_TIMER_MASK (0x7 << 11) +#define GRSTCTL_CLOCK_SWITH_TIMER_SHIFT 11 +#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_19 0x0 +#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_15 0x1 +#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_147 0x2 +#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_50 0x3 +#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_100 0x4 +#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_125 0x5 +#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_200 0x6 +#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_DIS 0x7 +#define GRSTCTL_CLOCK_SWITH_TIMER (_x) ((_x) << 11)#define GRSTCTL_TXFNUM_MASK (0x1f << 6)#define GRSTCTL_TXFNUM_SHIFT 6#define GRSTCTL_TXFNUM_LIMIT 0x1f
Signature · 1 line
2.41.0