Lines Matching +full:am62 +full:- +full:usb
1 // SPDX-License-Identifier: GPL-2.0
3 * dwc3-am62.c - TI specific Glue layer for AM62 DWC3 USB Controller
5 * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com
22 /* USB WRAPPER register offsets */
104 /* USB PHY2 register offsets */
142 static inline u32 dwc3_ti_readl(struct dwc3_am62 *am62, u32 offset) in dwc3_ti_readl() argument
144 return readl((am62->usbss) + offset); in dwc3_ti_readl()
147 static inline void dwc3_ti_writel(struct dwc3_am62 *am62, u32 offset, u32 value) in dwc3_ti_writel() argument
149 writel(value, (am62->usbss) + offset); in dwc3_ti_writel()
152 static int phy_syscon_pll_refclk(struct dwc3_am62 *am62) in phy_syscon_pll_refclk() argument
154 struct device *dev = am62->dev; in phy_syscon_pll_refclk()
155 struct device_node *node = dev->of_node; in phy_syscon_pll_refclk()
160 syscon = syscon_regmap_lookup_by_phandle(node, "ti,syscon-phy-pll-refclk"); in phy_syscon_pll_refclk()
162 dev_err(dev, "unable to get ti,syscon-phy-pll-refclk regmap\n"); in phy_syscon_pll_refclk()
166 am62->syscon = syscon; in phy_syscon_pll_refclk()
168 ret = of_parse_phandle_with_fixed_args(node, "ti,syscon-phy-pll-refclk", 1, in phy_syscon_pll_refclk()
174 am62->offset = args.args[0]; in phy_syscon_pll_refclk()
177 ret = regmap_update_bits(am62->syscon, am62->offset, PHY_CORE_VOLTAGE_MASK, 0); in phy_syscon_pll_refclk()
183 ret = regmap_update_bits(am62->syscon, am62->offset, PHY_PLL_REFCLK_MASK, am62->rate_code); in phy_syscon_pll_refclk()
192 static int dwc3_ti_init(struct dwc3_am62 *am62) in dwc3_ti_init() argument
198 ret = phy_syscon_pll_refclk(am62); in dwc3_ti_init()
203 if (am62->phy_regs) { in dwc3_ti_init()
204 reg = readl(am62->phy_regs + USB_PHY_PLL_REG12); in dwc3_ti_init()
206 writel(reg, am62->phy_regs + USB_PHY_PLL_REG12); in dwc3_ti_init()
210 reg = dwc3_ti_readl(am62, USBSS_PHY_CONFIG); in dwc3_ti_init()
211 if (am62->vbus_divider) in dwc3_ti_init()
214 dwc3_ti_writel(am62, USBSS_PHY_CONFIG, reg); in dwc3_ti_init()
216 clk_prepare_enable(am62->usb2_refclk); in dwc3_ti_init()
219 reg = dwc3_ti_readl(am62, USBSS_MODE_CONTROL); in dwc3_ti_init()
221 dwc3_ti_writel(am62, USBSS_MODE_CONTROL, reg); in dwc3_ti_init()
228 struct device *dev = &pdev->dev; in dwc3_ti_probe()
229 struct device_node *node = pdev->dev.of_node; in dwc3_ti_probe()
230 struct dwc3_am62 *am62; in dwc3_ti_probe() local
234 am62 = devm_kzalloc(dev, sizeof(*am62), GFP_KERNEL); in dwc3_ti_probe()
235 if (!am62) in dwc3_ti_probe()
236 return -ENOMEM; in dwc3_ti_probe()
238 am62->dev = dev; in dwc3_ti_probe()
239 platform_set_drvdata(pdev, am62); in dwc3_ti_probe()
241 am62->usbss = devm_platform_ioremap_resource(pdev, 0); in dwc3_ti_probe()
242 if (IS_ERR(am62->usbss)) { in dwc3_ti_probe()
244 return PTR_ERR(am62->usbss); in dwc3_ti_probe()
247 am62->usb2_refclk = devm_clk_get(dev, "ref"); in dwc3_ti_probe()
248 if (IS_ERR(am62->usb2_refclk)) { in dwc3_ti_probe()
250 return PTR_ERR(am62->usb2_refclk); in dwc3_ti_probe()
254 rate = clk_get_rate(am62->usb2_refclk); in dwc3_ti_probe()
263 return -EINVAL; in dwc3_ti_probe()
266 am62->rate_code = i; in dwc3_ti_probe()
268 am62->phy_regs = devm_platform_ioremap_resource(pdev, 1); in dwc3_ti_probe()
269 if (IS_ERR(am62->phy_regs)) { in dwc3_ti_probe()
271 am62->phy_regs = NULL; in dwc3_ti_probe()
274 am62->vbus_divider = device_property_read_bool(dev, "ti,vbus-divider"); in dwc3_ti_probe()
276 ret = dwc3_ti_init(am62); in dwc3_ti_probe()
308 clk_disable_unprepare(am62->usb2_refclk); in dwc3_ti_probe()
316 struct device *dev = &pdev->dev; in dwc3_ti_remove()
317 struct dwc3_am62 *am62 = platform_get_drvdata(pdev); in dwc3_ti_remove() local
325 reg = dwc3_ti_readl(am62, USBSS_MODE_CONTROL); in dwc3_ti_remove()
327 dwc3_ti_writel(am62, USBSS_MODE_CONTROL, reg); in dwc3_ti_remove()
338 struct dwc3_am62 *am62 = dev_get_drvdata(dev); in dwc3_ti_suspend_common() local
342 reg = dwc3_ti_readl(am62, USBSS_CORE_STAT); in dwc3_ti_suspend_common()
346 reg = dwc3_ti_readl(am62, USBSS_WAKEUP_CONFIG); in dwc3_ti_suspend_common()
353 * and in U2/L3 state else it causes spurious wake-up. in dwc3_ti_suspend_common()
356 dwc3_ti_writel(am62, USBSS_WAKEUP_CONFIG, reg); in dwc3_ti_suspend_common()
358 dwc3_ti_writel(am62, USBSS_WAKEUP_STAT, USBSS_WAKEUP_STAT_CLR); in dwc3_ti_suspend_common()
362 dwc3_ti_writel(am62, USBSS_DEBUG_CFG, USBSS_DEBUG_CFG_DISABLED); in dwc3_ti_suspend_common()
364 clk_disable_unprepare(am62->usb2_refclk); in dwc3_ti_suspend_common()
371 struct dwc3_am62 *am62 = dev_get_drvdata(dev); in dwc3_ti_resume_common() local
374 reg = dwc3_ti_readl(am62, USBSS_DEBUG_CFG); in dwc3_ti_resume_common()
377 dwc3_ti_init(am62); in dwc3_ti_resume_common()
379 dwc3_ti_writel(am62, USBSS_DEBUG_CFG, USBSS_DEBUG_CFG_OFF); in dwc3_ti_resume_common()
380 clk_prepare_enable(am62->usb2_refclk); in dwc3_ti_resume_common()
385 dwc3_ti_writel(am62, USBSS_WAKEUP_CONFIG, USBSS_WAKEUP_CFG_NONE); in dwc3_ti_resume_common()
388 reg = dwc3_ti_readl(am62, USBSS_WAKEUP_STAT); in dwc3_ti_resume_common()
389 am62->wakeup_stat = reg; in dwc3_ti_resume_common()
403 { .compatible = "ti,am62-usb"},
412 .name = "dwc3-am62",
420 MODULE_ALIAS("platform:dwc3-am62");
421 MODULE_AUTHOR("Aswath Govindraju <a-[email protected]>");