summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorSevak Arakelyan <sevaka@synopsys.com>2018-01-24 16:43:32 +0300
committerFelipe Balbi <felipe.balbi@linux.intel.com>2018-03-13 11:47:49 +0300
commit21b0340580f14d6e657439f7b7ce8cb98842dcaa (patch)
treeb58c1b2709d9c97a363e08c1a53270d94843ea66 /drivers/usb
parent376f04015944785d0634a288c9e1d1adb4439162 (diff)
downloadlinux-21b0340580f14d6e657439f7b7ce8cb98842dcaa.tar.xz
usb: dwc2: gadget: Configure the core to enable LPM
Configure core in device mode to support LPM according to programming guide. Device will start giving valid responses for LPM tokens. After this patch device side LPM will start working. Signed-off-by: Sevak Arakelyan <sevaka@synopsys.com> Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc2/core.h2
-rw-r--r--drivers/usb/dwc2/core_intr.c1
-rw-r--r--drivers/usb/dwc2/gadget.c26
3 files changed, 29 insertions, 0 deletions
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index bd6672b8c2ff..96799a399393 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1209,6 +1209,7 @@ int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg);
int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg);
int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
+void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg);
#else
static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
{ return 0; }
@@ -1236,6 +1237,7 @@ static inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
{ return 0; }
static inline int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg)
{ return 0; }
+static inline void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg) {}
#endif
#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 23599e798e24..a8e43948f807 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -372,6 +372,7 @@ static void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg)
dev_err(hsotg->dev, "Failed to exit L1 sleep state in 200us.\n");
return;
}
+ dwc2_gadget_init_lpm(hsotg);
} else {
/* TODO */
dev_err(hsotg->dev, "Host side LPM is not supported.\n");
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index ddfe6a94a12a..706fecf16b52 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -3372,6 +3372,9 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
val |= DCTL_SFTDISCON;
dwc2_set_bit(hsotg->regs + DCTL, val);
+ /* configure the core to support LPM */
+ dwc2_gadget_init_lpm(hsotg);
+
/* must be at-least 3ms to allow bus to see disconnect */
mdelay(3);
@@ -4862,3 +4865,26 @@ int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
return 0;
}
+
+/**
+ * dwc2_gadget_init_lpm - Configure the core to support LPM in device mode
+ *
+ * @hsotg: Programming view of DWC_otg controller
+ *
+ */
+void dwc2_gadget_init_lpm(struct dwc2_hsotg *hsotg)
+{
+ u32 val;
+
+ if (!hsotg->params.lpm)
+ return;
+
+ val = GLPMCFG_LPMCAP | GLPMCFG_APPL1RES;
+ val |= hsotg->params.hird_threshold_en ? GLPMCFG_HIRD_THRES_EN : 0;
+ val |= hsotg->params.lpm_clock_gating ? GLPMCFG_ENBLSLPM : 0;
+ val |= hsotg->params.hird_threshold << GLPMCFG_HIRD_THRES_SHIFT;
+ val |= hsotg->params.besl ? GLPMCFG_ENBESL : 0;
+ dwc2_writel(val, hsotg->regs + GLPMCFG);
+ dev_dbg(hsotg->dev, "GLPMCFG=0x%08x\n", dwc2_readl(hsotg->regs
+ + GLPMCFG));
+}