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;
77 void __iomem *phybase_20;
78 void __iomem *phybase_30;
81 static int cdns_mode_init(struct platform_device *pdev,
82 struct cdns_starfive *data)
84 enum usb_dr_mode mode;
86 /* Init usb 2.0 utmi phy */
87 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
88 USB_SUSPENDM_BYPS_MASK, BIT(USB_SUSPENDM_BYPS_SHIFT));
89 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
90 USB_PLL_EN_MASK, BIT(USB_PLL_EN_SHIFT));
91 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
92 USB_REFCLK_MODE_MASK, BIT(USB_REFCLK_MODE_SHIFT));
94 if (data->usb2_only) {
95 /* Disconnect usb 3.0 phy mode */
96 regmap_update_bits(data->sys_syscon, data->sys_offset,
97 USB_PDRSTN_SPLIT_MASK, BIT(USB_PDRSTN_SPLIT_SHIFT));
99 /* Config usb 3.0 pipe phy */
100 regmap_update_bits(data->stg_syscon, data->stg_offset_196,
101 PCIE_CKREF_SRC_MASK, (0<<PCIE_CKREF_SRC_SHIFT));
102 regmap_update_bits(data->stg_syscon, data->stg_offset_196,
103 PCIE_CLK_SEL_MASK, (0<<PCIE_CLK_SEL_SHIFT));
104 regmap_update_bits(data->stg_syscon, data->stg_offset_328,
105 PCIE_PHY_MODE_MASK, BIT(PCIE_PHY_MODE_SHIFT));
106 regmap_update_bits(data->stg_syscon, data->stg_offset_500,
107 PCIE_USB3_BUS_WIDTH_MASK, (0 << PCIE_USB3_BUS_WIDTH_SHIFT));
108 regmap_update_bits(data->stg_syscon, data->stg_offset_500,
109 PCIE_USB3_RATE_MASK, (0 << PCIE_USB3_RATE_SHIFT));
110 regmap_update_bits(data->stg_syscon, data->stg_offset_500,
111 PCIE_USB3_RX_STANDBY_MASK, (0 << PCIE_USB3_RX_STANDBY_SHIFT));
112 regmap_update_bits(data->stg_syscon, data->stg_offset_500,
113 PCIE_USB3_PHY_ENABLE_MASK, BIT(PCIE_USB3_PHY_ENABLE_SHIFT));
115 /* Connect usb 3.0 phy mode */
116 regmap_update_bits(data->sys_syscon, data->sys_offset,
117 USB_PDRSTN_SPLIT_MASK, (0 << USB_PDRSTN_SPLIT_SHIFT));
119 mode = usb_get_dr_mode(&pdev->dev);
123 case USB_DR_MODE_HOST:
124 regmap_update_bits(data->stg_syscon,
128 regmap_update_bits(data->stg_syscon,
134 case USB_DR_MODE_PERIPHERAL:
135 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
136 USB_STRAP_MASK, USB_STRAP_DEVICE);
137 regmap_update_bits(data->stg_syscon, data->stg_offset_4,
138 USB_SUSPENDM_MASK, USB_SUSPENDM_DEVICE);
141 case USB_DR_MODE_UNKNOWN:
142 case USB_DR_MODE_OTG:
151 static int cdns_clk_rst_init(struct cdns_starfive *data)
155 data->usb_125m_clk = devm_clk_get(data->dev, "125m");
156 if (IS_ERR(data->usb_125m_clk)) {
157 dev_err(data->dev, "Failed to get usb 125m clock\n");
158 ret = PTR_ERR(data->usb_125m_clk);
162 data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks);
163 if (data->num_clks < 0) {
164 dev_err(data->dev, "Failed to get usb clocks\n");
169 /* Needs to set the USB_125M clock explicitly,
170 * since it's divided from pll0 clock, and the pll0 clock
171 * changes per the cpu frequency.
173 ret = clk_set_rate(data->usb_125m_clk, USB_125M_CLK_RATE);
175 dev_err(data->dev, "Failed to set usb 125m clock\n");
178 ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
180 dev_err(data->dev, "Failed to enable clocks\n");
184 data->resets = devm_reset_control_array_get_exclusive(data->dev);
185 if (IS_ERR(data->resets)) {
186 ret = PTR_ERR(data->resets);
187 dev_err(data->dev, "Failed to get usb resets");
190 ret = reset_control_deassert(data->resets);
194 clk_bulk_disable_unprepare(data->num_clks, data->clks);
199 static void cdns_starfive_set_phy(struct cdns_starfive *data)
203 if (data->mode != USB_DR_MODE_PERIPHERAL) {
204 /* Enable the LS speed keep-alive signal */
205 val = readl(data->phybase_20 + USB_LS_KEEPALIVE_OFF);
206 val |= BIT(USB_LS_KEEPALIVE_ENABLE);
207 writel(val, data->phybase_20 + USB_LS_KEEPALIVE_OFF);
210 if (!data->usb2_only) {
211 /* Configuare spread-spectrum mode: down-spread-spectrum */
212 writel(BIT(4), data->phybase_30 + PCIE_USB3_PHY_PLL_CTL_OFF);
216 static int cdns_starfive_phy_init(struct platform_device *pdev,
217 struct cdns_starfive *data)
219 struct device *dev = &pdev->dev;
222 data->phybase_20 = devm_platform_ioremap_resource(pdev, USB2_PHY_RES_INDEX);
223 if (IS_ERR(data->phybase_20)) {
224 dev_err(dev, "Can't map phybase_20 IOMEM resource\n");
225 ret = PTR_ERR(data->phybase_20);
229 data->phybase_30 = devm_platform_ioremap_resource(pdev, USB3_PHY_RES_INDEX);
230 if (IS_ERR(data->phybase_30)) {
231 dev_err(dev, "Can't map phybase_30 IOMEM resource\n");
232 ret = PTR_ERR(data->phybase_30);
236 cdns_starfive_set_phy(data);
242 static int cdns_starfive_probe(struct platform_device *pdev)
244 struct device *dev = &pdev->dev;
245 struct device_node *node = pdev->dev.of_node;
246 struct cdns_starfive *data;
247 struct of_phandle_args args;
250 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
254 platform_set_drvdata(pdev, data);
258 data->usb2_only = device_property_read_bool(dev, "starfive,usb2-only");
259 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
260 "starfive,stg-syscon", 4, 0, &args);
262 dev_err(dev, "Failed to parse starfive,stg-syscon\n");
266 data->stg_syscon = syscon_node_to_regmap(args.np);
267 of_node_put(args.np);
268 if (IS_ERR(data->stg_syscon))
269 return PTR_ERR(data->stg_syscon);
270 data->stg_offset_4 = args.args[0];
271 data->stg_offset_196 = args.args[1];
272 data->stg_offset_328 = args.args[2];
273 data->stg_offset_500 = args.args[3];
275 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
276 "starfive,sys-syscon", 1, 0, &args);
278 dev_err(dev, "Failed to parse starfive,sys-syscon\n");
282 data->sys_syscon = syscon_node_to_regmap(args.np);
283 of_node_put(args.np);
284 if (IS_ERR(data->sys_syscon))
285 return PTR_ERR(data->sys_syscon);
286 data->sys_offset = args.args[0];
288 cdns_mode_init(pdev, data);
290 ret = cdns_clk_rst_init(data);
292 dev_err(&pdev->dev, "Failed to init usb clk reset: %d\n", ret);
296 ret = cdns_starfive_phy_init(pdev, data);
298 dev_err(dev, "Failed to init sratfive usb phy: %d\n", ret);
302 ret = of_platform_populate(node, NULL, NULL, dev);
304 dev_err(dev, "Failed to create children: %d\n", ret);
308 device_set_wakeup_capable(dev, true);
309 pm_runtime_set_active(dev);
310 pm_runtime_enable(dev);
312 dev_info(dev, "usb mode %d %s probe success\n",
313 data->mode, data->usb2_only ? "2.0" : "3.0");
320 static int cdns_starfive_remove_core(struct device *dev, void *c)
322 struct platform_device *pdev = to_platform_device(dev);
324 platform_device_unregister(pdev);
329 static int cdns_starfive_remove(struct platform_device *pdev)
331 struct device *dev = &pdev->dev;
332 struct cdns_starfive *data = dev_get_drvdata(dev);
334 pm_runtime_get_sync(dev);
335 device_for_each_child(dev, NULL, cdns_starfive_remove_core);
337 reset_control_assert(data->resets);
338 clk_bulk_disable_unprepare(data->num_clks, data->clks);
339 pm_runtime_disable(dev);
340 pm_runtime_put_noidle(dev);
341 platform_set_drvdata(pdev, NULL);
347 static int cdns_starfive_resume(struct device *dev)
349 struct cdns_starfive *data = dev_get_drvdata(dev);
352 ret = clk_set_rate(data->usb_125m_clk, USB_125M_CLK_RATE);
356 ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
360 ret = reset_control_deassert(data->resets);
364 cdns_starfive_set_phy(data);
369 static int cdns_starfive_suspend(struct device *dev)
371 struct cdns_starfive *data = dev_get_drvdata(dev);
373 clk_bulk_disable_unprepare(data->num_clks, data->clks);
374 reset_control_assert(data->resets);
380 static const struct dev_pm_ops cdns_starfive_pm_ops = {
381 SET_RUNTIME_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume, NULL)
382 SET_SYSTEM_SLEEP_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume)
385 static const struct of_device_id cdns_starfive_of_match[] = {
386 { .compatible = "starfive,jh7110-cdns3", },
389 MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);
391 static struct platform_driver cdns_starfive_driver = {
392 .probe = cdns_starfive_probe,
393 .remove = cdns_starfive_remove,
395 .name = "cdns3-starfive",
396 .of_match_table = cdns_starfive_of_match,
397 .pm = &cdns_starfive_pm_ops,
401 module_platform_driver(cdns_starfive_driver);
403 MODULE_ALIAS("platform:cdns3-starfive");
404 MODULE_AUTHOR("YanHong Wang <yanhong.wang@starfivetech.com>");
405 MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
406 MODULE_LICENSE("GPL v2");
407 MODULE_DESCRIPTION("Cadence USB3 StarFive SoC platform");