Message ID | 0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2,1/6] dt-bindings: phy: qcom,qmp: Add IPQ6018 USB3 PHY | expand |
Hi, Baruch Siach <baruch@tkos.co.il> writes: > @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) > &dwc->hsphy_interface); > device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", > &dwc->fladj); > + device_property_read_u32(dev, "snps,ref-clock-period", > + &dwc->ref_clk_per); I wonder if it would make more sense to pass an actual clock reference here. If valid, then reconfigure the period to the value returned by clk_get_rate(). It would avoid yet another DT binding. If we make the clock optional, then we won't affect any other platforms. The clock itself could be a regular fixed clock node.
Hi Felipe, On Wed, Aug 04 2021, Felipe Balbi wrote: > Baruch Siach <baruch@tkos.co.il> writes: >> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) >> &dwc->hsphy_interface); >> device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", >> &dwc->fladj); >> + device_property_read_u32(dev, "snps,ref-clock-period", >> + &dwc->ref_clk_per); > > I wonder if it would make more sense to pass an actual clock reference > here. If valid, then reconfigure the period to the value returned by > clk_get_rate(). It would avoid yet another DT binding. If we make the > clock optional, then we won't affect any other platforms. The clock > itself could be a regular fixed clock node. Thinh Nguyen asked to add a dedicated DT property. He explained that clk_get_rate() does not work for PCI hosted dwc3. This is the most complete summary of the discussion: https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32@synopsys.com baruch
Hi, Baruch Siach <baruch@tkos.co.il> writes: > Hi Felipe, > > On Wed, Aug 04 2021, Felipe Balbi wrote: >> Baruch Siach <baruch@tkos.co.il> writes: >>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) >>> &dwc->hsphy_interface); >>> device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", >>> &dwc->fladj); >>> + device_property_read_u32(dev, "snps,ref-clock-period", >>> + &dwc->ref_clk_per); >> >> I wonder if it would make more sense to pass an actual clock reference >> here. If valid, then reconfigure the period to the value returned by >> clk_get_rate(). It would avoid yet another DT binding. If we make the >> clock optional, then we won't affect any other platforms. The clock >> itself could be a regular fixed clock node. > > Thinh Nguyen asked to add a dedicated DT property. He explained that > clk_get_rate() does not work for PCI hosted dwc3. This is the most > complete summary of the discussion: Hence the "optional" :-) Or, perhaps, Thinh wants to use this for internal FPGA-based validation? In that case, I'm okay with the property.
Felipe Balbi wrote: > > Hi, > > Baruch Siach <baruch@tkos.co.il> writes: >> Hi Felipe, >> >> On Wed, Aug 04 2021, Felipe Balbi wrote: >>> Baruch Siach <baruch@tkos.co.il> writes: >>>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) >>>> &dwc->hsphy_interface); >>>> device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", >>>> &dwc->fladj); >>>> + device_property_read_u32(dev, "snps,ref-clock-period", >>>> + &dwc->ref_clk_per); >>> >>> I wonder if it would make more sense to pass an actual clock reference >>> here. If valid, then reconfigure the period to the value returned by >>> clk_get_rate(). It would avoid yet another DT binding. If we make the >>> clock optional, then we won't affect any other platforms. The clock >>> itself could be a regular fixed clock node. >> >> Thinh Nguyen asked to add a dedicated DT property. He explained that >> clk_get_rate() does not work for PCI hosted dwc3. This is the most >> complete summary of the discussion: > > Hence the "optional" :-) > > Or, perhaps, Thinh wants to use this for internal FPGA-based validation? > > In that case, I'm okay with the property. > We do use it for internal FPGA validation, but it should help for other dwc3 PCI devices also. BR, Thinh
On Wed, Aug 04, 2021 at 05:22:27PM +0300, Baruch Siach wrote: > Hi Felipe, > > On Wed, Aug 04 2021, Felipe Balbi wrote: > > Baruch Siach <baruch@tkos.co.il> writes: > >> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) > >> &dwc->hsphy_interface); > >> device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", > >> &dwc->fladj); > >> + device_property_read_u32(dev, "snps,ref-clock-period", > >> + &dwc->ref_clk_per); > > > > I wonder if it would make more sense to pass an actual clock reference > > here. If valid, then reconfigure the period to the value returned by > > clk_get_rate(). It would avoid yet another DT binding. If we make the > > clock optional, then we won't affect any other platforms. The clock > > itself could be a regular fixed clock node. > > Thinh Nguyen asked to add a dedicated DT property. He explained that > clk_get_rate() does not work for PCI hosted dwc3. This is the most > complete summary of the discussion: > > https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32@synopsys.com PCI devices can have DT nodes with clock properties too. Or use the VID/PID to infer the frequency. Or use 'clock-frequency' property. It boils down to we have lots of standard properties for clocks and clock configuration, so custom properties are a NAK. Rob
Rob Herring wrote: > On Wed, Aug 04, 2021 at 05:22:27PM +0300, Baruch Siach wrote: >> Hi Felipe, >> >> On Wed, Aug 04 2021, Felipe Balbi wrote: >>> Baruch Siach <baruch@tkos.co.il> writes: >>>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) >>>> &dwc->hsphy_interface); >>>> device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", >>>> &dwc->fladj); >>>> + device_property_read_u32(dev, "snps,ref-clock-period", >>>> + &dwc->ref_clk_per); >>> >>> I wonder if it would make more sense to pass an actual clock reference >>> here. If valid, then reconfigure the period to the value returned by >>> clk_get_rate(). It would avoid yet another DT binding. If we make the >>> clock optional, then we won't affect any other platforms. The clock >>> itself could be a regular fixed clock node. >> >> Thinh Nguyen asked to add a dedicated DT property. He explained that >> clk_get_rate() does not work for PCI hosted dwc3. This is the most >> complete summary of the discussion: >> >> https://urldefense.com/v3/__https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32@synopsys.com__;!!A4F2R9G_pg!Nh6rqp_aOd8XIvqELvDRQe5ooZf13UZKwmn9lWcRgdbyMKpTMzL8HasrB1X2Ojvumo8g$ > > PCI devices can have DT nodes with clock properties too. Or use the > VID/PID to infer the frequency. Or use 'clock-frequency' property. > > It boils down to we have lots of standard properties for clocks and > clock configuration, so custom properties are a NAK. > Do we have DT node for the PCI device before discovering the device from PCI bus enumeration? I don't think we can find the clock properties from its configuration space. For our HAPS devices, we can't use VID/PID to infer the frequency since our phy and ref clock may change. Does "clock-frequency" mean ref clock? If so, let's use that? Thanks, Thinh
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ba74ad7f6995..7ec5bfb5fc11 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -26,6 +26,7 @@ #include <linux/acpi.h> #include <linux/pinctrl/consumer.h> #include <linux/reset.h> +#include <linux/bitfield.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -351,6 +352,29 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc) } } +/** + * 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 @@ -1011,6 +1035,9 @@ static int dwc3_core_init(struct dwc3 *dwc) /* Adjust Frame Length */ dwc3_frame_length_adjustment(dwc); + /* Adjust Reference Clock Period */ + dwc3_ref_clk_period(dwc); + dwc3_set_incr_burst_type(dwc); usb_phy_set_suspend(dwc->usb2_phy, 0); @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) &dwc->hsphy_interface); device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj); + device_property_read_u32(dev, "snps,ref-clock-period", + &dwc->ref_clk_per); dwc->dis_metastability_quirk = device_property_read_bool(dev, "snps,dis_metastability_quirk"); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5991766239ba..1e4e21ea9d97 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -386,6 +386,10 @@ #define DWC3_GFLADJ_30MHZ_SDBND_SEL BIT(7) #define DWC3_GFLADJ_30MHZ_MASK 0x3f +/* Global User Control Register*/ +#define DWC3_GUCTL_REFCLKPER_MASK 0xffc00000 +#define DWC3_GUCTL_REFCLKPER_SEL 22 + /* Global User Control Register 2 */ #define DWC3_GUCTL2_RST_ACTBITLATER BIT(14) @@ -969,6 +973,7 @@ struct dwc3_scratchpad_array { * @regs: base address for our registers * @regs_size: address space size * @fladj: frame length adjustment + * @ref_clk_per: reference clock period configuration * @irq_gadget: peripheral controller's IRQ number * @otg_irq: IRQ number for OTG IRQs * @current_otg_role: current role of operation while using the OTG block @@ -1141,6 +1146,7 @@ struct dwc3 { struct power_supply *usb_psy; u32 fladj; + u32 ref_clk_per; u32 irq_gadget; u32 otg_irq; u32 current_otg_role;