From b43ebc96e985fed9417c6aff769a6839bdaa6cdf Mon Sep 17 00:00:00 2001 From: Grigor Tovmasyan Date: Sat, 5 May 2018 12:17:58 +0400 Subject: [PATCH] usb: dwc2: Add Interpacket Gap(IPG) feature support Added GHWCFG4_IPG_ISOC_SUPPORTED and DCFG_IPG_ISOC_SUPPORDED bits definitions to enable/disable IPG feature. Added ipg_isoc_en core parameter which will indicate IPG support enable/disable and initialize it. Signed-off-by: Grigor Tovmasyan Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 11 +++++++++++ drivers/usb/dwc2/debugfs.c | 1 + drivers/usb/dwc2/gadget.c | 3 +++ drivers/usb/dwc2/hw.h | 2 ++ drivers/usb/dwc2/params.c | 3 +++ 5 files changed, 20 insertions(+) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 274bf0a..e75a417 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -380,6 +380,9 @@ enum dwc2_ep0_state { * is FS. * 0 - No (default) * 1 - Yes + * @ipg_isoc_en Indicates the IPG supports is enabled or disabled. + * 0 - Disable (default) + * 1 - Enable * @ulpi_fs_ls: Make ULPI phy operate in FS/LS mode only * 0 - No (default) * 1 - Yes @@ -511,6 +514,7 @@ struct dwc2_core_params { bool hird_threshold_en; u8 hird_threshold; bool activate_stm_fs_transceiver; + bool ipg_isoc_en; u16 max_packet_count; u32 max_transfer_size; u32 ahbcfg; @@ -560,6 +564,12 @@ struct dwc2_core_params { * 0 - Slave only * 1 - External DMA * 2 - Internal DMA + * @ipg_isoc_en This feature indicates that the controller supports + * the worst-case scenario of Rx followed by Rx + * Interpacket Gap (IPG) (32 bitTimes) as per the utmi + * specification for any token following ISOC OUT token. + * 0 - Don't support + * 1 - Support * @power_optimized Are power optimizations enabled? * @num_dev_ep Number of device endpoints available * @num_dev_in_eps Number of device IN endpoints available @@ -622,6 +632,7 @@ struct dwc2_hw_params { unsigned hibernation:1; unsigned utmi_phy_data_width:2; unsigned lpm_mode:1; + unsigned ipg_isoc_en:1; u32 snpsid; u32 dev_ep_dirs; u32 g_tx_fifo_size[MAX_EPS_CHANNELS]; diff --git a/drivers/usb/dwc2/debugfs.c b/drivers/usb/dwc2/debugfs.c index 58c691f..5897333 100644 --- a/drivers/usb/dwc2/debugfs.c +++ b/drivers/usb/dwc2/debugfs.c @@ -710,6 +710,7 @@ static int params_show(struct seq_file *seq, void *v) print_param(seq, p, phy_ulpi_ddr); print_param(seq, p, phy_ulpi_ext_vbus); print_param(seq, p, i2c_enable); + print_param(seq, p, ipg_isoc_en); print_param(seq, p, ulpi_fs_ls); print_param(seq, p, host_support_fs_ls_low_power); print_param(seq, p, host_ls_low_power_phy_clk); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 403e990..abd22b4 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3236,6 +3236,9 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, dcfg |= DCFG_DEVSPD_HS; } + if (hsotg->params.ipg_isoc_en) + dcfg |= DCFG_IPG_ISOC_SUPPORDED; + dwc2_writel(dcfg, hsotg->regs + DCFG); /* Clear any pending OTG interrupts */ diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h index 38391e4..0ca8e7b 100644 --- a/drivers/usb/dwc2/hw.h +++ b/drivers/usb/dwc2/hw.h @@ -311,6 +311,7 @@ #define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14) #define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14 #define GHWCFG4_ACG_SUPPORTED BIT(12) +#define GHWCFG4_IPG_ISOC_SUPPORTED BIT(11) #define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 0 #define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 1 #define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 2 @@ -424,6 +425,7 @@ #define DCFG_EPMISCNT_SHIFT 18 #define DCFG_EPMISCNT_LIMIT 0x1f #define DCFG_EPMISCNT(_x) ((_x) << 18) +#define DCFG_IPG_ISOC_SUPPORDED BIT(17) #define DCFG_PERFRINT_MASK (0x3 << 11) #define DCFG_PERFRINT_SHIFT 11 #define DCFG_PERFRINT_LIMIT 0x3 diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index f03e418..2700f52 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -298,6 +298,7 @@ static void dwc2_set_default_params(struct dwc2_hsotg *hsotg) p->besl = true; p->hird_threshold_en = true; p->hird_threshold = 4; + p->ipg_isoc_en = false; p->max_packet_count = hw->max_packet_count; p->max_transfer_size = hw->max_transfer_size; p->ahbcfg = GAHBCFG_HBSTLEN_INCR << GAHBCFG_HBSTLEN_SHIFT; @@ -579,6 +580,7 @@ static void dwc2_check_params(struct dwc2_hsotg *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); + CHECK_BOOL(ipg_isoc_en, hw->ipg_isoc_en); CHECK_BOOL(acg_enable, hw->acg_enable); CHECK_BOOL(reload_ctl, (hsotg->hw_params.snpsid > DWC2_CORE_REV_2_92a)); CHECK_BOOL(lpm, (hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_80a)); @@ -772,6 +774,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >> GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT; hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED); + hw->ipg_isoc_en = !!(hwcfg4 & GHWCFG4_IPG_ISOC_SUPPORTED); /* fifo sizes */ hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >> -- 2.7.4