Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / usb / chipidea / ci_hdrc_msm.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2010, Code Aurora Forum. All rights reserved. */
3
4 #include <linux/module.h>
5 #include <linux/platform_device.h>
6 #include <linux/pm_runtime.h>
7 #include <linux/usb/chipidea.h>
8 #include <linux/clk.h>
9 #include <linux/reset.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/regmap.h>
12 #include <linux/io.h>
13 #include <linux/reset-controller.h>
14 #include <linux/extcon.h>
15 #include <linux/of.h>
16
17 #include "ci.h"
18
19 #define HS_PHY_AHB_MODE                 0x0098
20
21 #define HS_PHY_GENCONFIG                0x009c
22 #define HS_PHY_TXFIFO_IDLE_FORCE_DIS    BIT(4)
23
24 #define HS_PHY_GENCONFIG_2              0x00a0
25 #define HS_PHY_SESS_VLD_CTRL_EN         BIT(7)
26 #define HS_PHY_ULPI_TX_PKT_EN_CLR_FIX   BIT(19)
27
28 #define HSPHY_SESS_VLD_CTRL             BIT(25)
29
30 /* Vendor base starts at 0x200 beyond CI base */
31 #define HS_PHY_CTRL                     0x0040
32 #define HS_PHY_SEC_CTRL                 0x0078
33 #define HS_PHY_DIG_CLAMP_N              BIT(16)
34 #define HS_PHY_POR_ASSERT               BIT(0)
35
36 struct ci_hdrc_msm {
37         struct platform_device *ci;
38         struct clk *core_clk;
39         struct clk *iface_clk;
40         struct clk *fs_clk;
41         struct ci_hdrc_platform_data pdata;
42         struct reset_controller_dev rcdev;
43         bool secondary_phy;
44         bool hsic;
45         void __iomem *base;
46 };
47
48 static int
49 ci_hdrc_msm_por_reset(struct reset_controller_dev *r, unsigned long id)
50 {
51         struct ci_hdrc_msm *ci_msm = container_of(r, struct ci_hdrc_msm, rcdev);
52         void __iomem *addr = ci_msm->base;
53         u32 val;
54
55         if (id)
56                 addr += HS_PHY_SEC_CTRL;
57         else
58                 addr += HS_PHY_CTRL;
59
60         val = readl_relaxed(addr);
61         val |= HS_PHY_POR_ASSERT;
62         writel(val, addr);
63         /*
64          * wait for minimum 10 microseconds as suggested by manual.
65          * Use a slightly larger value since the exact value didn't
66          * work 100% of the time.
67          */
68         udelay(12);
69         val &= ~HS_PHY_POR_ASSERT;
70         writel(val, addr);
71
72         return 0;
73 }
74
75 static const struct reset_control_ops ci_hdrc_msm_reset_ops = {
76         .reset = ci_hdrc_msm_por_reset,
77 };
78
79 static int ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
80 {
81         struct device *dev = ci->dev->parent;
82         struct ci_hdrc_msm *msm_ci = dev_get_drvdata(dev);
83         int ret;
84
85         switch (event) {
86         case CI_HDRC_CONTROLLER_RESET_EVENT:
87                 dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
88
89                 hw_phymode_configure(ci);
90                 if (msm_ci->secondary_phy) {
91                         u32 val = readl_relaxed(msm_ci->base + HS_PHY_SEC_CTRL);
92                         val |= HS_PHY_DIG_CLAMP_N;
93                         writel_relaxed(val, msm_ci->base + HS_PHY_SEC_CTRL);
94                 }
95
96                 ret = phy_init(ci->phy);
97                 if (ret)
98                         return ret;
99
100                 ret = phy_power_on(ci->phy);
101                 if (ret) {
102                         phy_exit(ci->phy);
103                         return ret;
104                 }
105
106                 /* use AHB transactor, allow posted data writes */
107                 hw_write_id_reg(ci, HS_PHY_AHB_MODE, 0xffffffff, 0x8);
108
109                 /* workaround for rx buffer collision issue */
110                 hw_write_id_reg(ci, HS_PHY_GENCONFIG,
111                                 HS_PHY_TXFIFO_IDLE_FORCE_DIS, 0);
112
113                 if (!msm_ci->hsic)
114                         hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
115                                         HS_PHY_ULPI_TX_PKT_EN_CLR_FIX, 0);
116
117                 if (!IS_ERR(ci->platdata->vbus_extcon.edev)) {
118                         hw_write_id_reg(ci, HS_PHY_GENCONFIG_2,
119                                         HS_PHY_SESS_VLD_CTRL_EN,
120                                         HS_PHY_SESS_VLD_CTRL_EN);
121                         hw_write(ci, OP_USBCMD, HSPHY_SESS_VLD_CTRL,
122                                  HSPHY_SESS_VLD_CTRL);
123
124                 }
125                 break;
126         case CI_HDRC_CONTROLLER_STOPPED_EVENT:
127                 dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
128                 phy_power_off(ci->phy);
129                 phy_exit(ci->phy);
130                 break;
131         default:
132                 dev_dbg(dev, "unknown ci_hdrc event\n");
133                 break;
134         }
135
136         return 0;
137 }
138
139 static int ci_hdrc_msm_mux_phy(struct ci_hdrc_msm *ci,
140                                struct platform_device *pdev)
141 {
142         struct regmap *regmap;
143         struct device *dev = &pdev->dev;
144         struct of_phandle_args args;
145         u32 val;
146         int ret;
147
148         ret = of_parse_phandle_with_fixed_args(dev->of_node, "phy-select", 2, 0,
149                                                &args);
150         if (ret)
151                 return 0;
152
153         regmap = syscon_node_to_regmap(args.np);
154         of_node_put(args.np);
155         if (IS_ERR(regmap))
156                 return PTR_ERR(regmap);
157
158         ret = regmap_write(regmap, args.args[0], args.args[1]);
159         if (ret)
160                 return ret;
161
162         ci->secondary_phy = !!args.args[1];
163         if (ci->secondary_phy) {
164                 val = readl_relaxed(ci->base + HS_PHY_SEC_CTRL);
165                 val |= HS_PHY_DIG_CLAMP_N;
166                 writel_relaxed(val, ci->base + HS_PHY_SEC_CTRL);
167         }
168
169         return 0;
170 }
171
172 static int ci_hdrc_msm_probe(struct platform_device *pdev)
173 {
174         struct ci_hdrc_msm *ci;
175         struct platform_device *plat_ci;
176         struct clk *clk;
177         struct reset_control *reset;
178         int ret;
179         struct device_node *ulpi_node, *phy_node;
180
181         dev_dbg(&pdev->dev, "ci_hdrc_msm_probe\n");
182
183         ci = devm_kzalloc(&pdev->dev, sizeof(*ci), GFP_KERNEL);
184         if (!ci)
185                 return -ENOMEM;
186         platform_set_drvdata(pdev, ci);
187
188         ci->pdata.name = "ci_hdrc_msm";
189         ci->pdata.capoffset = DEF_CAPOFFSET;
190         ci->pdata.flags = CI_HDRC_REGS_SHARED | CI_HDRC_DISABLE_STREAMING |
191                           CI_HDRC_OVERRIDE_AHB_BURST |
192                           CI_HDRC_OVERRIDE_PHY_CONTROL;
193         ci->pdata.notify_event = ci_hdrc_msm_notify_event;
194
195         reset = devm_reset_control_get(&pdev->dev, "core");
196         if (IS_ERR(reset))
197                 return PTR_ERR(reset);
198
199         ci->core_clk = clk = devm_clk_get(&pdev->dev, "core");
200         if (IS_ERR(clk))
201                 return PTR_ERR(clk);
202
203         ci->iface_clk = clk = devm_clk_get(&pdev->dev, "iface");
204         if (IS_ERR(clk))
205                 return PTR_ERR(clk);
206
207         ci->fs_clk = clk = devm_clk_get_optional(&pdev->dev, "fs");
208         if (IS_ERR(clk))
209                 return PTR_ERR(clk);
210
211         ci->base = devm_platform_ioremap_resource(pdev, 1);
212         if (IS_ERR(ci->base))
213                 return PTR_ERR(ci->base);
214
215         ci->rcdev.owner = THIS_MODULE;
216         ci->rcdev.ops = &ci_hdrc_msm_reset_ops;
217         ci->rcdev.of_node = pdev->dev.of_node;
218         ci->rcdev.nr_resets = 2;
219         ret = reset_controller_register(&ci->rcdev);
220         if (ret)
221                 return ret;
222
223         ret = clk_prepare_enable(ci->fs_clk);
224         if (ret)
225                 goto err_fs;
226
227         reset_control_assert(reset);
228         usleep_range(10000, 12000);
229         reset_control_deassert(reset);
230
231         clk_disable_unprepare(ci->fs_clk);
232
233         ret = clk_prepare_enable(ci->core_clk);
234         if (ret)
235                 goto err_fs;
236
237         ret = clk_prepare_enable(ci->iface_clk);
238         if (ret)
239                 goto err_iface;
240
241         ret = ci_hdrc_msm_mux_phy(ci, pdev);
242         if (ret)
243                 goto err_mux;
244
245         ulpi_node = of_get_child_by_name(pdev->dev.of_node, "ulpi");
246         if (ulpi_node) {
247                 phy_node = of_get_next_available_child(ulpi_node, NULL);
248                 ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy");
249                 of_node_put(phy_node);
250         }
251         of_node_put(ulpi_node);
252
253         plat_ci = ci_hdrc_add_device(&pdev->dev, pdev->resource,
254                                      pdev->num_resources, &ci->pdata);
255         if (IS_ERR(plat_ci)) {
256                 ret = PTR_ERR(plat_ci);
257                 if (ret != -EPROBE_DEFER)
258                         dev_err(&pdev->dev, "ci_hdrc_add_device failed!\n");
259                 goto err_mux;
260         }
261
262         ci->ci = plat_ci;
263
264         pm_runtime_set_active(&pdev->dev);
265         pm_runtime_no_callbacks(&pdev->dev);
266         pm_runtime_enable(&pdev->dev);
267
268         return 0;
269
270 err_mux:
271         clk_disable_unprepare(ci->iface_clk);
272 err_iface:
273         clk_disable_unprepare(ci->core_clk);
274 err_fs:
275         reset_controller_unregister(&ci->rcdev);
276         return ret;
277 }
278
279 static int ci_hdrc_msm_remove(struct platform_device *pdev)
280 {
281         struct ci_hdrc_msm *ci = platform_get_drvdata(pdev);
282
283         pm_runtime_disable(&pdev->dev);
284         ci_hdrc_remove_device(ci->ci);
285         clk_disable_unprepare(ci->iface_clk);
286         clk_disable_unprepare(ci->core_clk);
287         reset_controller_unregister(&ci->rcdev);
288
289         return 0;
290 }
291
292 static const struct of_device_id msm_ci_dt_match[] = {
293         { .compatible = "qcom,ci-hdrc", },
294         { }
295 };
296 MODULE_DEVICE_TABLE(of, msm_ci_dt_match);
297
298 static struct platform_driver ci_hdrc_msm_driver = {
299         .probe = ci_hdrc_msm_probe,
300         .remove = ci_hdrc_msm_remove,
301         .driver = {
302                 .name = "msm_hsusb",
303                 .of_match_table = msm_ci_dt_match,
304         },
305 };
306
307 module_platform_driver(ci_hdrc_msm_driver);
308
309 MODULE_ALIAS("platform:msm_hsusb");
310 MODULE_ALIAS("platform:ci13xxx_msm");
311 MODULE_LICENSE("GPL v2");