summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/core.c
diff options
context:
space:
mode:
authorBalaji Prakash J <bjagadee@codeaurora.org>2022-11-27 15:31:53 +0100
committerMarek Vasut <marex@denx.de>2022-11-27 15:34:56 +0100
commit57548e8bc7cb6eb1c1a0206579c2a84737a70650 (patch)
treec973f7b72bd5edb756692edd022bb9298a90a31a /drivers/usb/dwc3/core.c
parent8ae84e64530e81f23066d86417b9225388ba96ae (diff)
usb: dwc3: reference clock period configuration
Set reference clock period when it differs from dwc3 default hardware set. We could calculate clock period based on reference clock frequency. But this information is not always available. This is the case of PCI bus attached USB host. For that reason we use a custom property. Tested (USB2 only) on IPQ6010 SoC based board with 24 MHz reference clock while hardware default is 19.2 MHz. [ baruch: rewrite commit message; drop GFLADJ code; remove 'quirk-' from property name; mention tested hardware ] [ marek: Ported from Linux kernel commit 7bee318838890 ("usb: dwc3: reference clock period configuration") ] Reviewed-by: Sean Anderson <seanga2@gmail.com> Signed-off-by: Balaji Prakash J <bjagadee@codeaurora.org> Signed-off-by: Baruch Siach <baruch@tkos.co.il> Signed-off-by: Marek Vasut <marex@denx.de> # Port from Linux
Diffstat (limited to 'drivers/usb/dwc3/core.c')
-rw-r--r--drivers/usb/dwc3/core.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index b592a487e00..300450100c9 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -28,6 +28,7 @@
#include <generic-phy.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
+#include <linux/bitfield.h>
#include "core.h"
#include "gadget.h"
@@ -115,6 +116,28 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
}
/**
+ * dwc3_ref_clk_period - Reference clock period configuration
+ * Default reference clock period depends on hardware
+ * configuration. For systems with reference clock that differs
+ * from the default, this will set clock period in DWC3_GUCTL
+ * register.
+ * @dwc: Pointer to our controller context structure
+ * @ref_clk_per: reference clock period in ns
+ */
+static void dwc3_ref_clk_period(struct dwc3 *dwc)
+{
+ u32 reg;
+
+ if (dwc->ref_clk_per == 0)
+ return;
+
+ reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+ reg &= ~DWC3_GUCTL_REFCLKPER_MASK;
+ reg |= FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, dwc->ref_clk_per);
+ dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+}
+
+/**
* dwc3_free_one_event_buffer - Frees one event buffer
* @dwc: Pointer to our controller context structure
* @evt: Pointer to event buffer to be freed
@@ -640,6 +663,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
/* Adjust Frame Length */
dwc3_frame_length_adjustment(dwc, dwc->fladj);
+ /* Adjust Reference Clock Period */
+ dwc3_ref_clk_period(dwc);
+
dwc3_set_incr_burst_type(dwc);
return 0;
@@ -1043,6 +1069,7 @@ void dwc3_of_parse(struct dwc3 *dwc)
| (dwc->is_utmi_l1_suspend << 4);
dev_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj);
+ dev_read_u32(dev, "snps,ref-clock-period-ns", &dwc->ref_clk_per);
/*
* Handle property "snps,incr-burst-type-adjustment".