1 // SPDX-License-Identifier: GPL-2.0
3 * cdns-starfive.c - Cadence USB Controller
5 * Copyright (C) 2022 Starfive, Inc.
6 * Author: yanhong <yanhong.wang@starfivetech.com>
9 #include <linux/bits.h>
10 #include <linux/clk.h>
11 #include <linux/module.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/kernel.h>
14 #include <linux/platform_device.h>
16 #include <linux/of_platform.h>
17 #include <linux/regmap.h>
18 #include <linux/reset.h>
19 #include <linux/usb/otg.h>
21 #define USB_STRAP_HOST (2 << 0x10)
22 #define USB_STRAP_DEVICE (4 << 0X10)
23 #define USB_STRAP_MASK 0x70000
25 #define USB_SUSPENDM_HOST (1 << 0x13)
26 #define USB_SUSPENDM_DEVICE (0 << 0x13)
27 #define USB_SUSPENDM_MASK 0x80000
29 #define USB_SUSPENDM_BYPS_SHIFT 0x14
30 #define USB_SUSPENDM_BYPS_MASK 0x100000
31 #define USB_REFCLK_MODE_SHIFT 0x17
32 #define USB_REFCLK_MODE_MASK 0x800000
33 #define USB_PLL_EN_SHIFT 0x16
34 #define USB_PLL_EN_MASK 0x400000
35 #define USB_PDRSTN_SPLIT_SHIFT 0x11
36 #define USB_PDRSTN_SPLIT_MASK 0x20000
38 #define PCIE_CKREF_SRC_SHIFT 0x12
39 #define PCIE_CKREF_SRC_MASK 0xC0000
40 #define PCIE_CLK_SEL_SHIFT 0x14
41 #define PCIE_CLK_SEL_MASK 0x300000
42 #define PCIE_PHY_MODE_SHIFT 0x14
43 #define PCIE_PHY_MODE_MASK 0x300000
44 #define PCIE_USB3_BUS_WIDTH_SHIFT 0x2
45 #define PCIE_USB3_BUS_WIDTH_MASK 0xC
46 #define PCIE_USB3_RATE_SHIFT 0x5
47 #define PCIE_USB3_RATE_MASK 0x60
48 #define PCIE_USB3_RX_STANDBY_SHIFT 0x7
49 #define PCIE_USB3_RX_STANDBY_MASK 0x80
50 #define PCIE_USB3_PHY_ENABLE_SHIFT 0x4
51 #define PCIE_USB3_PHY_ENABLE_MASK 0x10
52 #define PCIE_USB3_PHY_PLL_CTL_OFF (0x1f * 4)
55 #define USB_125M_CLK_RATE 125000000
57 #define USB3_PHY_RES_INDEX 0
58 #define USB2_PHY_RES_INDEX 1
59 #define USB_LS_KEEPALIVE_OFF 0x4
60 #define USB_LS_KEEPALIVE_ENABLE 4
62 struct cdns_starfive {
64 struct regmap *stg_syscon;
65 struct regmap *sys_syscon;
66 struct reset_control *resets;
67 struct clk_bulk_data *clks;
69 struct clk *usb_125m_clk;
76 enum usb_dr_mode mode;
79 static int cdns_mode_init(struct platform_device *pdev,
80 struct cdns_starfive *data)
82 enum usb_dr_mode mode;
84 /* Init usb 2.0 utmi phy */
85 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
86 USB_SUSPENDM_BYPS_MASK, BIT(USB_SUSPENDM_BYPS_SHIFT));
87 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
88 USB_PLL_EN_MASK, BIT(USB_PLL_EN_SHIFT));
89 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
90 USB_REFCLK_MODE_MASK, BIT(USB_REFCLK_MODE_SHIFT));
92 if (data->usb2_only) {
93 /* Disconnect usb 3.0 phy mode */
94 regmap_update_bits(data->sys_syscon, data->sys_offset,
95 USB_PDRSTN_SPLIT_MASK, BIT(USB_PDRSTN_SPLIT_SHIFT));
97 /* Config usb 3.0 pipe phy */
98 regmap_update_bits(data->stg_syscon, data->stg_offset_196,
99 PCIE_CKREF_SRC_MASK, (0<<PCIE_CKREF_SRC_SHIFT));
100 regmap_update_bits(data->stg_syscon, data->stg_offset_196,
101 PCIE_CLK_SEL_MASK, (0<<PCIE_CLK_SEL_SHIFT));
102 regmap_update_bits(data->stg_syscon, data->stg_offset_328,
103 PCIE_PHY_MODE_MASK, BIT(PCIE_PHY_MODE_SHIFT));
104 regmap_update_bits(data->stg_syscon, data->stg_offset_500,
105 PCIE_USB3_BUS_WIDTH_MASK, (0 << PCIE_USB3_BUS_WIDTH_SHIFT));
106 regmap_update_bits(data->stg_syscon, data->stg_offset_500,
107 PCIE_USB3_RATE_MASK, (0 << PCIE_USB3_RATE_SHIFT));
108 regmap_update_bits(data->stg_syscon, data->stg_offset_500,
109 PCIE_USB3_RX_STANDBY_MASK, (0 << PCIE_USB3_RX_STANDBY_SHIFT));
110 regmap_update_bits(data->stg_syscon, data->stg_offset_500,
111 PCIE_USB3_PHY_ENABLE_MASK, BIT(PCIE_USB3_PHY_ENABLE_SHIFT));
113 /* Connect usb 3.0 phy mode */
114 regmap_update_bits(data->sys_syscon, data->sys_offset,
115 USB_PDRSTN_SPLIT_MASK, (0 << USB_PDRSTN_SPLIT_SHIFT));
117 mode = usb_get_dr_mode(&pdev->dev);
121 case USB_DR_MODE_HOST:
122 regmap_update_bits(data->stg_syscon,
126 regmap_update_bits(data->stg_syscon,
132 case USB_DR_MODE_PERIPHERAL:
133 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
134 USB_STRAP_MASK, USB_STRAP_DEVICE);
135 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
136 USB_SUSPENDM_MASK, USB_SUSPENDM_DEVICE);
139 case USB_DR_MODE_UNKNOWN:
140 case USB_DR_MODE_OTG:
149 static int cdns_clk_rst_init(struct cdns_starfive *data)
153 data->usb_125m_clk = devm_clk_get(data->dev, "125m");
154 if (IS_ERR(data->usb_125m_clk)) {
155 dev_err(data->dev, "Failed to get usb 125m clock\n");
156 ret = PTR_ERR(data->usb_125m_clk);
160 data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks);
161 if (data->num_clks < 0) {
162 dev_err(data->dev, "Failed to get usb clocks\n");
167 /* Needs to set the USB_125M clock explicitly,
168 * since it's divided from pll0 clock, and the pll0 clock
169 * changes per the cpu frequency.
171 ret = clk_set_rate(data->usb_125m_clk, USB_125M_CLK_RATE);
173 dev_err(data->dev, "Failed to set usb 125m clock\n");
176 ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
178 dev_err(data->dev, "Failed to enable clocks\n");
182 data->resets = devm_reset_control_array_get_exclusive(data->dev);
183 if (IS_ERR(data->resets)) {
184 ret = PTR_ERR(data->resets);
185 dev_err(data->dev, "Failed to get usb resets");
188 ret = reset_control_deassert(data->resets);
192 clk_bulk_disable_unprepare(data->num_clks, data->clks);
197 static int cdns_starfive_phy_init(struct platform_device *pdev,
198 struct cdns_starfive *data)
200 struct device *dev = &pdev->dev;
201 void __iomem *phybase_20, *phybase_30;
205 phybase_20 = devm_platform_ioremap_resource(pdev, USB2_PHY_RES_INDEX);
206 if (IS_ERR(phybase_20)) {
207 dev_err(dev, "Can't map phybase_20 IOMEM resource\n");
208 ret = PTR_ERR(phybase_20);
212 phybase_30 = devm_platform_ioremap_resource(pdev, USB3_PHY_RES_INDEX);
213 if (IS_ERR(phybase_30)) {
214 dev_err(dev, "Can't map phybase_30 IOMEM resource\n");
215 ret = PTR_ERR(phybase_30);
219 if (data->mode != USB_DR_MODE_PERIPHERAL) {
220 /* Enable the LS speed keep-alive signal */
221 val = readl(phybase_20 + USB_LS_KEEPALIVE_OFF);
222 val |= BIT(USB_LS_KEEPALIVE_ENABLE);
223 writel(val, phybase_20 + USB_LS_KEEPALIVE_OFF);
226 if (!data->usb2_only) {
227 /* Configuare spread-spectrum mode: down-spread-spectrum */
228 writel(BIT(4), (phybase_30 + PCIE_USB3_PHY_PLL_CTL_OFF));
235 static int cdns_starfive_probe(struct platform_device *pdev)
237 struct device *dev = &pdev->dev;
238 struct device_node *node = pdev->dev.of_node;
239 struct cdns_starfive *data;
240 struct of_phandle_args args;
243 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
247 platform_set_drvdata(pdev, data);
251 data->usb2_only = device_property_read_bool(dev, "starfive,usb2-only");
252 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
253 "starfive,stg-syscon", 4, 0, &args);
255 dev_err(dev, "Failed to parse starfive,stg-syscon\n");
259 data->stg_syscon = syscon_node_to_regmap(args.np);
260 of_node_put(args.np);
261 if (IS_ERR(data->stg_syscon))
262 return PTR_ERR(data->stg_syscon);
263 data->stg_offset_4 = args.args[0];
264 data->stg_offset_196 = args.args[1];
265 data->stg_offset_328 = args.args[2];
266 data->stg_offset_500 = args.args[3];
268 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
269 "starfive,sys-syscon", 1, 0, &args);
271 dev_err(dev, "Failed to parse starfive,sys-syscon\n");
275 data->sys_syscon = syscon_node_to_regmap(args.np);
276 of_node_put(args.np);
277 if (IS_ERR(data->sys_syscon))
278 return PTR_ERR(data->sys_syscon);
279 data->sys_offset = args.args[0];
281 cdns_mode_init(pdev, data);
283 ret = cdns_clk_rst_init(data);
285 dev_err(&pdev->dev, "Failed to init usb clk reset: %d\n", ret);
289 ret = cdns_starfive_phy_init(pdev, data);
291 dev_err(dev, "Failed to init sratfive usb phy: %d\n", ret);
295 ret = of_platform_populate(node, NULL, NULL, dev);
297 dev_err(dev, "Failed to create children: %d\n", ret);
301 device_set_wakeup_capable(dev, true);
302 pm_runtime_set_active(dev);
303 pm_runtime_enable(dev);
305 dev_info(dev, "usb mode %d %s probe success\n",
306 data->mode, data->usb2_only ? "2.0" : "3.0");
313 static int cdns_starfive_remove_core(struct device *dev, void *c)
315 struct platform_device *pdev = to_platform_device(dev);
317 platform_device_unregister(pdev);
322 static int cdns_starfive_remove(struct platform_device *pdev)
324 struct device *dev = &pdev->dev;
325 struct cdns_starfive *data = dev_get_drvdata(dev);
327 pm_runtime_get_sync(dev);
328 device_for_each_child(dev, NULL, cdns_starfive_remove_core);
330 reset_control_assert(data->resets);
331 clk_bulk_disable_unprepare(data->num_clks, data->clks);
332 pm_runtime_disable(dev);
333 pm_runtime_put_noidle(dev);
334 platform_set_drvdata(pdev, NULL);
340 static int cdns_starfive_resume(struct device *dev)
342 struct cdns_starfive *data = dev_get_drvdata(dev);
345 ret = clk_set_rate(data->usb_125m_clk, USB_125M_CLK_RATE);
349 ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
353 ret = reset_control_deassert(data->resets);
358 static int cdns_starfive_suspend(struct device *dev)
360 struct cdns_starfive *data = dev_get_drvdata(dev);
362 clk_bulk_disable_unprepare(data->num_clks, data->clks);
363 reset_control_assert(data->resets);
369 static const struct dev_pm_ops cdns_starfive_pm_ops = {
370 SET_RUNTIME_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume, NULL)
371 SET_SYSTEM_SLEEP_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume)
374 static const struct of_device_id cdns_starfive_of_match[] = {
375 { .compatible = "starfive,jh7110-cdns3", },
378 MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);
380 static struct platform_driver cdns_starfive_driver = {
381 .probe = cdns_starfive_probe,
382 .remove = cdns_starfive_remove,
384 .name = "cdns3-starfive",
385 .of_match_table = cdns_starfive_of_match,
386 .pm = &cdns_starfive_pm_ops,
390 module_platform_driver(cdns_starfive_driver);
392 MODULE_ALIAS("platform:cdns3-starfive");
393 MODULE_AUTHOR("YanHong Wang <yanhong.wang@starfivetech.com>");
394 MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
395 MODULE_LICENSE("GPL v2");
396 MODULE_DESCRIPTION("Cadence USB3 StarFive SoC platform");