diff options
-rw-r--r-- | drivers/usb/dwc3/core.c | 27 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.h | 6 |
2 files changed, 33 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b592a48..3004501 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". diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 0d20fe2..b4a7d9e 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -249,6 +249,10 @@ #define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7) #define DWC3_GFLADJ_30MHZ_MASK 0x3f +/* Global User Control Register*/ +#define DWC3_GUCTL_REFCLKPER_MASK 0xffc00000 +#define DWC3_GUCTL_REFCLKPER_SEL 22 + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) @@ -671,6 +675,7 @@ struct dwc3_scratchpad_array { * @ref_clk: reference clock * @regs: base address for our registers * @regs_size: address space size + * @ref_clk_per: reference clock period configuration * @nr_scratch: number of scratch buffers * @num_event_buffers: calculated number of event buffers * @u1u2: only used on revisions <1.83a for workaround @@ -832,6 +837,7 @@ struct dwc3 { u8 lpm_nyet_threshold; u8 hird_threshold; u32 fladj; + u32 ref_clk_per; u8 incrx_mode; u32 incrx_size; |