• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Rockchip USB 3.0 PHY with Innosilicon IP block driver
3  *
4  * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16 
17 #include <linux/clk.h>
18 #include <linux/delay.h>
19 #include <linux/debugfs.h>
20 #include <linux/gpio/consumer.h>
21 #include <linux/interrupt.h>
22 #include <linux/io.h>
23 #include <linux/kernel.h>
24 #include <linux/mfd/syscon.h>
25 #include <linux/module.h>
26 #include <linux/of.h>
27 #include <linux/of_address.h>
28 #include <linux/of_irq.h>
29 #include <linux/of_platform.h>
30 #include <linux/phy/phy.h>
31 #include <linux/platform_device.h>
32 #include <linux/regmap.h>
33 #include <linux/reset.h>
34 #include <linux/usb/phy.h>
35 #include <linux/uaccess.h>
36 
37 #define FILE_RIGHT_644 0644
38 
39 #define U3PHY_PORT_NUM 2
40 #define U3PHY_MAX_CLKS 4
41 #define BIT_WRITEABLE_SHIFT 16
42 #define SCHEDULE_DELAY (60 * HZ)
43 
44 #define U3PHY_APB_RST BIT(0)
45 #define U3PHY_POR_RST BIT(1)
46 #define U3PHY_MAC_RST BIT(2)
47 
48 struct rockchip_u3phy;
49 struct rockchip_u3phy_port;
50 
51 enum rockchip_u3phy_type {
52     U3PHY_TYPE_PIPE,
53     U3PHY_TYPE_UTMI,
54 };
55 
56 enum rockchip_u3phy_pipe_pwr {
57     PIPE_PWR_P0 = 0,
58     PIPE_PWR_P1 = 1,
59     PIPE_PWR_P2 = 2,
60     PIPE_PWR_P3 = 3,
61     PIPE_PWR_MAX = 4,
62 };
63 
64 enum rockchip_u3phy_rest_req {
65     U3_POR_RSTN = 0,
66     U2_POR_RSTN = 1,
67     PIPE_MAC_RSTN = 2,
68     UTMI_MAC_RSTN = 3,
69     PIPE_APB_RSTN = 4,
70     UTMI_APB_RSTN = 5,
71     U3PHY_RESET_MAX = 6,
72 };
73 
74 enum rockchip_u3phy_utmi_state {
75     PHY_UTMI_HS_ONLINE = 0,
76     PHY_UTMI_DISCONNECT = 1,
77     PHY_UTMI_CONNECT = 2,
78     PHY_UTMI_FS_LS_ONLINE = 4,
79 };
80 
81 /*
82  * @rvalue: reset value
83  * @dvalue: desired value
84  */
85 struct u3phy_reg {
86     unsigned int offset;
87     unsigned int bitend;
88     unsigned int bitstart;
89     unsigned int rvalue;
90     unsigned int dvalue;
91 };
92 
93 struct rockchip_u3phy_grfcfg {
94     struct u3phy_reg um_suspend;
95     struct u3phy_reg ls_det_en;
96     struct u3phy_reg ls_det_st;
97     struct u3phy_reg um_ls;
98     struct u3phy_reg um_hstdct;
99     struct u3phy_reg u2_only_ctrl;
100     struct u3phy_reg u3_disable;
101     struct u3phy_reg pp_pwr_st;
102     struct u3phy_reg pp_pwr_en[PIPE_PWR_MAX];
103 };
104 
105 /**
106  * struct rockchip_u3phy_apbcfg: usb3-phy apb configuration.
107  * @u2_pre_emp: usb2-phy pre-emphasis tuning.
108  * @u2_pre_emp_sth: usb2-phy pre-emphasis strength tuning.
109  * @u2_odt_tuning: usb2-phy odt 45ohm tuning.
110  */
111 struct rockchip_u3phy_apbcfg {
112     unsigned int u2_pre_emp;
113     unsigned int u2_pre_emp_sth;
114     unsigned int u2_odt_tuning;
115 };
116 
117 struct rockchip_u3phy_cfg {
118     unsigned int reg;
119     const struct rockchip_u3phy_grfcfg grfcfg;
120 
121     int (*phy_pipe_power)(struct rockchip_u3phy *, struct rockchip_u3phy_port *, bool on);
122     int (*phy_tuning)(struct rockchip_u3phy *, struct rockchip_u3phy_port *, struct device_node *);
123 };
124 
125 struct rockchip_u3phy_port {
126     struct phy *phy;
127     void __iomem *base;
128     unsigned int index;
129     unsigned char type;
130     bool suspended;
131     bool refclk_25m_quirk;
132     struct mutex mutex; /* mutex for updating register */
133     struct delayed_work um_sm_work;
134 };
135 
136 struct rockchip_u3phy {
137     struct device *dev;
138     struct regmap *u3phy_grf;
139     struct regmap *grf;
140     int um_ls_irq;
141     struct clk *clks[U3PHY_MAX_CLKS];
142     struct dentry *root;
143     struct regulator *vbus;
144     struct reset_control *rsts[U3PHY_RESET_MAX];
145     struct rockchip_u3phy_apbcfg apbcfg;
146     const struct rockchip_u3phy_cfg *cfgs;
147     struct rockchip_u3phy_port ports[U3PHY_PORT_NUM];
148     struct usb_phy usb_phy;
149     bool vbus_enabled;
150 };
151 
param_write(void __iomem * base,const struct u3phy_reg * reg,bool desired)152 static inline int param_write(void __iomem *base, const struct u3phy_reg *reg, bool desired)
153 {
154     unsigned int val, mask;
155     unsigned int tmp = desired ? reg->dvalue : reg->rvalue;
156     int ret = 0;
157 
158     mask = GENMASK(reg->bitend, reg->bitstart);
159     val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
160     ret = regmap_write(base, reg->offset, val);
161 
162     return ret;
163 }
164 
param_exped(void __iomem * base,const struct u3phy_reg * reg,unsigned int value)165 static inline bool param_exped(void __iomem *base, const struct u3phy_reg *reg, unsigned int value)
166 {
167     int ret;
168     unsigned int tmp, orig;
169     unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
170 
171     ret = regmap_read(base, reg->offset, &orig);
172     if (ret) {
173         return false;
174     }
175 
176     tmp = (orig & mask) >> reg->bitstart;
177     return tmp == value;
178 }
179 
rockchip_set_vbus_power(struct rockchip_u3phy * u3phy,bool en)180 static int rockchip_set_vbus_power(struct rockchip_u3phy *u3phy, bool en)
181 {
182     int ret = 0;
183 
184     if (!u3phy->vbus) {
185         return 0;
186     }
187 
188     if (en && !u3phy->vbus_enabled) {
189         ret = regulator_enable(u3phy->vbus);
190         if (ret) {
191             dev_err(u3phy->dev, "Failed to enable VBUS supply\n");
192         }
193     } else if (!en && u3phy->vbus_enabled) {
194         ret = regulator_disable(u3phy->vbus);
195     }
196 
197     if (ret == 0) {
198         u3phy->vbus_enabled = en;
199     }
200 
201     return ret;
202 }
203 
rockchip_u3phy_usb2_only_show(struct seq_file * s,void * unused)204 static int rockchip_u3phy_usb2_only_show(struct seq_file *s, void *unused)
205 {
206     struct rockchip_u3phy *u3phy = s->private;
207 
208     if (param_exped(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.u2_only_ctrl, 1)) {
209         dev_info(u3phy->dev, "u2\n");
210     } else {
211         dev_info(u3phy->dev, "u3\n");
212     }
213 
214     return 0;
215 }
216 
rockchip_u3phy_usb2_only_open(struct inode * inode,struct file * file)217 static int rockchip_u3phy_usb2_only_open(struct inode *inode, struct file *file)
218 {
219     return single_open(file, rockchip_u3phy_usb2_only_show, inode->i_private);
220 }
221 
rockchip_u3phy_usb2_only_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)222 static ssize_t rockchip_u3phy_usb2_only_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
223 {
224     struct seq_file *s = file->private_data;
225     struct rockchip_u3phy *u3phy = s->private;
226     struct rockchip_u3phy_port *u3phy_port;
227     char buf[32];
228     u8 index;
229 
230     if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) {
231         return -EFAULT;
232     }
233 
234     if (!strncmp(buf, "u3", 2) && param_exped(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.u2_only_ctrl, 1)) {
235         dev_info(u3phy->dev, "Set usb3.0 and usb2.0 mode successfully\n");
236 
237         rockchip_set_vbus_power(u3phy, false);
238 
239         param_write(u3phy->grf, &u3phy->cfgs->grfcfg.u3_disable, false);
240         param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.u2_only_ctrl, false);
241 
242         for (index = 0; index < U3PHY_PORT_NUM; index++) {
243             u3phy_port = &u3phy->ports[index];
244             /* enable u3 rx termimation */
245             if (u3phy_port->type == U3PHY_TYPE_PIPE) {
246                 writel(0x30, u3phy_port->base + 0xd8);
247             }
248         }
249 
250         atomic_notifier_call_chain(&u3phy->usb_phy.notifier, 0, NULL);
251 
252         rockchip_set_vbus_power(u3phy, true);
253     } else if (!strncmp(buf, "u2", 2) && param_exped(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.u2_only_ctrl, 0)) {
254         dev_info(u3phy->dev, "Set usb2.0 only mode successfully\n");
255 
256         rockchip_set_vbus_power(u3phy, false);
257 
258         param_write(u3phy->grf, &u3phy->cfgs->grfcfg.u3_disable, true);
259         param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.u2_only_ctrl, true);
260 
261         for (index = 0; index < U3PHY_PORT_NUM; index++) {
262             u3phy_port = &u3phy->ports[index];
263             /* disable u3 rx termimation */
264             if (u3phy_port->type == U3PHY_TYPE_PIPE) {
265                 writel(0x20, u3phy_port->base + 0xd8);
266             }
267         }
268 
269         atomic_notifier_call_chain(&u3phy->usb_phy.notifier, 0, NULL);
270 
271         rockchip_set_vbus_power(u3phy, true);
272     } else {
273         dev_info(u3phy->dev, "Same or illegal mode\n");
274     }
275 
276     return count;
277 }
278 
279 static const struct file_operations rockchip_u3phy_usb2_only_fops = {
280     .open = rockchip_u3phy_usb2_only_open,
281     .write = rockchip_u3phy_usb2_only_write,
282     .read = seq_read,
283     .llseek = seq_lseek,
284     .release = single_release,
285 };
286 
rockchip_u3phy_debugfs_init(struct rockchip_u3phy * u3phy)287 int rockchip_u3phy_debugfs_init(struct rockchip_u3phy *u3phy)
288 {
289     struct dentry *root;
290     struct dentry *file;
291     int ret;
292 
293     root = debugfs_create_dir(dev_name(u3phy->dev), NULL);
294     if (!root) {
295         ret = -ENOMEM;
296         goto err0;
297     }
298 
299     u3phy->root = root;
300 
301     file = debugfs_create_file("u3phy_mode", FILE_RIGHT_644, root, u3phy, &rockchip_u3phy_usb2_only_fops);
302     if (!file) {
303         ret = -ENOMEM;
304         goto err1;
305     }
306     return 0;
307 
308 err1:
309     debugfs_remove_recursive(root);
310 err0:
311     return ret;
312 }
313 
get_rest_name(enum rockchip_u3phy_rest_req rst)314 static const char *get_rest_name(enum rockchip_u3phy_rest_req rst)
315 {
316     switch (rst) {
317         case U2_POR_RSTN:
318             return "u3phy-u2-por";
319         case U3_POR_RSTN:
320             return "u3phy-u3-por";
321         case PIPE_MAC_RSTN:
322             return "u3phy-pipe-mac";
323         case UTMI_MAC_RSTN:
324             return "u3phy-utmi-mac";
325         case UTMI_APB_RSTN:
326             return "u3phy-utmi-apb";
327         case PIPE_APB_RSTN:
328             return "u3phy-pipe-apb";
329         default:
330             return "invalid";
331     }
332 }
333 
rockchip_u3phy_rest_deassert(struct rockchip_u3phy * u3phy,unsigned int flag)334 static void rockchip_u3phy_rest_deassert(struct rockchip_u3phy *u3phy, unsigned int flag)
335 {
336     int rst;
337 
338     if (flag & U3PHY_APB_RST) {
339         dev_dbg(u3phy->dev, "deassert APB bus interface reset\n");
340         for (rst = PIPE_APB_RSTN; rst <= UTMI_APB_RSTN; rst++) {
341             if (u3phy->rsts[rst]) {
342                 reset_control_deassert(u3phy->rsts[rst]);
343             }
344         }
345     }
346 
347     if (flag & U3PHY_POR_RST) {
348         usleep_range(0x0C, 0x0F);
349         dev_dbg(u3phy->dev, "deassert u2 and u3 phy power on reset\n");
350         for (rst = U3_POR_RSTN; rst <= U2_POR_RSTN; rst++) {
351             if (u3phy->rsts[rst]) {
352                 reset_control_deassert(u3phy->rsts[rst]);
353             }
354         }
355     }
356 
357     if (flag & U3PHY_MAC_RST) {
358         usleep_range(0x4B0, 0x5DC);
359         dev_dbg(u3phy->dev, "deassert pipe and utmi MAC reset\n");
360         for (rst = PIPE_MAC_RSTN; rst <= UTMI_MAC_RSTN; rst++) {
361             if (u3phy->rsts[rst]) {
362                 reset_control_deassert(u3phy->rsts[rst]);
363             }
364         }
365     }
366 }
367 
rockchip_u3phy_rest_assert(struct rockchip_u3phy * u3phy)368 static void rockchip_u3phy_rest_assert(struct rockchip_u3phy *u3phy)
369 {
370     int rst;
371 
372     dev_dbg(u3phy->dev, "assert u3phy reset\n");
373     for (rst = 0; rst < U3PHY_RESET_MAX; rst++) {
374         if (u3phy->rsts[rst]) {
375             reset_control_assert(u3phy->rsts[rst]);
376         }
377     }
378 }
379 
rockchip_u3phy_clk_enable(struct rockchip_u3phy * u3phy)380 static int rockchip_u3phy_clk_enable(struct rockchip_u3phy *u3phy)
381 {
382     int ret, clk;
383 
384     for (clk = 0; clk < U3PHY_MAX_CLKS && u3phy->clks[clk]; clk++) {
385         ret = clk_prepare_enable(u3phy->clks[clk]);
386         if (ret) {
387             goto err_disable_clks;
388         }
389     }
390     return 0;
391 
392 err_disable_clks:
393     while (--clk >= 0) {
394         clk_disable_unprepare(u3phy->clks[clk]);
395     }
396     return ret;
397 }
398 
rockchip_u3phy_clk_disable(struct rockchip_u3phy * u3phy)399 static void rockchip_u3phy_clk_disable(struct rockchip_u3phy *u3phy)
400 {
401     int clk;
402 
403     for (clk = U3PHY_MAX_CLKS - 1; clk >= 0; clk--) {
404         if (u3phy->clks[clk]) {
405             clk_disable_unprepare(u3phy->clks[clk]);
406         }
407     }
408 }
409 
rockchip_u3phy_init(struct phy * phy)410 static int rockchip_u3phy_init(struct phy *phy)
411 {
412     return 0;
413 }
414 
rockchip_u3phy_exit(struct phy * phy)415 static int rockchip_u3phy_exit(struct phy *phy)
416 {
417     return 0;
418 }
419 
rockchip_u3phy_power_on(struct phy * phy)420 static int rockchip_u3phy_power_on(struct phy *phy)
421 {
422     struct rockchip_u3phy_port *u3phy_port = phy_get_drvdata(phy);
423     struct rockchip_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
424     int ret;
425 
426     dev_info(&u3phy_port->phy->dev, "u3phy %s power on\n", (u3phy_port->type == U3PHY_TYPE_UTMI) ? "u2" : "u3");
427 
428     if (!u3phy_port->suspended) {
429         return 0;
430     }
431 
432     ret = rockchip_u3phy_clk_enable(u3phy);
433     if (ret) {
434         return ret;
435     }
436 
437     if (u3phy_port->type == U3PHY_TYPE_UTMI) {
438         param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.um_suspend, false);
439     } else {
440         /* current in p2 ? */
441         if (param_exped(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.pp_pwr_st, PIPE_PWR_P2)) {
442             goto done;
443         }
444 
445         if (u3phy->cfgs->phy_pipe_power) {
446             dev_dbg(u3phy->dev, "do pipe power up\n");
447             u3phy->cfgs->phy_pipe_power(u3phy, u3phy_port, true);
448         }
449 
450         /* exit to p0 */
451         param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P0], true);
452         usleep_range(0x5A, 0x64);
453 
454         /* enter to p2 from p0 */
455         param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P2], false);
456         udelay(0x03);
457     }
458 
459 done:
460     rockchip_set_vbus_power(u3phy, true);
461     u3phy_port->suspended = false;
462     return 0;
463 }
464 
rockchip_u3phy_power_off(struct phy * phy)465 static int rockchip_u3phy_power_off(struct phy *phy)
466 {
467     struct rockchip_u3phy_port *u3phy_port = phy_get_drvdata(phy);
468     struct rockchip_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
469 
470     dev_info(&u3phy_port->phy->dev, "u3phy %s power off\n", (u3phy_port->type == U3PHY_TYPE_UTMI) ? "u2" : "u3");
471 
472     if (u3phy_port->suspended) {
473         return 0;
474     }
475 
476     if (u3phy_port->type == U3PHY_TYPE_UTMI) {
477         param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.um_suspend, true);
478     } else {
479         /* current in p3 ? */
480         if (param_exped(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.pp_pwr_st, PIPE_PWR_P3)) {
481             goto done;
482         }
483 
484         /* exit to p0 */
485         param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P0], true);
486         udelay(0x02);
487 
488         /* enter to p3 from p0 */
489         param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P3], true);
490         udelay(0x06);
491 
492         if (u3phy->cfgs->phy_pipe_power) {
493             dev_dbg(u3phy->dev, "do pipe power down\n");
494             u3phy->cfgs->phy_pipe_power(u3phy, u3phy_port, false);
495         }
496     }
497 
498 done:
499     rockchip_u3phy_clk_disable(u3phy);
500     u3phy_port->suspended = true;
501     return 0;
502 }
503 
rockchip_u3phy_xlate(struct device * dev,struct of_phandle_args * args)504 static __maybe_unused struct phy *rockchip_u3phy_xlate(struct device *dev, struct of_phandle_args *args)
505 {
506     struct rockchip_u3phy *u3phy = dev_get_drvdata(dev);
507     struct rockchip_u3phy_port *u3phy_port = NULL;
508     struct device_node *phy_np = args->np;
509     int index;
510 
511     if (args->args_count != 1) {
512         dev_err(dev, "invalid number of cells in 'phy' property\n");
513         return ERR_PTR(-EINVAL);
514     }
515 
516     for (index = 0; index < U3PHY_PORT_NUM; index++) {
517         if (phy_np == u3phy->ports[index].phy->dev.of_node) {
518             u3phy_port = &u3phy->ports[index];
519             break;
520         }
521     }
522 
523     if (!u3phy_port) {
524         dev_err(dev, "failed to find appropriate phy\n");
525         return ERR_PTR(-EINVAL);
526     }
527 
528     return u3phy_port->phy;
529 }
530 
531 static struct phy_ops rockchip_u3phy_ops = {
532     .init = rockchip_u3phy_init,
533     .exit = rockchip_u3phy_exit,
534     .power_on = rockchip_u3phy_power_on,
535     .power_off = rockchip_u3phy_power_off,
536     .owner = THIS_MODULE,
537 };
538 
539 /*
540  * The function manage host-phy port state and suspend/resume phy port
541  * to save power automatically.
542  *
543  * we rely on utmi_linestate and utmi_hostdisconnect to identify whether
544  * devices is disconnect or not. Besides, we do not need care it is FS/LS
545  * disconnected or HS disconnected, actually, we just only need get the
546  * device is disconnected at last through rearm the delayed work,
547  * to suspend the phy port in _PHY_STATE_DISCONNECT_ case.
548  */
rockchip_u3phy_um_sm_work(struct work_struct * work)549 static void rockchip_u3phy_um_sm_work(struct work_struct *work)
550 {
551     struct rockchip_u3phy_port *u3phy_port = container_of(work, struct rockchip_u3phy_port, um_sm_work.work);
552     struct rockchip_u3phy *u3phy = dev_get_drvdata(u3phy_port->phy->dev.parent);
553     unsigned int sh = u3phy->cfgs->grfcfg.um_hstdct.bitend - u3phy->cfgs->grfcfg.um_hstdct.bitstart + 1;
554     unsigned int ul, uhd, state;
555     unsigned int ul_mask, uhd_mask;
556     int ret;
557 
558     mutex_lock(&u3phy_port->mutex);
559 
560     ret = regmap_read(u3phy->u3phy_grf, u3phy->cfgs->grfcfg.um_ls.offset, &ul);
561     if (ret < 0) {
562         goto next_schedule;
563     }
564 
565     ret = regmap_read(u3phy->u3phy_grf, u3phy->cfgs->grfcfg.um_hstdct.offset, &uhd);
566     if (ret < 0) {
567         goto next_schedule;
568     }
569 
570     uhd_mask = GENMASK(u3phy->cfgs->grfcfg.um_hstdct.bitend, u3phy->cfgs->grfcfg.um_hstdct.bitstart);
571     ul_mask = GENMASK(u3phy->cfgs->grfcfg.um_ls.bitend, u3phy->cfgs->grfcfg.um_ls.bitstart);
572 
573     /* stitch on um_ls and um_hstdct as phy state */
574     state = ((uhd & uhd_mask) >> u3phy->cfgs->grfcfg.um_hstdct.bitstart) |
575             (((ul & ul_mask) >> u3phy->cfgs->grfcfg.um_ls.bitstart) << sh);
576 
577     switch (state) {
578         case PHY_UTMI_HS_ONLINE:
579             dev_dbg(&u3phy_port->phy->dev, "HS online\n");
580             break;
581         case PHY_UTMI_FS_LS_ONLINE:
582             /*
583              * For FS/LS device, the online state share with connect state
584              * from um_ls and um_hstdct register, so we distinguish
585              * them via suspended flag.
586              *
587              * Plus, there are two cases, one is D- Line pull-up, and D+
588              * line pull-down, the state is 4; another is D+ line pull-up,
589              * and D- line pull-down, the state is 2.
590              */
591             if (!u3phy_port->suspended) {
592                 /* D- line pull-up, D+ line pull-down */
593                 dev_dbg(&u3phy_port->phy->dev, "FS/LS online\n");
594                 break;
595             }
596             /* fall through */
597         case PHY_UTMI_CONNECT:
598             if (u3phy_port->suspended) {
599                 dev_dbg(&u3phy_port->phy->dev, "Connected\n");
600                 rockchip_u3phy_power_on(u3phy_port->phy);
601                 u3phy_port->suspended = false;
602             } else {
603                 /* D+ line pull-up, D- line pull-down */
604                 dev_dbg(&u3phy_port->phy->dev, "FS/LS online\n");
605             }
606             break;
607         case PHY_UTMI_DISCONNECT:
608             if (!u3phy_port->suspended) {
609                 dev_dbg(&u3phy_port->phy->dev, "Disconnected\n");
610                 rockchip_u3phy_power_off(u3phy_port->phy);
611                 u3phy_port->suspended = true;
612             }
613 
614             /*
615              * activate the linestate detection to get the next device
616              * plug-in irq.
617              */
618             param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_st, true);
619             param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_en, true);
620 
621             /*
622              * we don't need to rearm the delayed work when the phy port
623              * is suspended.
624              */
625             mutex_unlock(&u3phy_port->mutex);
626             return;
627         default:
628             dev_dbg(&u3phy_port->phy->dev, "unknown phy state\n");
629             break;
630     }
631 
632 next_schedule:
633     mutex_unlock(&u3phy_port->mutex);
634     schedule_delayed_work(&u3phy_port->um_sm_work, SCHEDULE_DELAY);
635 }
636 
rockchip_u3phy_um_ls_irq(int irq,void * data)637 static irqreturn_t rockchip_u3phy_um_ls_irq(int irq, void *data)
638 {
639     struct rockchip_u3phy_port *u3phy_port = data;
640     struct rockchip_u3phy *u3phy = dev_get_drvdata(u3phy_port->phy->dev.parent);
641 
642     if (!param_exped(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_st, u3phy->cfgs->grfcfg.ls_det_st.dvalue)) {
643         return IRQ_NONE;
644     }
645 
646     dev_dbg(u3phy->dev, "utmi linestate interrupt\n");
647     mutex_lock(&u3phy_port->mutex);
648 
649     /* disable linestate detect irq and clear its status */
650     param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_en, false);
651     param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_st, true);
652 
653     mutex_unlock(&u3phy_port->mutex);
654 
655     /*
656      * In this case for host phy, a new device is plugged in, meanwhile,
657      * if the phy port is suspended, we need rearm the work to resume it
658      * and mange its states; otherwise, we just return irq handled.
659      */
660     if (u3phy_port->suspended) {
661         dev_dbg(u3phy->dev, "schedule utmi sm work\n");
662         rockchip_u3phy_um_sm_work(&u3phy_port->um_sm_work.work);
663     }
664 
665     return IRQ_HANDLED;
666 }
667 
rockchip_u3phy_parse_dt(struct rockchip_u3phy * u3phy,struct platform_device * pdev)668 static int rockchip_u3phy_parse_dt(struct rockchip_u3phy *u3phy, struct platform_device *pdev)
669 
670 {
671     struct device *dev = &pdev->dev;
672     struct device_node *np = dev->of_node;
673     int ret, i, clk;
674 
675     u3phy->um_ls_irq = platform_get_irq_byname(pdev, "linestate");
676     if (u3phy->um_ls_irq < 0) {
677         dev_err(dev, "get utmi linestate irq failed\n");
678         return -ENXIO;
679     }
680 
681     /* Get Vbus regulators */
682     u3phy->vbus = devm_regulator_get_optional(dev, "vbus");
683     if (IS_ERR(u3phy->vbus)) {
684         ret = PTR_ERR(u3phy->vbus);
685         if (ret == -EPROBE_DEFER) {
686             return ret;
687         }
688 
689         dev_warn(dev, "Failed to get VBUS supply regulator\n");
690         u3phy->vbus = NULL;
691     }
692 
693     for (clk = 0; clk < U3PHY_MAX_CLKS; clk++) {
694         u3phy->clks[clk] = of_clk_get(np, clk);
695         if (IS_ERR(u3phy->clks[clk])) {
696             ret = PTR_ERR(u3phy->clks[clk]);
697             if (ret == -EPROBE_DEFER) {
698                 goto err_put_clks;
699             }
700             u3phy->clks[clk] = NULL;
701             break;
702         }
703     }
704 
705     for (i = 0; i < U3PHY_RESET_MAX; i++) {
706         u3phy->rsts[i] = devm_reset_control_get(dev, get_rest_name(i));
707         if (IS_ERR(u3phy->rsts[i])) {
708             dev_info(dev, "no %s reset control specified\n", get_rest_name(i));
709             u3phy->rsts[i] = NULL;
710         }
711     }
712 
713     return 0;
714 
715 err_put_clks:
716     while (--clk >= 0) {
717         clk_put(u3phy->clks[clk]);
718     }
719     return ret;
720 }
721 
rockchip_u3phy_port_init(struct rockchip_u3phy * u3phy,struct rockchip_u3phy_port * u3phy_port,struct device_node * child_np)722 static int rockchip_u3phy_port_init(struct rockchip_u3phy *u3phy, struct rockchip_u3phy_port *u3phy_port,
723                                     struct device_node *child_np)
724 {
725     struct resource res;
726     struct phy *phy;
727     int ret;
728 
729     dev_dbg(u3phy->dev, "u3phy port initialize\n");
730 
731     mutex_init(&u3phy_port->mutex);
732     u3phy_port->suspended = true; /* initial status */
733 
734     phy = devm_phy_create(u3phy->dev, child_np, &rockchip_u3phy_ops);
735     if (IS_ERR(phy)) {
736         dev_err(u3phy->dev, "failed to create phy\n");
737         return PTR_ERR(phy);
738     }
739 
740     u3phy_port->phy = phy;
741 
742     ret = of_address_to_resource(child_np, 0, &res);
743     if (ret) {
744         dev_err(u3phy->dev, "failed to get address resource(np-%s)\n", child_np->name);
745         return ret;
746     }
747 
748     u3phy_port->base = devm_ioremap_resource(&u3phy_port->phy->dev, &res);
749     if (IS_ERR(u3phy_port->base)) {
750         dev_err(u3phy->dev, "failed to remap phy regs\n");
751         return PTR_ERR(u3phy_port->base);
752     }
753 
754     if (!of_node_cmp(child_np->name, "pipe")) {
755         u3phy_port->type = U3PHY_TYPE_PIPE;
756         u3phy_port->refclk_25m_quirk = of_property_read_bool(child_np, "rockchip,refclk-25m-quirk");
757     } else {
758         u3phy_port->type = U3PHY_TYPE_UTMI;
759         INIT_DELAYED_WORK(&u3phy_port->um_sm_work, rockchip_u3phy_um_sm_work);
760 
761         ret = devm_request_threaded_irq(u3phy->dev, u3phy->um_ls_irq, NULL, rockchip_u3phy_um_ls_irq, IRQF_ONESHOT,
762                                         "rockchip_u3phy", u3phy_port);
763         if (ret) {
764             dev_err(u3phy->dev, "failed to request utmi linestate irq handle\n");
765             return ret;
766         }
767     }
768 
769     if (u3phy->cfgs->phy_tuning) {
770         dev_dbg(u3phy->dev, "do u3phy tuning\n");
771         ret = u3phy->cfgs->phy_tuning(u3phy, u3phy_port, child_np);
772         if (ret) {
773             return ret;
774         }
775     }
776 
777     phy_set_drvdata(u3phy_port->phy, u3phy_port);
778     return 0;
779 }
780 
rockchip_u3phy_on_init(struct usb_phy * usb_phy)781 static int rockchip_u3phy_on_init(struct usb_phy *usb_phy)
782 {
783     struct rockchip_u3phy *u3phy = container_of(usb_phy, struct rockchip_u3phy, usb_phy);
784 
785     rockchip_u3phy_rest_deassert(u3phy, U3PHY_POR_RST | U3PHY_MAC_RST);
786     return 0;
787 }
788 
rockchip_u3phy_on_shutdown(struct usb_phy * usb_phy)789 static void rockchip_u3phy_on_shutdown(struct usb_phy *usb_phy)
790 {
791     struct rockchip_u3phy *u3phy = container_of(usb_phy, struct rockchip_u3phy, usb_phy);
792     int rst;
793 
794     for (rst = 0; rst < U3PHY_RESET_MAX; rst++) {
795         if (u3phy->rsts[rst] && rst != UTMI_APB_RSTN && rst != PIPE_APB_RSTN) {
796             reset_control_assert(u3phy->rsts[rst]);
797         }
798     }
799     udelay(1);
800 }
801 
rockchip_u3phy_on_disconnect(struct usb_phy * usb_phy,enum usb_device_speed speed)802 static int rockchip_u3phy_on_disconnect(struct usb_phy *usb_phy, enum usb_device_speed speed)
803 {
804     struct rockchip_u3phy *u3phy = container_of(usb_phy, struct rockchip_u3phy, usb_phy);
805 
806     dev_info(u3phy->dev, "%s device has disconnected\n", (speed == USB_SPEED_SUPER) ? "U3" : "UW/U2/U1.1/U1");
807 
808     if (speed == USB_SPEED_SUPER) {
809         atomic_notifier_call_chain(&usb_phy->notifier, 0, NULL);
810     }
811 
812     return 0;
813 }
814 
rockchip_u3phy_probe(struct platform_device * pdev)815 static int rockchip_u3phy_probe(struct platform_device *pdev)
816 {
817     struct device *dev = &pdev->dev;
818     struct device_node *np = dev->of_node;
819     struct device_node *child_np;
820     struct phy_provider *provider;
821     struct rockchip_u3phy *u3phy;
822     const struct rockchip_u3phy_cfg *phy_cfgs;
823     const struct of_device_id *match;
824     unsigned int reg[2];
825     int index, ret;
826 
827     match = of_match_device(dev->driver->of_match_table, dev);
828     if (!match || !match->data) {
829         dev_err(dev, "phy-cfgs are not assigned!\n");
830         return -EINVAL;
831     }
832 
833     u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
834     if (!u3phy) {
835         return -ENOMEM;
836     }
837 
838     u3phy->u3phy_grf = syscon_regmap_lookup_by_phandle(np, "rockchip,u3phygrf");
839     if (IS_ERR(u3phy->u3phy_grf)) {
840         return PTR_ERR(u3phy->u3phy_grf);
841     }
842 
843     u3phy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
844     if (IS_ERR(u3phy->grf)) {
845         dev_err(dev, "Missing rockchip,grf property\n");
846         return PTR_ERR(u3phy->grf);
847     }
848 
849     if (of_property_read_u32_array(np, "reg", reg, 0x02)) {
850         dev_err(dev, "the reg property is not assigned in %s node\n", np->name);
851         return -EINVAL;
852     }
853 
854     u3phy->dev = dev;
855     u3phy->vbus_enabled = false;
856     phy_cfgs = match->data;
857     platform_set_drvdata(pdev, u3phy);
858 
859     /* find out a proper config which can be matched with dt. */
860     index = 0;
861     while (phy_cfgs[index].reg) {
862         if (phy_cfgs[index].reg == reg[1]) {
863             u3phy->cfgs = &phy_cfgs[index];
864             break;
865         }
866 
867         ++index;
868     }
869 
870     if (!u3phy->cfgs) {
871         dev_err(dev, "no phy-cfgs can be matched with %s node\n", np->name);
872         return -EINVAL;
873     }
874 
875     ret = rockchip_u3phy_parse_dt(u3phy, pdev);
876     if (ret) {
877         dev_err(dev, "parse dt failed, ret(%d)\n", ret);
878         return ret;
879     }
880 
881     ret = rockchip_u3phy_clk_enable(u3phy);
882     if (ret) {
883         dev_err(dev, "clk enable failed, ret(%d)\n", ret);
884         return ret;
885     }
886 
887     rockchip_u3phy_rest_assert(u3phy);
888     rockchip_u3phy_rest_deassert(u3phy, U3PHY_APB_RST | U3PHY_POR_RST);
889 
890     index = 0;
891     for_each_available_child_of_node(np, child_np)
892     {
893         struct rockchip_u3phy_port *u3phy_port = &u3phy->ports[index];
894 
895         u3phy_port->index = index;
896         ret = rockchip_u3phy_port_init(u3phy, u3phy_port, child_np);
897         if (ret) {
898             dev_err(dev, "u3phy port init failed,ret(%d)\n", ret);
899             goto put_child;
900         }
901 
902         /* to prevent out of boundary */
903         if (++index >= U3PHY_PORT_NUM) {
904             break;
905         }
906     }
907 
908     provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
909     if (IS_ERR_OR_NULL(provider)) {
910         goto put_child;
911     }
912 
913     rockchip_u3phy_rest_deassert(u3phy, U3PHY_MAC_RST);
914     rockchip_u3phy_clk_disable(u3phy);
915 
916     u3phy->usb_phy.dev = dev;
917     u3phy->usb_phy.init = rockchip_u3phy_on_init;
918     u3phy->usb_phy.shutdown = rockchip_u3phy_on_shutdown;
919     u3phy->usb_phy.notify_disconnect = rockchip_u3phy_on_disconnect;
920     usb_add_phy(&u3phy->usb_phy, USB_PHY_TYPE_USB3);
921     ATOMIC_INIT_NOTIFIER_HEAD(&u3phy->usb_phy.notifier);
922 
923     rockchip_u3phy_debugfs_init(u3phy);
924 
925     dev_info(dev, "Rockchip u3phy initialized successfully\n");
926     return 0;
927 
928 put_child:
929     of_node_put(child_np);
930     return ret;
931 }
932 
rk3328_u3phy_pipe_power(struct rockchip_u3phy * u3phy,struct rockchip_u3phy_port * u3phy_port,bool on)933 static int rk3328_u3phy_pipe_power(struct rockchip_u3phy *u3phy, struct rockchip_u3phy_port *u3phy_port, bool on)
934 {
935     unsigned int reg;
936 
937     if (on) {
938         reg = readl(u3phy_port->base + 0x1a8);
939         reg &= ~BIT(0x04); /* ldo power up */
940         writel(reg, u3phy_port->base + 0x1a8);
941 
942         reg = readl(u3phy_port->base + 0x044);
943         reg &= ~BIT(0x04); /* bg power on */
944         writel(reg, u3phy_port->base + 0x044);
945 
946         reg = readl(u3phy_port->base + 0x150);
947         reg |= BIT(0x06); /* tx bias enable */
948         writel(reg, u3phy_port->base + 0x150);
949 
950         reg = readl(u3phy_port->base + 0x080);
951         reg &= ~BIT(0x02); /* tx cm power up */
952         writel(reg, u3phy_port->base + 0x080);
953 
954         reg = readl(u3phy_port->base + 0x0c0);
955         /* tx obs enable and rx cm enable */
956         reg |= (BIT(0x03) | BIT(0x04));
957         writel(reg, u3phy_port->base + 0x0c0);
958 
959         udelay(1);
960     } else {
961         reg = readl(u3phy_port->base + 0x1a8);
962         reg |= BIT(0x04); /* ldo power down */
963         writel(reg, u3phy_port->base + 0x1a8);
964 
965         reg = readl(u3phy_port->base + 0x044);
966         reg |= BIT(0x04); /* bg power down */
967         writel(reg, u3phy_port->base + 0x044);
968 
969         reg = readl(u3phy_port->base + 0x150);
970         reg &= ~BIT(0x06); /* tx bias disable */
971         writel(reg, u3phy_port->base + 0x150);
972 
973         reg = readl(u3phy_port->base + 0x080);
974         reg |= BIT(0x02); /* tx cm power down */
975         writel(reg, u3phy_port->base + 0x080);
976 
977         reg = readl(u3phy_port->base + 0x0c0);
978         /* tx obs disable and rx cm disable */
979         reg &= ~(BIT(0x03) | BIT(0x04));
980         writel(reg, u3phy_port->base + 0x0c0);
981     }
982 
983     return 0;
984 }
985 
rk3328_u3phy_tuning(struct rockchip_u3phy * u3phy,struct rockchip_u3phy_port * u3phy_port,struct device_node * child_np)986 static int rk3328_u3phy_tuning(struct rockchip_u3phy *u3phy, struct rockchip_u3phy_port *u3phy_port,
987                                struct device_node *child_np)
988 {
989     if (u3phy_port->type == U3PHY_TYPE_UTMI) {
990         /*
991          * For rk3328 SoC, pre-emphasis and pre-emphasis strength must
992          * be written as one fixed value as below.
993          *
994          * Dissimilarly, the odt 45ohm value should be flexibly tuninged
995          * for the different boards to adjust HS eye height, so its
996          * value can be assigned in DT in code design.
997          */
998 
999         /* {bits[2:0]=111}: always enable pre-emphasis */
1000         u3phy->apbcfg.u2_pre_emp = 0x0f;
1001 
1002         /* {bits[5:3]=000}: pre-emphasis strength as the weakest */
1003         u3phy->apbcfg.u2_pre_emp_sth = 0x41;
1004 
1005         /* {bits[4:0]=10101}: odt 45ohm tuning */
1006         u3phy->apbcfg.u2_odt_tuning = 0xb5;
1007         /* optional override of the odt 45ohm tuning */
1008         of_property_read_u32(child_np, "rockchip,odt-val-tuning", &u3phy->apbcfg.u2_odt_tuning);
1009 
1010         writel(u3phy->apbcfg.u2_pre_emp, u3phy_port->base + 0x030);
1011         writel(u3phy->apbcfg.u2_pre_emp_sth, u3phy_port->base + 0x040);
1012         writel(u3phy->apbcfg.u2_odt_tuning, u3phy_port->base + 0x11c);
1013     } else if (u3phy_port->type == U3PHY_TYPE_PIPE) {
1014         if (u3phy_port->refclk_25m_quirk) {
1015             dev_dbg(u3phy->dev, "switch to 25m refclk\n");
1016             /* ref clk switch to 25M */
1017             writel(0x64, u3phy_port->base + 0x11c);
1018             writel(0x64, u3phy_port->base + 0x028);
1019             writel(0x01, u3phy_port->base + 0x020);
1020             writel(0x21, u3phy_port->base + 0x030);
1021             writel(0x06, u3phy_port->base + 0x108);
1022             writel(0x00, u3phy_port->base + 0x118);
1023         } else {
1024             /* configure for 24M ref clk */
1025             writel(0x80, u3phy_port->base + 0x10c);
1026             writel(0x01, u3phy_port->base + 0x118);
1027             writel(0x38, u3phy_port->base + 0x11c);
1028             writel(0x83, u3phy_port->base + 0x020);
1029             writel(0x02, u3phy_port->base + 0x108);
1030         }
1031 
1032         /* Enable SSC */
1033         udelay(0x03);
1034         writel(0x08, u3phy_port->base + 0x000);
1035         writel(0x0c, u3phy_port->base + 0x120);
1036 
1037         /* Tuning Rx for compliance RJTL test */
1038         writel(0x70, u3phy_port->base + 0x150);
1039         writel(0x12, u3phy_port->base + 0x0c8);
1040         writel(0x05, u3phy_port->base + 0x148);
1041         writel(0x08, u3phy_port->base + 0x068);
1042         writel(0xf0, u3phy_port->base + 0x1c4);
1043         writel(0xff, u3phy_port->base + 0x070);
1044         writel(0x0f, u3phy_port->base + 0x06c);
1045         writel(0xe0, u3phy_port->base + 0x060);
1046 
1047         /*
1048          * Tuning Tx to increase the bias current
1049          * used in TX driver and RX EQ, it can
1050          * also increase the voltage of LFPS.
1051          */
1052         writel(0x08, u3phy_port->base + 0x180);
1053     } else {
1054         dev_err(u3phy->dev, "invalid u3phy port type\n");
1055         return -EINVAL;
1056     }
1057 
1058     return 0;
1059 }
1060 
1061 static const struct rockchip_u3phy_cfg rk3328_u3phy_cfgs[] = {{
1062     .reg = 0xff470000,
1063     .grfcfg =
1064         {
1065             .um_suspend = {0x0004, 15, 0, 0x1452, 0x15d1},
1066             .u2_only_ctrl = {0x0020, 15, 15, 0, 1},
1067             .um_ls = {0x0030, 5, 4, 0, 1},
1068             .um_hstdct = {0x0030, 7, 7, 0, 1},
1069             .ls_det_en = {0x0040, 0, 0, 0, 1},
1070             .ls_det_st = {0x0044, 0, 0, 0, 1},
1071             .pp_pwr_st = {0x0034, 14, 13, 0, 0},
1072             .pp_pwr_en = {
1073                 {0x0020, 14, 0, 0x0014, 0x0005},
1074                 {0x0020, 14, 0, 0x0014, 0x000d},
1075                 {0x0020, 14, 0, 0x0014, 0x0015},
1076                 {0x0020, 14, 0, 0x0014, 0x001d}},
1077             .u3_disable = {0x04c4, 15, 0, 0x1100, 0x101},
1078         },
1079     .phy_pipe_power = rk3328_u3phy_pipe_power,
1080     .phy_tuning = rk3328_u3phy_tuning,
1081 }, {
1082 }};
1083 
1084 static const struct of_device_id rockchip_u3phy_dt_match[] = {
1085     {.compatible = "rockchip,rk3328-u3phy", .data = &rk3328_u3phy_cfgs}, {}};
1086 MODULE_DEVICE_TABLE(of, rockchip_u3phy_dt_match);
1087 
1088 static struct platform_driver rockchip_u3phy_driver = {
1089     .probe = rockchip_u3phy_probe,
1090     .driver =
1091         {
1092             .name = "rockchip-u3phy",
1093             .of_match_table = rockchip_u3phy_dt_match,
1094         },
1095 };
1096 module_platform_driver(rockchip_u3phy_driver);
1097 
1098 MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
1099 MODULE_AUTHOR("William Wu <william.wu@rock-chips.com>");
1100 MODULE_DESCRIPTION("Rockchip USB 3.0 PHY driver");
1101 MODULE_LICENSE("GPL v2");
1102