9d1147b7067f2c1bf34d4ca0f9b708244daff364
[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 };
78
79 static int cdns_mode_init(struct platform_device *pdev,
80                                 struct cdns_starfive *data)
81 {
82         enum usb_dr_mode mode;
83
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));
91
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));
96         } else {
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));
112
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));
116         }
117         mode = usb_get_dr_mode(&pdev->dev);
118         data->mode = mode;
119
120         switch (mode) {
121         case USB_DR_MODE_HOST:
122                 regmap_update_bits(data->stg_syscon,
123                         data->stg_offset_4,
124                         USB_STRAP_MASK,
125                         USB_STRAP_HOST);
126                 regmap_update_bits(data->stg_syscon,
127                         data->stg_offset_4,
128                         USB_SUSPENDM_MASK,
129                         USB_SUSPENDM_HOST);
130                 break;
131
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);
137                 break;
138
139         case USB_DR_MODE_UNKNOWN:
140         case USB_DR_MODE_OTG:
141         default:
142                 break;
143         }
144
145         return 0;
146 }
147
148
149 static int cdns_clk_rst_init(struct cdns_starfive *data)
150 {
151         int ret;
152
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);
157                 goto exit;
158         }
159
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");
163                 ret = -ENODEV;
164                 goto exit;
165         }
166
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.
170          */
171         ret = clk_set_rate(data->usb_125m_clk, USB_125M_CLK_RATE);
172         if (ret) {
173                 dev_err(data->dev, "Failed to set usb 125m clock\n");
174                 goto exit;
175         }
176         ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
177         if (ret) {
178                 dev_err(data->dev, "Failed to enable clocks\n");
179                 goto exit;
180         }
181
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");
186                 goto err_clk_init;
187         }
188         ret = reset_control_deassert(data->resets);
189         goto exit;
190
191 err_clk_init:
192         clk_bulk_disable_unprepare(data->num_clks, data->clks);
193 exit:
194         return ret;
195 }
196
197 static int cdns_starfive_phy_init(struct platform_device *pdev,
198                                                         struct cdns_starfive *data)
199 {
200         struct device *dev = &pdev->dev;
201         void __iomem *phybase_20, *phybase_30;
202         unsigned int val;
203         int ret = 0;
204
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);
209                 goto get_res_err;
210         }
211
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);
216                 goto get_res_err;
217         }
218
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);
224         }
225
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));
229         }
230
231 get_res_err:
232         return ret;
233 }
234
235 static int cdns_starfive_probe(struct platform_device *pdev)
236 {
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;
241         int ret;
242
243         data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
244         if (!data)
245                 return -ENOMEM;
246
247         platform_set_drvdata(pdev, data);
248
249         data->dev = dev;
250
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);
254         if (ret < 0) {
255                 dev_err(dev, "Failed to parse starfive,stg-syscon\n");
256                 return -EINVAL;
257         }
258
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];
267
268         ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
269                                                 "starfive,sys-syscon", 1, 0, &args);
270         if (ret < 0) {
271                 dev_err(dev, "Failed to parse starfive,sys-syscon\n");
272                 return -EINVAL;
273         }
274
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];
280
281         cdns_mode_init(pdev, data);
282
283         ret = cdns_clk_rst_init(data);
284         if (ret < 0) {
285                 dev_err(&pdev->dev, "Failed to init usb clk reset: %d\n", ret);
286                 goto exit;
287         }
288
289         ret = cdns_starfive_phy_init(pdev, data);
290         if (ret) {
291                 dev_err(dev, "Failed to init sratfive usb phy: %d\n", ret);
292                 goto exit;
293         }
294
295         ret = of_platform_populate(node, NULL, NULL, dev);
296         if (ret) {
297                 dev_err(dev, "Failed to create children: %d\n", ret);
298                 goto exit;
299         }
300
301         device_set_wakeup_capable(dev, true);
302         pm_runtime_set_active(dev);
303         pm_runtime_enable(dev);
304
305         dev_info(dev, "usb mode %d %s probe success\n",
306                 data->mode, data->usb2_only ? "2.0" : "3.0");
307
308         return 0;
309 exit:
310         return ret;
311 }
312
313 static int cdns_starfive_remove_core(struct device *dev, void *c)
314 {
315         struct platform_device *pdev = to_platform_device(dev);
316
317         platform_device_unregister(pdev);
318
319         return 0;
320 }
321
322 static int cdns_starfive_remove(struct platform_device *pdev)
323 {
324         struct device *dev = &pdev->dev;
325         struct cdns_starfive *data = dev_get_drvdata(dev);
326
327         pm_runtime_get_sync(dev);
328         device_for_each_child(dev, NULL, cdns_starfive_remove_core);
329
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);
335
336         return 0;
337 }
338
339 #ifdef CONFIG_PM
340 static int cdns_starfive_resume(struct device *dev)
341 {
342         struct cdns_starfive *data = dev_get_drvdata(dev);
343         int ret;
344
345         ret = clk_set_rate(data->usb_125m_clk, USB_125M_CLK_RATE);
346         if (ret)
347                 goto err;
348
349         ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
350         if (ret)
351                 goto err;
352
353         ret = reset_control_deassert(data->resets);
354 err:
355         return ret;
356 }
357
358 static int cdns_starfive_suspend(struct device *dev)
359 {
360         struct cdns_starfive *data = dev_get_drvdata(dev);
361
362         clk_bulk_disable_unprepare(data->num_clks, data->clks);
363         reset_control_assert(data->resets);
364
365         return 0;
366 }
367 #endif
368
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)
372 };
373
374 static const struct of_device_id cdns_starfive_of_match[] = {
375         { .compatible = "starfive,jh7110-cdns3", },
376         {},
377 };
378 MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);
379
380 static struct platform_driver cdns_starfive_driver = {
381         .probe          = cdns_starfive_probe,
382         .remove         = cdns_starfive_remove,
383         .driver         = {
384                 .name   = "cdns3-starfive",
385                 .of_match_table = cdns_starfive_of_match,
386                 .pm     = &cdns_starfive_pm_ops,
387         },
388 };
389
390 module_platform_driver(cdns_starfive_driver);
391
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");