usb: phy: init phy in resume function
[platform/kernel/linux-starfive.git] / drivers / usb / cdns3 / cdns3-starfive.c
1 // SPDX-License-Identifier: GPL-2.0
2 /**
3  * cdns-starfive.c - Cadence USB Controller
4  *
5  * Copyright (C) 2022 Starfive, Inc.
6  * Author:      yanhong <yanhong.wang@starfivetech.com>
7  */
8
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>
15 #include <linux/io.h>
16 #include <linux/of_platform.h>
17 #include <linux/regmap.h>
18 #include <linux/reset.h>
19 #include <linux/usb/otg.h>
20
21 #define USB_STRAP_HOST                  (2 << 0x10)
22 #define USB_STRAP_DEVICE                (4 << 0X10)
23 #define USB_STRAP_MASK                  0x70000
24
25 #define USB_SUSPENDM_HOST               (1 << 0x13)
26 #define USB_SUSPENDM_DEVICE             (0 << 0x13)
27 #define USB_SUSPENDM_MASK               0x80000
28
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
37
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)
53
54
55 #define USB_125M_CLK_RATE               125000000
56
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
61
62 struct cdns_starfive {
63         struct device *dev;
64         struct regmap *stg_syscon;
65         struct regmap *sys_syscon;
66         struct reset_control *resets;
67         struct clk_bulk_data *clks;
68         int num_clks;
69         struct clk *usb_125m_clk;
70         u32 sys_offset;
71         u32 stg_offset_4;
72         u32 stg_offset_196;
73         u32 stg_offset_328;
74         u32 stg_offset_500;
75         bool usb2_only;
76         enum usb_dr_mode mode;
77         void __iomem *phybase_20;
78         void __iomem *phybase_30;
79 };
80
81 static int cdns_mode_init(struct platform_device *pdev,
82                                 struct cdns_starfive *data)
83 {
84         enum usb_dr_mode mode;
85
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));
93
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));
98         } else {
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));
114
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));
118         }
119         mode = usb_get_dr_mode(&pdev->dev);
120         data->mode = mode;
121
122         switch (mode) {
123         case USB_DR_MODE_HOST:
124                 regmap_update_bits(data->stg_syscon,
125                         data->stg_offset_4,
126                         USB_STRAP_MASK,
127                         USB_STRAP_HOST);
128                 regmap_update_bits(data->stg_syscon,
129                         data->stg_offset_4,
130                         USB_SUSPENDM_MASK,
131                         USB_SUSPENDM_HOST);
132                 break;
133
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);
139                 break;
140
141         case USB_DR_MODE_UNKNOWN:
142         case USB_DR_MODE_OTG:
143         default:
144                 break;
145         }
146
147         return 0;
148 }
149
150
151 static int cdns_clk_rst_init(struct cdns_starfive *data)
152 {
153         int ret;
154
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);
159                 goto exit;
160         }
161
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");
165                 ret = -ENODEV;
166                 goto exit;
167         }
168
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.
172          */
173         ret = clk_set_rate(data->usb_125m_clk, USB_125M_CLK_RATE);
174         if (ret) {
175                 dev_err(data->dev, "Failed to set usb 125m clock\n");
176                 goto exit;
177         }
178         ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
179         if (ret) {
180                 dev_err(data->dev, "Failed to enable clocks\n");
181                 goto exit;
182         }
183
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");
188                 goto err_clk_init;
189         }
190         ret = reset_control_deassert(data->resets);
191         goto exit;
192
193 err_clk_init:
194         clk_bulk_disable_unprepare(data->num_clks, data->clks);
195 exit:
196         return ret;
197 }
198
199 static void cdns_starfive_set_phy(struct cdns_starfive *data)
200 {
201         unsigned int val;
202
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);
208         }
209
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);
213         }
214 }
215
216 static int cdns_starfive_phy_init(struct platform_device *pdev,
217                                                         struct cdns_starfive *data)
218 {
219         struct device *dev = &pdev->dev;
220         int ret = 0;
221
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);
226                 goto get_res_err;
227         }
228
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);
233                 goto get_res_err;
234         }
235
236         cdns_starfive_set_phy(data);
237
238 get_res_err:
239         return ret;
240 }
241
242 static int cdns_starfive_probe(struct platform_device *pdev)
243 {
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;
248         int ret;
249
250         data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
251         if (!data)
252                 return -ENOMEM;
253
254         platform_set_drvdata(pdev, data);
255
256         data->dev = dev;
257
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);
261         if (ret < 0) {
262                 dev_err(dev, "Failed to parse starfive,stg-syscon\n");
263                 return -EINVAL;
264         }
265
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];
274
275         ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
276                                                 "starfive,sys-syscon", 1, 0, &args);
277         if (ret < 0) {
278                 dev_err(dev, "Failed to parse starfive,sys-syscon\n");
279                 return -EINVAL;
280         }
281
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];
287
288         cdns_mode_init(pdev, data);
289
290         ret = cdns_clk_rst_init(data);
291         if (ret < 0) {
292                 dev_err(&pdev->dev, "Failed to init usb clk reset: %d\n", ret);
293                 goto exit;
294         }
295
296         ret = cdns_starfive_phy_init(pdev, data);
297         if (ret) {
298                 dev_err(dev, "Failed to init sratfive usb phy: %d\n", ret);
299                 goto exit;
300         }
301
302         ret = of_platform_populate(node, NULL, NULL, dev);
303         if (ret) {
304                 dev_err(dev, "Failed to create children: %d\n", ret);
305                 goto exit;
306         }
307
308         device_set_wakeup_capable(dev, true);
309         pm_runtime_set_active(dev);
310         pm_runtime_enable(dev);
311
312         dev_info(dev, "usb mode %d %s probe success\n",
313                 data->mode, data->usb2_only ? "2.0" : "3.0");
314
315         return 0;
316 exit:
317         return ret;
318 }
319
320 static int cdns_starfive_remove_core(struct device *dev, void *c)
321 {
322         struct platform_device *pdev = to_platform_device(dev);
323
324         platform_device_unregister(pdev);
325
326         return 0;
327 }
328
329 static int cdns_starfive_remove(struct platform_device *pdev)
330 {
331         struct device *dev = &pdev->dev;
332         struct cdns_starfive *data = dev_get_drvdata(dev);
333
334         pm_runtime_get_sync(dev);
335         device_for_each_child(dev, NULL, cdns_starfive_remove_core);
336
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);
342
343         return 0;
344 }
345
346 #ifdef CONFIG_PM
347 static int cdns_starfive_resume(struct device *dev)
348 {
349         struct cdns_starfive *data = dev_get_drvdata(dev);
350         int ret;
351
352         ret = clk_set_rate(data->usb_125m_clk, USB_125M_CLK_RATE);
353         if (ret)
354                 goto err;
355
356         ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
357         if (ret)
358                 goto err;
359
360         ret = reset_control_deassert(data->resets);
361         if (ret)
362                 goto err;
363
364         cdns_starfive_set_phy(data);
365 err:
366         return ret;
367 }
368
369 static int cdns_starfive_suspend(struct device *dev)
370 {
371         struct cdns_starfive *data = dev_get_drvdata(dev);
372
373         clk_bulk_disable_unprepare(data->num_clks, data->clks);
374         reset_control_assert(data->resets);
375
376         return 0;
377 }
378 #endif
379
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)
383 };
384
385 static const struct of_device_id cdns_starfive_of_match[] = {
386         { .compatible = "starfive,jh7110-cdns3", },
387         {},
388 };
389 MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);
390
391 static struct platform_driver cdns_starfive_driver = {
392         .probe          = cdns_starfive_probe,
393         .remove         = cdns_starfive_remove,
394         .driver         = {
395                 .name   = "cdns3-starfive",
396                 .of_match_table = cdns_starfive_of_match,
397                 .pm     = &cdns_starfive_pm_ops,
398         },
399 };
400
401 module_platform_driver(cdns_starfive_driver);
402
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");