phy-stm32-usbphyc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  2. /*
  3. * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
  4. */
  5. #define LOG_CATEGORY UCLASS_PHY
  6. #include <common.h>
  7. #include <clk.h>
  8. #include <clk-uclass.h>
  9. #include <div64.h>
  10. #include <dm.h>
  11. #include <fdtdec.h>
  12. #include <generic-phy.h>
  13. #include <log.h>
  14. #include <reset.h>
  15. #include <syscon.h>
  16. #include <usb.h>
  17. #include <asm/io.h>
  18. #include <dm/device_compat.h>
  19. #include <dm/lists.h>
  20. #include <dm/of_access.h>
  21. #include <linux/bitfield.h>
  22. #include <linux/bitops.h>
  23. #include <linux/delay.h>
  24. #include <power/regulator.h>
  25. /* USBPHYC registers */
  26. #define STM32_USBPHYC_PLL 0x0
  27. #define STM32_USBPHYC_MISC 0x8
  28. #define STM32_USBPHYC_TUNE(X) (0x10C + ((X) * 0x100))
  29. /* STM32_USBPHYC_PLL bit fields */
  30. #define PLLNDIV GENMASK(6, 0)
  31. #define PLLNDIV_SHIFT 0
  32. #define PLLFRACIN GENMASK(25, 10)
  33. #define PLLFRACIN_SHIFT 10
  34. #define PLLEN BIT(26)
  35. #define PLLSTRB BIT(27)
  36. #define PLLSTRBYP BIT(28)
  37. #define PLLFRACCTL BIT(29)
  38. #define PLLDITHEN0 BIT(30)
  39. #define PLLDITHEN1 BIT(31)
  40. /* STM32_USBPHYC_MISC bit fields */
  41. #define SWITHOST BIT(0)
  42. /* STM32_USBPHYC_TUNE bit fields */
  43. #define INCURREN BIT(0)
  44. #define INCURRINT BIT(1)
  45. #define LFSCAPEN BIT(2)
  46. #define HSDRVSLEW BIT(3)
  47. #define HSDRVDCCUR BIT(4)
  48. #define HSDRVDCLEV BIT(5)
  49. #define HSDRVCURINCR BIT(6)
  50. #define FSDRVRFADJ BIT(7)
  51. #define HSDRVRFRED BIT(8)
  52. #define HSDRVCHKITRM GENMASK(12, 9)
  53. #define HSDRVCHKZTRM GENMASK(14, 13)
  54. #define OTPCOMP GENMASK(19, 15)
  55. #define SQLCHCTL GENMASK(21, 20)
  56. #define HDRXGNEQEN BIT(22)
  57. #define HSRXOFF GENMASK(24, 23)
  58. #define HSFALLPREEM BIT(25)
  59. #define SHTCCTCTLPROT BIT(26)
  60. #define STAGSEL BIT(27)
  61. #define MAX_PHYS 2
  62. /* max 100 us for PLL lock and 100 us for PHY init */
  63. #define PLL_INIT_TIME_US 200
  64. #define PLL_PWR_DOWN_TIME_US 5
  65. #define PLL_FVCO 2880 /* in MHz */
  66. #define PLL_INFF_MIN_RATE 19200000 /* in Hz */
  67. #define PLL_INFF_MAX_RATE 38400000 /* in Hz */
  68. /* USBPHYC_CLK48 */
  69. #define USBPHYC_CLK48_FREQ 48000000 /* in Hz */
  70. enum boosting_vals {
  71. BOOST_1000_UA = 1000,
  72. BOOST_2000_UA = 2000,
  73. };
  74. enum dc_level_vals {
  75. DC_MINUS_5_TO_7_MV,
  76. DC_PLUS_5_TO_7_MV,
  77. DC_PLUS_10_TO_14_MV,
  78. DC_MAX,
  79. };
  80. enum current_trim {
  81. CUR_NOMINAL,
  82. CUR_PLUS_1_56_PCT,
  83. CUR_PLUS_3_12_PCT,
  84. CUR_PLUS_4_68_PCT,
  85. CUR_PLUS_6_24_PCT,
  86. CUR_PLUS_7_8_PCT,
  87. CUR_PLUS_9_36_PCT,
  88. CUR_PLUS_10_92_PCT,
  89. CUR_PLUS_12_48_PCT,
  90. CUR_PLUS_14_04_PCT,
  91. CUR_PLUS_15_6_PCT,
  92. CUR_PLUS_17_16_PCT,
  93. CUR_PLUS_19_01_PCT,
  94. CUR_PLUS_20_58_PCT,
  95. CUR_PLUS_22_16_PCT,
  96. CUR_PLUS_23_73_PCT,
  97. CUR_MAX,
  98. };
  99. enum impedance_trim {
  100. IMP_NOMINAL,
  101. IMP_MINUS_2_OHMS,
  102. IMP_MINUS_4_OMHS,
  103. IMP_MINUS_6_OHMS,
  104. IMP_MAX,
  105. };
  106. enum squelch_level {
  107. SQLCH_NOMINAL,
  108. SQLCH_PLUS_7_MV,
  109. SQLCH_MINUS_5_MV,
  110. SQLCH_PLUS_14_MV,
  111. SQLCH_MAX,
  112. };
  113. enum rx_offset {
  114. NO_RX_OFFSET,
  115. RX_OFFSET_PLUS_5_MV,
  116. RX_OFFSET_PLUS_10_MV,
  117. RX_OFFSET_MINUS_5_MV,
  118. RX_OFFSET_MAX,
  119. };
  120. struct pll_params {
  121. u8 ndiv;
  122. u16 frac;
  123. };
  124. struct stm32_usbphyc {
  125. fdt_addr_t base;
  126. struct clk clk;
  127. struct udevice *vdda1v1;
  128. struct udevice *vdda1v8;
  129. struct stm32_usbphyc_phy {
  130. struct udevice *vdd;
  131. struct udevice *vbus;
  132. bool init;
  133. bool powered;
  134. } phys[MAX_PHYS];
  135. int n_pll_cons;
  136. };
  137. static void stm32_usbphyc_get_pll_params(u32 clk_rate,
  138. struct pll_params *pll_params)
  139. {
  140. unsigned long long fvco, ndiv, frac;
  141. /*
  142. * | FVCO = INFF*2*(NDIV + FRACT/2^16 ) when DITHER_DISABLE[1] = 1
  143. * | FVCO = 2880MHz
  144. * | NDIV = integer part of input bits to set the LDF
  145. * | FRACT = fractional part of input bits to set the LDF
  146. * => PLLNDIV = integer part of (FVCO / (INFF*2))
  147. * => PLLFRACIN = fractional part of(FVCO / INFF*2) * 2^16
  148. * <=> PLLFRACIN = ((FVCO / (INFF*2)) - PLLNDIV) * 2^16
  149. */
  150. fvco = (unsigned long long)PLL_FVCO * 1000000; /* In Hz */
  151. ndiv = fvco;
  152. do_div(ndiv, (clk_rate * 2));
  153. pll_params->ndiv = (u8)ndiv;
  154. frac = fvco * (1 << 16);
  155. do_div(frac, (clk_rate * 2));
  156. frac = frac - (ndiv * (1 << 16));
  157. pll_params->frac = (u16)frac;
  158. }
  159. static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc)
  160. {
  161. struct pll_params pll_params;
  162. u32 clk_rate = clk_get_rate(&usbphyc->clk);
  163. u32 usbphyc_pll;
  164. if ((clk_rate < PLL_INFF_MIN_RATE) || (clk_rate > PLL_INFF_MAX_RATE)) {
  165. log_debug("input clk freq (%dHz) out of range\n",
  166. clk_rate);
  167. return -EINVAL;
  168. }
  169. stm32_usbphyc_get_pll_params(clk_rate, &pll_params);
  170. usbphyc_pll = PLLDITHEN1 | PLLDITHEN0 | PLLSTRBYP;
  171. usbphyc_pll |= ((pll_params.ndiv << PLLNDIV_SHIFT) & PLLNDIV);
  172. if (pll_params.frac) {
  173. usbphyc_pll |= PLLFRACCTL;
  174. usbphyc_pll |= ((pll_params.frac << PLLFRACIN_SHIFT)
  175. & PLLFRACIN);
  176. }
  177. writel(usbphyc_pll, usbphyc->base + STM32_USBPHYC_PLL);
  178. log_debug("input clk freq=%dHz, ndiv=%d, frac=%d\n",
  179. clk_rate, pll_params.ndiv, pll_params.frac);
  180. return 0;
  181. }
  182. static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc)
  183. {
  184. int i;
  185. for (i = 0; i < MAX_PHYS; i++) {
  186. if (usbphyc->phys[i].powered)
  187. return true;
  188. }
  189. return false;
  190. }
  191. static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
  192. {
  193. bool pllen = readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN ?
  194. true : false;
  195. int ret;
  196. /* Check if one consumer has already configured the pll */
  197. if (pllen && usbphyc->n_pll_cons) {
  198. usbphyc->n_pll_cons++;
  199. return 0;
  200. }
  201. if (usbphyc->vdda1v1) {
  202. ret = regulator_set_enable(usbphyc->vdda1v1, true);
  203. if (ret)
  204. return ret;
  205. }
  206. if (usbphyc->vdda1v8) {
  207. ret = regulator_set_enable(usbphyc->vdda1v8, true);
  208. if (ret)
  209. return ret;
  210. }
  211. if (pllen) {
  212. clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
  213. udelay(PLL_PWR_DOWN_TIME_US);
  214. }
  215. ret = stm32_usbphyc_pll_init(usbphyc);
  216. if (ret)
  217. return ret;
  218. setbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
  219. /* We must wait PLL_INIT_TIME_US before using PHY */
  220. udelay(PLL_INIT_TIME_US);
  221. if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
  222. return -EIO;
  223. usbphyc->n_pll_cons++;
  224. return 0;
  225. }
  226. static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
  227. {
  228. int ret;
  229. usbphyc->n_pll_cons--;
  230. /* Check if other consumer requires pllen */
  231. if (usbphyc->n_pll_cons)
  232. return 0;
  233. clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
  234. /*
  235. * We must wait PLL_PWR_DOWN_TIME_US before checking that PLLEN
  236. * bit is still clear
  237. */
  238. udelay(PLL_PWR_DOWN_TIME_US);
  239. if (readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)
  240. return -EIO;
  241. if (usbphyc->vdda1v1) {
  242. ret = regulator_set_enable(usbphyc->vdda1v1, false);
  243. if (ret)
  244. return ret;
  245. }
  246. if (usbphyc->vdda1v8) {
  247. ret = regulator_set_enable(usbphyc->vdda1v8, false);
  248. if (ret)
  249. return ret;
  250. }
  251. return 0;
  252. }
  253. static int stm32_usbphyc_phy_init(struct phy *phy)
  254. {
  255. struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
  256. struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
  257. int ret;
  258. dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
  259. if (usbphyc_phy->init)
  260. return 0;
  261. ret = stm32_usbphyc_pll_enable(usbphyc);
  262. if (ret)
  263. return log_ret(ret);
  264. usbphyc_phy->init = true;
  265. return 0;
  266. }
  267. static int stm32_usbphyc_phy_exit(struct phy *phy)
  268. {
  269. struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
  270. struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
  271. int ret;
  272. dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
  273. if (!usbphyc_phy->init)
  274. return 0;
  275. ret = stm32_usbphyc_pll_disable(usbphyc);
  276. usbphyc_phy->init = false;
  277. return log_ret(ret);
  278. }
  279. static int stm32_usbphyc_phy_power_on(struct phy *phy)
  280. {
  281. struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
  282. struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
  283. int ret;
  284. dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
  285. if (usbphyc_phy->vdd) {
  286. ret = regulator_set_enable(usbphyc_phy->vdd, true);
  287. if (ret)
  288. return ret;
  289. }
  290. if (usbphyc_phy->vbus) {
  291. ret = regulator_set_enable(usbphyc_phy->vbus, true);
  292. if (ret)
  293. return ret;
  294. }
  295. usbphyc_phy->powered = true;
  296. return 0;
  297. }
  298. static int stm32_usbphyc_phy_power_off(struct phy *phy)
  299. {
  300. struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
  301. struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
  302. int ret;
  303. dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
  304. usbphyc_phy->powered = false;
  305. if (stm32_usbphyc_is_powered(usbphyc))
  306. return 0;
  307. if (usbphyc_phy->vbus) {
  308. ret = regulator_set_enable_if_allowed(usbphyc_phy->vbus, false);
  309. if (ret)
  310. return ret;
  311. }
  312. if (usbphyc_phy->vdd) {
  313. ret = regulator_set_enable_if_allowed(usbphyc_phy->vdd, false);
  314. if (ret)
  315. return ret;
  316. }
  317. return 0;
  318. }
  319. static int stm32_usbphyc_get_regulator(ofnode node,
  320. char *supply_name,
  321. struct udevice **regulator)
  322. {
  323. struct ofnode_phandle_args regulator_phandle;
  324. int ret;
  325. ret = ofnode_parse_phandle_with_args(node, supply_name,
  326. NULL, 0, 0,
  327. &regulator_phandle);
  328. if (ret)
  329. return ret;
  330. ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR,
  331. regulator_phandle.node,
  332. regulator);
  333. if (ret)
  334. return ret;
  335. return 0;
  336. }
  337. static int stm32_usbphyc_of_xlate(struct phy *phy,
  338. struct ofnode_phandle_args *args)
  339. {
  340. if (args->args_count < 1)
  341. return -ENODEV;
  342. if (args->args[0] >= MAX_PHYS)
  343. return -ENODEV;
  344. phy->id = args->args[0];
  345. if ((phy->id == 0 && args->args_count != 1) ||
  346. (phy->id == 1 && args->args_count != 2)) {
  347. dev_err(phy->dev, "invalid number of cells for phy port%ld\n",
  348. phy->id);
  349. return -EINVAL;
  350. }
  351. return 0;
  352. }
  353. static void stm32_usbphyc_tuning(struct udevice *dev, ofnode node, u32 index)
  354. {
  355. struct stm32_usbphyc *usbphyc = dev_get_priv(dev);
  356. u32 reg = STM32_USBPHYC_TUNE(index);
  357. u32 otpcomp, val, tune = 0;
  358. int ret;
  359. /* Backup OTP compensation code */
  360. otpcomp = FIELD_GET(OTPCOMP, readl(usbphyc->base + reg));
  361. ret = ofnode_read_u32(node, "st,current-boost-microamp", &val);
  362. if (!ret && (val == BOOST_1000_UA || val == BOOST_2000_UA)) {
  363. val = (val == BOOST_2000_UA) ? 1 : 0;
  364. tune |= INCURREN | FIELD_PREP(INCURRINT, val);
  365. } else if (ret != -EINVAL) {
  366. dev_warn(dev, "phy%d: invalid st,current-boost-microamp value\n", index);
  367. }
  368. if (!ofnode_read_bool(node, "st,no-lsfs-fb-cap"))
  369. tune |= LFSCAPEN;
  370. if (ofnode_read_bool(node, "st,decrease-hs-slew-rate"))
  371. tune |= HSDRVSLEW;
  372. ret = ofnode_read_u32(node, "st,tune-hs-dc-level", &val);
  373. if (!ret && val < DC_MAX) {
  374. if (val == DC_MINUS_5_TO_7_MV) {
  375. tune |= HSDRVDCCUR;
  376. } else {
  377. val = (val == DC_PLUS_10_TO_14_MV) ? 1 : 0;
  378. tune |= HSDRVCURINCR | FIELD_PREP(HSDRVDCLEV, val);
  379. }
  380. } else if (ret != -EINVAL) {
  381. dev_warn(dev, "phy%d: invalid st,tune-hs-dc-level value\n", index);
  382. }
  383. if (ofnode_read_bool(node, "st,enable-fs-rftime-tuning"))
  384. tune |= FSDRVRFADJ;
  385. if (ofnode_read_bool(node, "st,enable-hs-rftime-reduction"))
  386. tune |= HSDRVRFRED;
  387. ret = ofnode_read_u32(node, "st,trim-hs-current", &val);
  388. if (!ret && val < CUR_MAX)
  389. tune |= FIELD_PREP(HSDRVCHKITRM, val);
  390. else if (ret != -EINVAL)
  391. dev_warn(dev, "phy%d: invalid st,trim-hs-current value\n", index);
  392. ret = ofnode_read_u32(node, "st,trim-hs-impedance", &val);
  393. if (!ret && val < IMP_MAX)
  394. tune |= FIELD_PREP(HSDRVCHKZTRM, val);
  395. else if (ret != -EINVAL)
  396. dev_warn(dev, "phy%d: invalid trim-hs-impedance value\n", index);
  397. ret = ofnode_read_u32(node, "st,tune-squelch-level", &val);
  398. if (!ret && val < SQLCH_MAX)
  399. tune |= FIELD_PREP(SQLCHCTL, val);
  400. else if (ret != -EINVAL)
  401. dev_warn(dev, "phy%d: invalid st,tune-squelch-level value\n", index);
  402. if (ofnode_read_bool(node, "st,enable-hs-rx-gain-eq"))
  403. tune |= HDRXGNEQEN;
  404. ret = ofnode_read_u32(node, "st,tune-hs-rx-offset", &val);
  405. if (!ret && val < RX_OFFSET_MAX)
  406. tune |= FIELD_PREP(HSRXOFF, val);
  407. else if (ret != -EINVAL)
  408. dev_warn(dev, "phy%d: invalid st,tune-hs-rx-offset value\n", index);
  409. if (ofnode_read_bool(node, "st,no-hs-ftime-ctrl"))
  410. tune |= HSFALLPREEM;
  411. if (!ofnode_read_bool(node, "st,no-lsfs-sc"))
  412. tune |= SHTCCTCTLPROT;
  413. if (ofnode_read_bool(node, "st,enable-hs-tx-staggering"))
  414. tune |= STAGSEL;
  415. /* Restore OTP compensation code */
  416. tune |= FIELD_PREP(OTPCOMP, otpcomp);
  417. writel(tune, usbphyc->base + reg);
  418. }
  419. static const struct phy_ops stm32_usbphyc_phy_ops = {
  420. .init = stm32_usbphyc_phy_init,
  421. .exit = stm32_usbphyc_phy_exit,
  422. .power_on = stm32_usbphyc_phy_power_on,
  423. .power_off = stm32_usbphyc_phy_power_off,
  424. .of_xlate = stm32_usbphyc_of_xlate,
  425. };
  426. static int stm32_usbphyc_bind(struct udevice *dev)
  427. {
  428. int ret;
  429. ret = device_bind_driver_to_node(dev, "stm32-usbphyc-clk", "ck_usbo_48m",
  430. dev_ofnode(dev), NULL);
  431. return log_ret(ret);
  432. }
  433. static int stm32_usbphyc_probe(struct udevice *dev)
  434. {
  435. struct stm32_usbphyc *usbphyc = dev_get_priv(dev);
  436. struct reset_ctl reset;
  437. ofnode node, connector;
  438. int ret;
  439. usbphyc->base = dev_read_addr(dev);
  440. if (usbphyc->base == FDT_ADDR_T_NONE)
  441. return -EINVAL;
  442. /* Enable clock */
  443. ret = clk_get_by_index(dev, 0, &usbphyc->clk);
  444. if (ret)
  445. return ret;
  446. ret = clk_enable(&usbphyc->clk);
  447. if (ret)
  448. return ret;
  449. /* Reset */
  450. ret = reset_get_by_index(dev, 0, &reset);
  451. if (!ret) {
  452. reset_assert(&reset);
  453. udelay(2);
  454. reset_deassert(&reset);
  455. }
  456. /* get usbphyc regulator */
  457. ret = device_get_supply_regulator(dev, "vdda1v1-supply",
  458. &usbphyc->vdda1v1);
  459. if (ret) {
  460. dev_err(dev, "Can't get vdda1v1-supply regulator\n");
  461. return ret;
  462. }
  463. ret = device_get_supply_regulator(dev, "vdda1v8-supply",
  464. &usbphyc->vdda1v8);
  465. if (ret) {
  466. dev_err(dev, "Can't get vdda1v8-supply regulator\n");
  467. return ret;
  468. }
  469. /* parse all PHY subnodes to populate regulator associated to each PHY port */
  470. dev_for_each_subnode(node, dev) {
  471. fdt_addr_t phy_id;
  472. struct stm32_usbphyc_phy *usbphyc_phy;
  473. phy_id = ofnode_read_u32_default(node, "reg", FDT_ADDR_T_NONE);
  474. if (phy_id >= MAX_PHYS) {
  475. dev_err(dev, "invalid reg value %llx for %s\n",
  476. (fdt64_t)phy_id, ofnode_get_name(node));
  477. return -ENOENT;
  478. }
  479. /* Configure phy tuning */
  480. stm32_usbphyc_tuning(dev, node, phy_id);
  481. usbphyc_phy = usbphyc->phys + phy_id;
  482. usbphyc_phy->init = false;
  483. usbphyc_phy->powered = false;
  484. ret = stm32_usbphyc_get_regulator(node, "phy-supply",
  485. &usbphyc_phy->vdd);
  486. if (ret) {
  487. dev_err(dev, "Can't get phy-supply regulator\n");
  488. return ret;
  489. }
  490. usbphyc_phy->vbus = NULL;
  491. connector = ofnode_find_subnode(node, "connector");
  492. if (ofnode_valid(connector)) {
  493. ret = stm32_usbphyc_get_regulator(connector, "vbus-supply",
  494. &usbphyc_phy->vbus);
  495. }
  496. }
  497. /* Check if second port has to be used for host controller */
  498. if (dev_read_bool(dev, "st,port2-switch-to-host"))
  499. setbits_le32(usbphyc->base + STM32_USBPHYC_MISC, SWITHOST);
  500. return 0;
  501. }
  502. static const struct udevice_id stm32_usbphyc_of_match[] = {
  503. { .compatible = "st,stm32mp1-usbphyc", },
  504. { },
  505. };
  506. U_BOOT_DRIVER(stm32_usb_phyc) = {
  507. .name = "stm32-usbphyc",
  508. .id = UCLASS_PHY,
  509. .of_match = stm32_usbphyc_of_match,
  510. .ops = &stm32_usbphyc_phy_ops,
  511. .bind = stm32_usbphyc_bind,
  512. .probe = stm32_usbphyc_probe,
  513. .priv_auto = sizeof(struct stm32_usbphyc),
  514. };
  515. struct stm32_usbphyc_clk {
  516. bool enable;
  517. };
  518. static ulong stm32_usbphyc_clk48_get_rate(struct clk *clk)
  519. {
  520. return USBPHYC_CLK48_FREQ;
  521. }
  522. static int stm32_usbphyc_clk48_enable(struct clk *clk)
  523. {
  524. struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev);
  525. struct stm32_usbphyc *usbphyc;
  526. int ret;
  527. if (usbphyc_clk->enable)
  528. return 0;
  529. usbphyc = dev_get_priv(clk->dev->parent);
  530. /* ck_usbo_48m is generated by usbphyc PLL */
  531. ret = stm32_usbphyc_pll_enable(usbphyc);
  532. if (ret)
  533. return ret;
  534. usbphyc_clk->enable = true;
  535. return 0;
  536. }
  537. static int stm32_usbphyc_clk48_disable(struct clk *clk)
  538. {
  539. struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev);
  540. struct stm32_usbphyc *usbphyc;
  541. int ret;
  542. if (!usbphyc_clk->enable)
  543. return 0;
  544. usbphyc = dev_get_priv(clk->dev->parent);
  545. ret = stm32_usbphyc_pll_disable(usbphyc);
  546. if (ret)
  547. return ret;
  548. usbphyc_clk->enable = false;
  549. return 0;
  550. }
  551. const struct clk_ops usbphyc_clk48_ops = {
  552. .get_rate = stm32_usbphyc_clk48_get_rate,
  553. .enable = stm32_usbphyc_clk48_enable,
  554. .disable = stm32_usbphyc_clk48_disable,
  555. };
  556. U_BOOT_DRIVER(stm32_usb_phyc_clk) = {
  557. .name = "stm32-usbphyc-clk",
  558. .id = UCLASS_CLK,
  559. .ops = &usbphyc_clk48_ops,
  560. .priv_auto = sizeof(struct stm32_usbphyc_clk),
  561. };