--- zzzz-none-000/linux-5.4.213/drivers/usb/dwc3/core.c 2022-09-15 10:04:56.000000000 +0000 +++ miami-7690-761/linux-5.4.213/drivers/usb/dwc3/core.c 2024-05-29 11:20:02.000000000 +0000 @@ -295,12 +295,6 @@ return 0; } -static const struct clk_bulk_data dwc3_core_clks[] = { - { .id = "ref" }, - { .id = "bus_early" }, - { .id = "suspend" }, -}; - /* * dwc3_frame_length_adjustment - Adjusts frame length if required * @dwc3: Pointer to our controller context structure @@ -326,6 +320,64 @@ } /** + * dwc3_30m_sb_sel_adjustment - 30MHZ side band sel adjustment + * + * @dwc: Pointer to our controller context structure + * @ref_clk_per: 30MHz side band sel value + */ +static void dwc3_30m_sb_sel_adjustment(struct dwc3 *dwc, int sb_30m_sel) +{ + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + reg &= ~DWC3_GFLADJ_30MHZ_SDBND_SEL_MASK; + reg |= (sb_30m_sel << 7); + dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); +} + +/** + * dwc3_ref_clk_adjustment - Reference clock settings for SOF and ITP + * Default reference clock configurations are calculated assuming + * 19.2 MHz clock source. For other clock source, this will set + * configuration in DWC3_GFLADJ register + * @dwc: Pointer to our controller context structure + */ +static void dwc3_ref_clk_adjustment(struct dwc3 *dwc) +{ + u32 reg; + + if (dwc->ref_clk_adj == 0) + return; + + reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + reg &= ~DWC3_GFLADJ_REFCLK_MASK; + reg |= (dwc->ref_clk_adj << DWC3_GFLADJ_REFCLK_SEL); + dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); +} + +/** + * dwc3_ref_clk_period - Reference clock period configuration + * Default reference clock period is calculated assuming + * 19.2 MHz as clock source. For other clock source, 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 |= (dwc->ref_clk_per << DWC3_GUCTL_REFCLKPER_SEL); + 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 @@ -957,6 +1009,21 @@ /* Adjust Frame Length */ dwc3_frame_length_adjustment(dwc); + /* Adjust Reference Clock Settings */ + dwc3_ref_clk_adjustment(dwc); + + /* Adjust Reference Clock Period */ + dwc3_ref_clk_period(dwc); + + /* adjust 30m side band sel */ + if (device_property_present(dwc->dev, "snps,quirk-30m-sb-sel")) { + u32 sb_30m_sel; + + device_property_read_u32(dwc->dev, "snps,quirk-30m-sb-sel", + &sb_30m_sel); + dwc3_30m_sb_sel_adjustment(dwc, sb_30m_sel); + } + dwc3_set_incr_burst_type(dwc); usb_phy_set_suspend(dwc->usb2_phy, 0); @@ -986,6 +1053,12 @@ dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); } + if (dwc->dis_ep_cache_eviction_quirk) { + reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); + reg |= DWC3_GUCTL2_ENABLEEPCACHEEVICT; + dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); + } + if (dwc->revision >= DWC3_REVISION_250A) { reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); @@ -1326,6 +1399,12 @@ &dwc->hsphy_interface); device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj); + device_property_read_u32(dev, "snps,quirk-ref-clock-adjustment", + &dwc->ref_clk_adj); + device_property_read_u32(dev, "snps,quirk-ref-clock-period", + &dwc->ref_clk_per); + dwc->dis_ep_cache_eviction_quirk = device_property_read_bool(dev, + "snps,dis_ep_cache_eviction"); dwc->dis_metastability_quirk = device_property_read_bool(dev, "snps,dis_metastability_quirk"); @@ -1419,11 +1498,6 @@ if (!dwc) return -ENOMEM; - dwc->clks = devm_kmemdup(dev, dwc3_core_clks, sizeof(dwc3_core_clks), - GFP_KERNEL); - if (!dwc->clks) - return -ENOMEM; - dwc->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1459,17 +1533,18 @@ return PTR_ERR(dwc->reset); if (dev->of_node) { - dwc->num_clks = ARRAY_SIZE(dwc3_core_clks); - - ret = devm_clk_bulk_get(dev, dwc->num_clks, dwc->clks); + ret = devm_clk_bulk_get_all(dev, &dwc->clks); if (ret == -EPROBE_DEFER) return ret; /* * Clocks are optional, but new DT platforms should support all * clocks as required by the DT-binding. */ - if (ret) + if (ret < 0) dwc->num_clks = 0; + else + dwc->num_clks = ret; + } ret = reset_control_deassert(dwc->reset);