phy-rockchip-inno-usb2.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Rockchip USB2.0 PHY with Innosilicon IP block driver
  4. *
  5. * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
  6. * Copyright (C) 2020 Amarula Solutions(India)
  7. */
  8. #include <common.h>
  9. #include <clk-uclass.h>
  10. #include <dm.h>
  11. #include <asm/global_data.h>
  12. #include <dm/device_compat.h>
  13. #include <dm/device-internal.h>
  14. #include <dm/lists.h>
  15. #include <generic-phy.h>
  16. #include <reset.h>
  17. #include <syscon.h>
  18. #include <asm/gpio.h>
  19. #include <asm/io.h>
  20. #include <linux/iopoll.h>
  21. #include <asm/arch-rockchip/clock.h>
  22. DECLARE_GLOBAL_DATA_PTR;
  23. #define usleep_range(a, b) udelay((b))
  24. #define BIT_WRITEABLE_SHIFT 16
  25. enum rockchip_usb2phy_port_id {
  26. USB2PHY_PORT_OTG,
  27. USB2PHY_PORT_HOST,
  28. USB2PHY_NUM_PORTS,
  29. };
  30. struct usb2phy_reg {
  31. unsigned int offset;
  32. unsigned int bitend;
  33. unsigned int bitstart;
  34. unsigned int disable;
  35. unsigned int enable;
  36. };
  37. struct rockchip_usb2phy_port_cfg {
  38. struct usb2phy_reg phy_sus;
  39. struct usb2phy_reg bvalid_det_en;
  40. struct usb2phy_reg bvalid_det_st;
  41. struct usb2phy_reg bvalid_det_clr;
  42. struct usb2phy_reg ls_det_en;
  43. struct usb2phy_reg ls_det_st;
  44. struct usb2phy_reg ls_det_clr;
  45. struct usb2phy_reg utmi_avalid;
  46. struct usb2phy_reg utmi_bvalid;
  47. struct usb2phy_reg utmi_ls;
  48. struct usb2phy_reg utmi_hstdet;
  49. };
  50. struct rockchip_usb2phy_cfg {
  51. unsigned int reg;
  52. struct usb2phy_reg clkout_ctl;
  53. const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS];
  54. };
  55. struct rockchip_usb2phy {
  56. void *reg_base;
  57. struct clk phyclk;
  58. const struct rockchip_usb2phy_cfg *phy_cfg;
  59. };
  60. static inline int property_enable(void *reg_base,
  61. const struct usb2phy_reg *reg, bool en)
  62. {
  63. unsigned int val, mask, tmp;
  64. tmp = en ? reg->enable : reg->disable;
  65. mask = GENMASK(reg->bitend, reg->bitstart);
  66. val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
  67. return writel(val, reg_base + reg->offset);
  68. }
  69. static inline bool property_enabled(void *reg_base,
  70. const struct usb2phy_reg *reg)
  71. {
  72. unsigned int tmp, orig;
  73. unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
  74. orig = readl(reg_base + reg->offset);
  75. tmp = (orig & mask) >> reg->bitstart;
  76. return tmp != reg->disable;
  77. }
  78. static const
  79. struct rockchip_usb2phy_port_cfg *us2phy_get_port(struct phy *phy)
  80. {
  81. struct udevice *parent = dev_get_parent(phy->dev);
  82. struct rockchip_usb2phy *priv = dev_get_priv(parent);
  83. const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg;
  84. return &phy_cfg->port_cfgs[phy->id];
  85. }
  86. static int rockchip_usb2phy_power_on(struct phy *phy)
  87. {
  88. struct udevice *parent = dev_get_parent(phy->dev);
  89. struct rockchip_usb2phy *priv = dev_get_priv(parent);
  90. const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
  91. property_enable(priv->reg_base, &port_cfg->phy_sus, false);
  92. /* waiting for the utmi_clk to become stable */
  93. usleep_range(1500, 2000);
  94. return 0;
  95. }
  96. static int rockchip_usb2phy_power_off(struct phy *phy)
  97. {
  98. struct udevice *parent = dev_get_parent(phy->dev);
  99. struct rockchip_usb2phy *priv = dev_get_priv(parent);
  100. const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
  101. property_enable(priv->reg_base, &port_cfg->phy_sus, true);
  102. return 0;
  103. }
  104. static int rockchip_usb2phy_init(struct phy *phy)
  105. {
  106. struct udevice *parent = dev_get_parent(phy->dev);
  107. struct rockchip_usb2phy *priv = dev_get_priv(parent);
  108. const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
  109. int ret;
  110. ret = clk_enable(&priv->phyclk);
  111. if (ret && ret != -ENOSYS) {
  112. dev_err(phy->dev, "failed to enable phyclk (ret=%d)\n", ret);
  113. return ret;
  114. }
  115. if (phy->id == USB2PHY_PORT_OTG) {
  116. property_enable(priv->reg_base, &port_cfg->bvalid_det_clr, true);
  117. property_enable(priv->reg_base, &port_cfg->bvalid_det_en, true);
  118. } else if (phy->id == USB2PHY_PORT_HOST) {
  119. property_enable(priv->reg_base, &port_cfg->bvalid_det_clr, true);
  120. property_enable(priv->reg_base, &port_cfg->bvalid_det_en, true);
  121. }
  122. return 0;
  123. }
  124. static int rockchip_usb2phy_exit(struct phy *phy)
  125. {
  126. struct udevice *parent = dev_get_parent(phy->dev);
  127. struct rockchip_usb2phy *priv = dev_get_priv(parent);
  128. clk_disable(&priv->phyclk);
  129. return 0;
  130. }
  131. static int rockchip_usb2phy_of_xlate(struct phy *phy,
  132. struct ofnode_phandle_args *args)
  133. {
  134. const char *name = phy->dev->name;
  135. if (!strcasecmp(name, "host-port"))
  136. phy->id = USB2PHY_PORT_HOST;
  137. else if (!strcasecmp(name, "otg-port"))
  138. phy->id = USB2PHY_PORT_OTG;
  139. else
  140. dev_err(phy->dev, "improper %s device\n", name);
  141. return 0;
  142. }
  143. static struct phy_ops rockchip_usb2phy_ops = {
  144. .init = rockchip_usb2phy_init,
  145. .exit = rockchip_usb2phy_exit,
  146. .power_on = rockchip_usb2phy_power_on,
  147. .power_off = rockchip_usb2phy_power_off,
  148. .of_xlate = rockchip_usb2phy_of_xlate,
  149. };
  150. /**
  151. * round_rate() - Adjust a rate to the exact rate a clock can provide.
  152. * @clk: The clock to manipulate.
  153. * @rate: Desidered clock rate in Hz.
  154. *
  155. * Return: rounded rate in Hz, or -ve error code.
  156. */
  157. ulong rockchip_usb2phy_clk_round_rate(struct clk *clk, ulong rate)
  158. {
  159. return 480000000;
  160. }
  161. /**
  162. * enable() - Enable a clock.
  163. * @clk: The clock to manipulate.
  164. *
  165. * Return: zero on success, or -ve error code.
  166. */
  167. int rockchip_usb2phy_clk_enable(struct clk *clk)
  168. {
  169. struct udevice *parent = dev_get_parent(clk->dev);
  170. struct rockchip_usb2phy *priv = dev_get_priv(parent);
  171. const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg;
  172. /* turn on 480m clk output if it is off */
  173. if (!property_enabled(priv->reg_base, &phy_cfg->clkout_ctl)) {
  174. property_enable(priv->reg_base, &phy_cfg->clkout_ctl, true);
  175. /* waiting for the clk become stable */
  176. usleep_range(1200, 1300);
  177. }
  178. return 0;
  179. }
  180. /**
  181. * disable() - Disable a clock.
  182. * @clk: The clock to manipulate.
  183. *
  184. * Return: zero on success, or -ve error code.
  185. */
  186. int rockchip_usb2phy_clk_disable(struct clk *clk)
  187. {
  188. struct udevice *parent = dev_get_parent(clk->dev);
  189. struct rockchip_usb2phy *priv = dev_get_priv(parent);
  190. const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg;
  191. /* turn off 480m clk output */
  192. property_enable(priv->reg_base, &phy_cfg->clkout_ctl, false);
  193. return 0;
  194. }
  195. static struct clk_ops rockchip_usb2phy_clk_ops = {
  196. .enable = rockchip_usb2phy_clk_enable,
  197. .disable = rockchip_usb2phy_clk_disable,
  198. .round_rate = rockchip_usb2phy_clk_round_rate
  199. };
  200. static int rockchip_usb2phy_probe(struct udevice *dev)
  201. {
  202. struct rockchip_usb2phy *priv = dev_get_priv(dev);
  203. const struct rockchip_usb2phy_cfg *phy_cfgs;
  204. unsigned int reg;
  205. int index, ret;
  206. priv->reg_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
  207. if (IS_ERR(priv->reg_base))
  208. return PTR_ERR(priv->reg_base);
  209. ret = ofnode_read_u32_index(dev_ofnode(dev), "reg", 0, &reg);
  210. if (ret) {
  211. dev_err(dev, "failed to read reg property (ret = %d)\n", ret);
  212. return ret;
  213. }
  214. /* support address_cells=2 */
  215. if (dev_read_addr_cells(dev) == 2 && reg == 0) {
  216. if (ofnode_read_u32_index(dev_ofnode(dev), "reg", 1, &reg)) {
  217. dev_err(dev, "%s must have reg[1]\n",
  218. ofnode_get_name(dev_ofnode(dev)));
  219. return -EINVAL;
  220. }
  221. }
  222. phy_cfgs = (const struct rockchip_usb2phy_cfg *)
  223. dev_get_driver_data(dev);
  224. if (!phy_cfgs)
  225. return -EINVAL;
  226. /* find out a proper config which can be matched with dt. */
  227. index = 0;
  228. do {
  229. if (phy_cfgs[index].reg == reg) {
  230. priv->phy_cfg = &phy_cfgs[index];
  231. break;
  232. }
  233. ++index;
  234. } while (phy_cfgs[index].reg);
  235. if (!priv->phy_cfg) {
  236. dev_err(dev, "failed find proper phy-cfg\n");
  237. return -EINVAL;
  238. }
  239. ret = clk_get_by_name(dev, "phyclk", &priv->phyclk);
  240. if (ret) {
  241. dev_err(dev, "failed to get the phyclk (ret=%d)\n", ret);
  242. return ret;
  243. }
  244. return 0;
  245. }
  246. static int rockchip_usb2phy_bind(struct udevice *dev)
  247. {
  248. struct udevice *usb2phy_dev;
  249. ofnode node;
  250. const char *name;
  251. int ret = 0;
  252. dev_for_each_subnode(node, dev) {
  253. if (!ofnode_valid(node)) {
  254. dev_info(dev, "subnode %s not found\n", dev->name);
  255. ret = -ENXIO;
  256. goto bind_fail;
  257. }
  258. name = ofnode_get_name(node);
  259. dev_dbg(dev, "subnode %s\n", name);
  260. ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_port",
  261. name, node, &usb2phy_dev);
  262. if (ret) {
  263. dev_err(dev,
  264. "'%s' cannot bind 'rockchip_usb2phy_port'\n", name);
  265. goto bind_fail;
  266. }
  267. }
  268. node = dev_ofnode(dev);
  269. name = "clk_usbphy_480m";
  270. dev_read_string_index(dev, "clock-output-names", 0, &name);
  271. dev_dbg(dev, "clk %s for node %s\n", name, ofnode_get_name(node));
  272. ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_clock",
  273. name, node, &usb2phy_dev);
  274. if (ret) {
  275. dev_err(dev,
  276. "'%s' cannot bind 'rockchip_usb2phy_clock'\n", name);
  277. goto bind_fail;
  278. }
  279. return 0;
  280. bind_fail:
  281. device_chld_unbind(dev, NULL);
  282. return ret;
  283. }
  284. static const struct rockchip_usb2phy_cfg rk3328_usb2phy_cfgs[] = {
  285. {
  286. .reg = 0x100,
  287. .clkout_ctl = { 0x108, 4, 4, 1, 0 },
  288. .port_cfgs = {
  289. [USB2PHY_PORT_OTG] = {
  290. .phy_sus = { 0x0100, 15, 0, 0, 0x1d1 },
  291. .bvalid_det_en = { 0x0110, 3, 2, 0, 3 },
  292. .bvalid_det_st = { 0x0114, 3, 2, 0, 3 },
  293. .bvalid_det_clr = { 0x0118, 3, 2, 0, 3 },
  294. .ls_det_en = { 0x0110, 0, 0, 0, 1 },
  295. .ls_det_st = { 0x0114, 0, 0, 0, 1 },
  296. .ls_det_clr = { 0x0118, 0, 0, 0, 1 },
  297. .utmi_avalid = { 0x0120, 10, 10, 0, 1 },
  298. .utmi_bvalid = { 0x0120, 9, 9, 0, 1 },
  299. .utmi_ls = { 0x0120, 5, 4, 0, 1 },
  300. },
  301. [USB2PHY_PORT_HOST] = {
  302. .phy_sus = { 0x104, 15, 0, 0, 0x1d1 },
  303. .ls_det_en = { 0x110, 1, 1, 0, 1 },
  304. .ls_det_st = { 0x114, 1, 1, 0, 1 },
  305. .ls_det_clr = { 0x118, 1, 1, 0, 1 },
  306. .utmi_ls = { 0x120, 17, 16, 0, 1 },
  307. .utmi_hstdet = { 0x120, 19, 19, 0, 1 }
  308. }
  309. },
  310. },
  311. { /* sentinel */ }
  312. };
  313. static const struct rockchip_usb2phy_cfg rk3399_usb2phy_cfgs[] = {
  314. {
  315. .reg = 0xe450,
  316. .clkout_ctl = { 0xe450, 4, 4, 1, 0 },
  317. .port_cfgs = {
  318. [USB2PHY_PORT_OTG] = {
  319. .phy_sus = { 0xe454, 1, 0, 2, 1 },
  320. .bvalid_det_en = { 0xe3c0, 3, 3, 0, 1 },
  321. .bvalid_det_st = { 0xe3e0, 3, 3, 0, 1 },
  322. .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 },
  323. .utmi_avalid = { 0xe2ac, 7, 7, 0, 1 },
  324. .utmi_bvalid = { 0xe2ac, 12, 12, 0, 1 },
  325. },
  326. [USB2PHY_PORT_HOST] = {
  327. .phy_sus = { 0xe458, 1, 0, 0x2, 0x1 },
  328. .ls_det_en = { 0xe3c0, 6, 6, 0, 1 },
  329. .ls_det_st = { 0xe3e0, 6, 6, 0, 1 },
  330. .ls_det_clr = { 0xe3d0, 6, 6, 0, 1 },
  331. .utmi_ls = { 0xe2ac, 22, 21, 0, 1 },
  332. .utmi_hstdet = { 0xe2ac, 23, 23, 0, 1 }
  333. }
  334. },
  335. },
  336. {
  337. .reg = 0xe460,
  338. .clkout_ctl = { 0xe460, 4, 4, 1, 0 },
  339. .port_cfgs = {
  340. [USB2PHY_PORT_OTG] = {
  341. .phy_sus = { 0xe464, 1, 0, 2, 1 },
  342. .bvalid_det_en = { 0xe3c0, 8, 8, 0, 1 },
  343. .bvalid_det_st = { 0xe3e0, 8, 8, 0, 1 },
  344. .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
  345. .utmi_avalid = { 0xe2ac, 10, 10, 0, 1 },
  346. .utmi_bvalid = { 0xe2ac, 16, 16, 0, 1 },
  347. },
  348. [USB2PHY_PORT_HOST] = {
  349. .phy_sus = { 0xe468, 1, 0, 0x2, 0x1 },
  350. .ls_det_en = { 0xe3c0, 11, 11, 0, 1 },
  351. .ls_det_st = { 0xe3e0, 11, 11, 0, 1 },
  352. .ls_det_clr = { 0xe3d0, 11, 11, 0, 1 },
  353. .utmi_ls = { 0xe2ac, 26, 25, 0, 1 },
  354. .utmi_hstdet = { 0xe2ac, 27, 27, 0, 1 }
  355. }
  356. },
  357. },
  358. { /* sentinel */ }
  359. };
  360. static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
  361. {
  362. .reg = 0xfe8a0000,
  363. .clkout_ctl = { 0x0008, 4, 4, 1, 0 },
  364. .port_cfgs = {
  365. [USB2PHY_PORT_OTG] = {
  366. .phy_sus = { 0x0000, 8, 0, 0x052, 0x1d1 },
  367. .bvalid_det_en = { 0x0080, 2, 2, 0, 1 },
  368. .bvalid_det_st = { 0x0084, 2, 2, 0, 1 },
  369. .bvalid_det_clr = { 0x0088, 2, 2, 0, 1 },
  370. .ls_det_en = { 0x0080, 0, 0, 0, 1 },
  371. .ls_det_st = { 0x0084, 0, 0, 0, 1 },
  372. .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
  373. .utmi_avalid = { 0x00c0, 10, 10, 0, 1 },
  374. .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 },
  375. .utmi_ls = { 0x00c0, 5, 4, 0, 1 },
  376. },
  377. [USB2PHY_PORT_HOST] = {
  378. .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 },
  379. .ls_det_en = { 0x0080, 1, 1, 0, 1 },
  380. .ls_det_st = { 0x0084, 1, 1, 0, 1 },
  381. .ls_det_clr = { 0x0088, 1, 1, 0, 1 },
  382. .utmi_ls = { 0x00c0, 17, 16, 0, 1 },
  383. .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 }
  384. }
  385. },
  386. },
  387. {
  388. .reg = 0xfe8b0000,
  389. .clkout_ctl = { 0x0008, 4, 4, 1, 0 },
  390. .port_cfgs = {
  391. [USB2PHY_PORT_OTG] = {
  392. .phy_sus = { 0x0000, 8, 0, 0x1d2, 0x1d1 },
  393. .ls_det_en = { 0x0080, 0, 0, 0, 1 },
  394. .ls_det_st = { 0x0084, 0, 0, 0, 1 },
  395. .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
  396. .utmi_ls = { 0x00c0, 5, 4, 0, 1 },
  397. .utmi_hstdet = { 0x00c0, 7, 7, 0, 1 }
  398. },
  399. [USB2PHY_PORT_HOST] = {
  400. .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 },
  401. .ls_det_en = { 0x0080, 1, 1, 0, 1 },
  402. .ls_det_st = { 0x0084, 1, 1, 0, 1 },
  403. .ls_det_clr = { 0x0088, 1, 1, 0, 1 },
  404. .utmi_ls = { 0x00c0, 17, 16, 0, 1 },
  405. .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 }
  406. }
  407. },
  408. },
  409. { /* sentinel */ }
  410. };
  411. static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
  412. {
  413. .reg = 0x0000,
  414. .port_cfgs = {
  415. [USB2PHY_PORT_OTG] = {
  416. .phy_sus = { 0x000c, 11, 11, 0, 1 },
  417. .ls_det_en = { 0x0080, 0, 0, 0, 1 },
  418. .ls_det_st = { 0x0084, 0, 0, 0, 1 },
  419. .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
  420. .utmi_ls = { 0x00c0, 10, 9, 0, 1 },
  421. }
  422. },
  423. },
  424. {
  425. .reg = 0x4000,
  426. .port_cfgs = {
  427. [USB2PHY_PORT_OTG] = {
  428. .phy_sus = { 0x000c, 11, 11, 0, 0 },
  429. .ls_det_en = { 0x0080, 0, 0, 0, 1 },
  430. .ls_det_st = { 0x0084, 0, 0, 0, 1 },
  431. .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
  432. .utmi_ls = { 0x00c0, 10, 9, 0, 1 },
  433. }
  434. },
  435. },
  436. {
  437. .reg = 0x8000,
  438. .port_cfgs = {
  439. [USB2PHY_PORT_HOST] = {
  440. .phy_sus = { 0x0008, 2, 2, 0, 1 },
  441. .ls_det_en = { 0x0080, 0, 0, 0, 1 },
  442. .ls_det_st = { 0x0084, 0, 0, 0, 1 },
  443. .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
  444. .utmi_ls = { 0x00c0, 10, 9, 0, 1 },
  445. }
  446. },
  447. },
  448. {
  449. .reg = 0xc000,
  450. .port_cfgs = {
  451. [USB2PHY_PORT_HOST] = {
  452. .phy_sus = { 0x0008, 2, 2, 0, 1 },
  453. .ls_det_en = { 0x0080, 0, 0, 0, 1 },
  454. .ls_det_st = { 0x0084, 0, 0, 0, 1 },
  455. .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
  456. .utmi_ls = { 0x00c0, 10, 9, 0, 1 },
  457. }
  458. },
  459. },
  460. { /* sentinel */ }
  461. };
  462. static const struct udevice_id rockchip_usb2phy_ids[] = {
  463. {
  464. .compatible = "rockchip,rk3328-usb2phy",
  465. .data = (ulong)&rk3328_usb2phy_cfgs,
  466. },
  467. {
  468. .compatible = "rockchip,rk3399-usb2phy",
  469. .data = (ulong)&rk3399_usb2phy_cfgs,
  470. },
  471. {
  472. .compatible = "rockchip,rk3568-usb2phy",
  473. .data = (ulong)&rk3568_phy_cfgs,
  474. },
  475. {
  476. .compatible = "rockchip,rk3588-usb2phy",
  477. .data = (ulong)&rk3588_phy_cfgs,
  478. },
  479. { /* sentinel */ }
  480. };
  481. U_BOOT_DRIVER(rockchip_usb2phy_port) = {
  482. .name = "rockchip_usb2phy_port",
  483. .id = UCLASS_PHY,
  484. .ops = &rockchip_usb2phy_ops,
  485. };
  486. U_BOOT_DRIVER(rockchip_usb2phy_clock) = {
  487. .name = "rockchip_usb2phy_clock",
  488. .id = UCLASS_CLK,
  489. .ops = &rockchip_usb2phy_clk_ops,
  490. };
  491. U_BOOT_DRIVER(rockchip_usb2phy) = {
  492. .name = "rockchip_usb2phy",
  493. .id = UCLASS_PHY,
  494. .of_match = rockchip_usb2phy_ids,
  495. .probe = rockchip_usb2phy_probe,
  496. .bind = rockchip_usb2phy_bind,
  497. .priv_auto = sizeof(struct rockchip_usb2phy),
  498. };