summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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));
+}