phy-dw-mipi-dphy.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * DesignWare MIPI DSI DPHY driver
  4. */
  5. #include <linux/bitfield.h>
  6. #include <linux/clk.h>
  7. #include <linux/mfd/syscon.h>
  8. #include <linux/module.h>
  9. #include <linux/mod_devicetable.h>
  10. #include <linux/of.h>
  11. #include <linux/phy/phy.h>
  12. #include <linux/phy/phy-mipi-dphy.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/regmap.h>
  15. /* ----------------------------- DPHY registers --------------------- */
  16. #define DW_PHY_TMR_LPCLK_CFG 0x98
  17. #define PHY_TMR_LPCLK_CFG_PHY_CLKHS2LP_TIME GENMASK(25, 16)
  18. #define PHY_TMR_LPCLK_CFG_PHY_CLKLP2HS_TIME GENMASK( 9, 0)
  19. #define DW_PHY_TMR_CFG 0x9c
  20. #define PHY_TMR_CFG_PHY_HS2LP_TIME GENMASK(25, 16)
  21. #define PHY_TMR_CFG_PHY_LP2HS_TIME GENMASK( 9, 0)
  22. #define DW_PHY_RSTZ 0xa0
  23. #define PHY_RSTZ_PHY_FORCEPLL BIT(3)
  24. #define PHY_RSTZ_PHY_ENABLECLK BIT(2)
  25. #define PHY_RSTZ_PHY_RSTZ BIT(1)
  26. #define PHY_RSTZ_PHY_SHUTDOWNZ BIT(0)
  27. #define DW_PHY_IF_CFG 0xa4
  28. #define PHY_IF_CFG_PHY_STOP_WAIT_TIME GENMASK(15, 8)
  29. #define PHY_IF_CFG_N_LANES GENMASK( 1, 0)
  30. #define DW_PHY_ULPS_CTRL 0xa8
  31. #define PHY_ULPS_CTRL_PHY_TXEXITULPSLAN BIT(3)
  32. #define PHY_ULPS_CTRL_PHY_TXREQULPSLAN BIT(2)
  33. #define PHY_ULPS_CTRL_PHY_TXEXITULPSCLK BIT(1)
  34. #define PHY_ULPS_CTRL_PHY_TXREQULPSCLK BIT(0)
  35. #define DW_PHY_TX_TRIGGERS 0xac
  36. #define PHY_TX_TRIGGERS_PHY_TX_TRIGGERS GENMASK( 3, 0)
  37. #define DW_PHY_STATUS 0xb0
  38. #define PHY_STATUS_PHY_ULPSACTIVENOT3LANE BIT(12)
  39. #define PHY_STATUS_PHY_STOPSTATE3LANE BIT(11)
  40. #define PHY_STATUS_PHY_ULPSACTIVENOT2LANE BIT(10)
  41. #define PHY_STATUS_PHY_STOPSTATE2LANE BIT(9)
  42. #define PHY_STATUS_PHY_ULPSACTIVENOT1LANE BIT(8)
  43. #define PHY_STATUS_PHY_STOPSTATE1LANE BIT(7)
  44. #define PHY_STATUS_PHY_RXULPSESC0LANE BIT(6)
  45. #define PHY_STATUS_PHY_ULPSACTIVENOT0LANE BIT(5)
  46. #define PHY_STATUS_PHY_STOPSTATE0LANE BIT(4)
  47. #define PHY_STATUS_PHY_ULPSACTIVENOTCLK BIT(3)
  48. #define PHY_STATUS_PHY_STOPSTATE_CLKLANE BIT(2)
  49. #define PHY_STATUS_PHY_DIRECTION BIT(1)
  50. #define PHY_STATUS_PHY_LOCK BIT(0)
  51. #define DW_PHY_TST_CTRL0 0xb4
  52. #define PHY_TST_CTRL0_TESTCLK BIT(1)
  53. #define PHY_TST_CTRL0_TESTCLR BIT(0)
  54. #define DW_PHY_TST_CTRL1 0xb8
  55. #define PHY_TST_CTRL1_TESTEN BIT(16)
  56. #define TESTEN_WRITEADDR 0x1
  57. #define TESTEN_WRITEDATA 0x0
  58. #define PHY_TST_CTRL1_TESTOUT GENMASK(15, 8)
  59. #define PHY_TST_CTRL1_TESTIN GENMASK( 7, 0)
  60. #define DW_PHY_CAL 0xcc
  61. #define PHY_CAL_TXSKEWCALHS BIT(0)
  62. #define DW_PHY_TMR_RD_CFG 0xf4
  63. #define PHY_TMR_RD_CFG_MAX_RD_TIME GENMASK(14, 0)
  64. /* -------------------------- DPHY Test Code ------------------------ */
  65. #define TC_PLL_DELAY_LP_TX_START_LP11 0x02
  66. #define TXDINDLYTIME_9_2 GENMASK( 7, 0)
  67. #define TC_PLL_FSM_CNTRL 0x03
  68. #define TC_PLL_PROP_CHARGE_PUMP_CTRL 0x0e
  69. #define PLL_PROP_CNTRL GENMASK( 5, 0)
  70. #define TC_PLL_INT_CHARGE_PUMP_CTRL 0x0f
  71. #define PLL_INT_CNTRL GENMASK( 5, 0)
  72. #define TC_PLL_VCO_CTRL 0x12
  73. #define PLL_VCO_CNTRL_OVR_EN BIT(6)
  74. #define PLL_VCO_CNTRL_OVR GENMASK( 5, 0)
  75. #define TC_PLL_GMP_CTRL_DIGITAL_TEST 0x13
  76. #define PLL_TESTLOCK BIT(7)
  77. #define PLL_GMP_CNTRL GENMASK( 5, 4)
  78. #define TSTPLLDIG GENMASK( 3, 1)
  79. #define TSTPLLDIG_LOCK 0x0
  80. #define TSTPLLDIG_REFCLK 0x1
  81. #define TSTPLLDIG_FBCLK 0x2
  82. #define TSTPLLDIG_INT_CLKIN 0x3
  83. #define TSTPLLDIG_LOCK_FROM_DETECTOR 0x4
  84. #define TSTPLLDIG_OUTPUT 0x5
  85. #define TSTPLLDIG_BUF_VCOCLK 0x6
  86. #define TSTPLLDIG_UPDATEPLL 0x7
  87. #define TC_PLL_N_DIV_FSM_SIG 0x17
  88. #define PLL_N_OVR GENMASK( 3, 0)
  89. #define TC_PLL_M_DIV 0x18
  90. #define PLL_M_OVR_4_0 GENMASK( 4, 0)
  91. #define PLL_M_OVR_9_5 GENMASK( 4, 0)
  92. #define TC_PLL_N_AND_M_DIV_CTRL 0x19
  93. #define PLL_M_OVR_EN BIT(5)
  94. #define PLL_N_OVR_EN BIT(4)
  95. #define TC_PLL_CHARGE_PUMP_BIAS_CTRL 0x1c
  96. #define PLL_CPBIAS_CNTRL GENMASK( 6, 0)
  97. #define TC_PLL_ANALOG_PROGRAM_CONTROL 0x1f
  98. #define PLL_MPLL_PROG_5_0 GENMASK( 5, 0)
  99. #define PLL_MPLL_PROG_11_6 GENMASK( 5, 0)
  100. #define PLL_MPLL_PROG_16_12 GENMASK( 4, 0)
  101. #define TC_HS_FREQ_RANGE_OF_OPERATION 0x44
  102. #define HSFREQRANGE_OVR_EN BIT(7)
  103. #define HSFREQRANGE_OVR GENMASK( 6, 0)
  104. #define HSFREQRANGE HSFREQRANGE_OVR
  105. #define TC_PG_LP_BIAS_LANE0 0x4a
  106. #define PRG_ON_LANE0 BIT(6)
  107. #define TC_SR_FSM_OVR_CNTRL 0xa0
  108. #define TC_SR_DDL_LOOP_CONF 0xa3
  109. /* ---------------------------------- PLL ------------------------------- */
  110. #define FCLKIN_FREQ_MIN 2000UL /* in KHz */
  111. #define FCLKIN_FREQ_MAX 64000UL
  112. #define FOUT_FREQ_MIN 40000UL
  113. #define FOUT_FREQ_MAX 1250000UL
  114. #define CFGCLK_FREQ_MIN 17000UL
  115. #define CFGCLK_FREQ_MAX 27000UL
  116. #define INPUT_DIV_MIN 1
  117. #define INPUT_DIV_MAX 16
  118. #define LOOP_DIV_MIN 64
  119. #define LOOP_DIV_MAX 625
  120. #define FIN_DIV_N_FREQ_MIN 2
  121. #define FIN_DIV_N_FREQ_MAX 4
  122. /* --------------------------------- VOSYS ------------------------------ */
  123. #define VOSYS_MIPIDSI0_SYSREG 0x74
  124. #define VOSYS_MIPIDSI1_SYSREG 0x78
  125. #define MIPIDSI_HSFREQRANGE GENMASK( 9, 3)
  126. #define MIPIDSI_CFGCLKFREQRANGE GENMASK(15, 10)
  127. struct dw_pll_range {
  128. u32 data_rate;
  129. u8 hsfreqrange;
  130. u8 vco_range;
  131. u16 clk_lp2hs;
  132. u16 clk_hs2lp;
  133. u16 data_lp2hs;
  134. u16 data_hs2lp;
  135. };
  136. struct dw_dphy_cfg {
  137. unsigned long hs_clk_rate;
  138. u8 hsfreqrange;
  139. u8 cfgclkfreqrange;
  140. u8 vco_range;
  141. u8 n_div;
  142. u8 m_div;
  143. u16 clk_lp2hs;
  144. u16 clk_hs2lp;
  145. u16 data_lp2hs;
  146. u16 data_hs2lp;
  147. };
  148. struct dw_dphy {
  149. struct phy *phy;
  150. struct device *dev;
  151. struct dw_dphy_cfg cfg;
  152. struct regmap *regmap;
  153. struct regmap *vosys_regmap;
  154. struct clk *refclk; /* PLL reference clock */
  155. struct clk *cfgclk; /* DPHY configure clock */
  156. struct clk *pclk; /* APB slave bus clock */
  157. struct clk *prefclk;
  158. struct clk *pcfgclk;
  159. };
  160. #define dw_fill_range(r, f, v, cl, ch, dl, dh) { \
  161. .data_rate = r, \
  162. .hsfreqrange = f, \
  163. .vco_range = v, \
  164. .clk_lp2hs = cl, \
  165. .clk_hs2lp = ch, \
  166. .data_lp2hs = dl, \
  167. .data_hs2lp = dh \
  168. }
  169. static const struct dw_pll_range pll_range_table[] = {
  170. dw_fill_range(80, 0x00, 0x3F, 21, 17, 15, 10),
  171. dw_fill_range(90, 0x10, 0x3F, 23, 17, 16, 10),
  172. dw_fill_range(100, 0x20, 0x3F, 22, 17, 16, 10),
  173. dw_fill_range(110, 0x30, 0x39, 25, 18, 17, 11),
  174. dw_fill_range(120, 0x01, 0x39, 26, 20, 18, 11),
  175. dw_fill_range(130, 0x11, 0x39, 27, 19, 19, 11),
  176. dw_fill_range(140, 0x21, 0x39, 27, 19, 19, 11),
  177. dw_fill_range(150, 0x31, 0x39, 28, 20, 20, 12),
  178. dw_fill_range(160, 0x02, 0x39, 30, 21, 22, 13),
  179. dw_fill_range(170, 0x12, 0x2F, 30, 21, 23, 13),
  180. dw_fill_range(180, 0x22, 0x2F, 31, 21, 23, 13),
  181. dw_fill_range(190, 0x32, 0x2F, 32, 22, 24, 13),
  182. dw_fill_range(205, 0x03, 0x2F, 35, 22, 25, 13),
  183. dw_fill_range(220, 0x13, 0x29, 37, 26, 27, 15),
  184. dw_fill_range(235, 0x23, 0x29, 38, 28, 27, 16),
  185. dw_fill_range(250, 0x33, 0x29, 41, 29, 30, 17),
  186. dw_fill_range(275, 0x04, 0x29, 43, 29, 32, 18),
  187. dw_fill_range(300, 0x14, 0x29, 45, 32, 35, 19),
  188. dw_fill_range(325, 0x25, 0x29, 48, 33, 36, 18),
  189. dw_fill_range(350, 0x35, 0x1F, 51, 35, 40, 20),
  190. dw_fill_range(400, 0x05, 0x1F, 59, 37, 44, 21),
  191. dw_fill_range(450, 0x16, 0x19, 65, 40, 49, 23),
  192. dw_fill_range(500, 0x26, 0x19, 71, 41, 54, 24),
  193. dw_fill_range(550, 0x37, 0x19, 77, 44, 57, 26),
  194. dw_fill_range(600, 0x07, 0x19, 82, 46, 64, 27),
  195. dw_fill_range(650, 0x18, 0x19, 87, 48, 67, 28),
  196. dw_fill_range(700, 0x28, 0x0F, 94, 52, 71, 29),
  197. dw_fill_range(750, 0x39, 0x0F, 99, 52, 75, 31),
  198. dw_fill_range(800, 0x09, 0x0F, 105, 55, 82, 32),
  199. dw_fill_range(850, 0x19, 0x0F, 110, 58, 85, 32),
  200. dw_fill_range(900, 0x29, 0x09, 115, 58, 88, 35),
  201. dw_fill_range(950, 0x3A, 0x09, 120, 62, 93, 36),
  202. dw_fill_range(1000, 0x0A, 0x09, 128, 63, 99, 38),
  203. dw_fill_range(1050, 0x1A, 0x09, 132, 65, 102, 38),
  204. dw_fill_range(1100, 0x2A, 0x09, 138, 67, 106, 39),
  205. dw_fill_range(1150, 0x3B, 0x09, 146, 69, 112, 42),
  206. dw_fill_range(1200, 0x0B, 0x09, 151, 71, 117, 43),
  207. dw_fill_range(1250, 0x1B, 0x09, 153, 74, 120, 45),
  208. dw_fill_range(1300, 0x2B, 0x09, 160, 73, 124, 46),
  209. dw_fill_range(1350, 0x3C, 0x03, 165, 76, 130, 47),
  210. dw_fill_range(1400, 0x0C, 0x03, 172, 78, 134, 49),
  211. dw_fill_range(1450, 0x1C, 0x03, 177, 80, 138, 49),
  212. dw_fill_range(1500, 0x2C, 0x03, 183, 81, 143, 52),
  213. dw_fill_range(1550, 0x3D, 0x03, 191, 84, 147, 52),
  214. dw_fill_range(1600, 0x0D, 0x03, 194, 85, 152, 52),
  215. dw_fill_range(1650, 0x1D, 0x03, 201, 86, 155, 53),
  216. dw_fill_range(1700, 0x2E, 0x03, 208, 88, 161, 53),
  217. dw_fill_range(1750, 0x3E, 0x03, 212, 89, 165, 53),
  218. dw_fill_range(1800, 0x0E, 0x03, 220, 90, 171, 54),
  219. dw_fill_range(1850, 0x1E, 0x03, 223, 92, 175, 54),
  220. dw_fill_range(1900, 0x2F, 0x03, 231, 91, 180, 55),
  221. dw_fill_range(1950, 0x3F, 0x03, 236, 95, 185, 56),
  222. dw_fill_range(2000, 0x0F, 0x03, 243, 97, 190, 56),
  223. dw_fill_range(2050, 0x40, 0x03, 248, 99, 194, 58),
  224. dw_fill_range(2100, 0x41, 0x03, 252, 100, 199, 59),
  225. dw_fill_range(2150, 0x42, 0x03, 259, 102, 204, 61),
  226. dw_fill_range(2200, 0x43, 0x03, 266, 105, 210, 62),
  227. dw_fill_range(2250, 0x44, 0x03, 269, 109, 213, 63),
  228. dw_fill_range(2300, 0x45, 0x01, 272, 109, 217, 65),
  229. dw_fill_range(2350, 0x46, 0x01, 281, 112, 225, 66),
  230. dw_fill_range(2400, 0x47, 0x01, 283, 115, 226, 66),
  231. dw_fill_range(2450, 0x48, 0x01, 282, 115, 226, 67),
  232. dw_fill_range(2500, 0x49, 0x01, 281, 118, 227, 67),
  233. };
  234. static int dw_dphy_config_rstz(struct dw_dphy *dphy, u8 val)
  235. {
  236. int ret;
  237. u32 rstz = FIELD_PREP(PHY_RSTZ_PHY_RSTZ, !!val);
  238. ret = regmap_update_bits(dphy->regmap, DW_PHY_RSTZ,
  239. PHY_RSTZ_PHY_RSTZ, rstz);
  240. if (ret)
  241. dev_err(dphy->dev, "config rstz failed : %d\n", ret);
  242. return ret;
  243. }
  244. static int dw_dphy_config_shutdownz(struct dw_dphy *dphy, u8 val)
  245. {
  246. int ret;
  247. u32 shutdownz = FIELD_PREP(PHY_RSTZ_PHY_SHUTDOWNZ, !!val);
  248. ret = regmap_update_bits(dphy->regmap, DW_PHY_RSTZ,
  249. PHY_RSTZ_PHY_SHUTDOWNZ, shutdownz);
  250. if (ret)
  251. dev_err(dphy->dev, "config shutdownz failed: %d\n", ret);
  252. return ret;
  253. }
  254. static int dw_dphy_config_enableclk(struct dw_dphy *dphy, u8 val)
  255. {
  256. int ret;
  257. u32 enableclk = FIELD_PREP(PHY_RSTZ_PHY_ENABLECLK, !!val);
  258. ret = regmap_update_bits(dphy->regmap, DW_PHY_RSTZ,
  259. PHY_RSTZ_PHY_ENABLECLK, enableclk);
  260. if (ret)
  261. dev_err(dphy->dev, "config enableclk failed: %d\n", ret);
  262. return ret;
  263. }
  264. static int dw_dphy_config_testclr(struct dw_dphy *dphy, u8 val)
  265. {
  266. int ret;
  267. u32 testclr = FIELD_PREP(PHY_TST_CTRL0_TESTCLR, !!val);
  268. ret = regmap_update_bits(dphy->regmap, DW_PHY_TST_CTRL0,
  269. PHY_TST_CTRL0_TESTCLR, testclr);
  270. if (ret)
  271. dev_err(dphy->dev, "config testclr failed: %d\n", ret);
  272. return ret;
  273. }
  274. static int dw_dphy_config_testclk(struct dw_dphy *dphy, u8 val)
  275. {
  276. int ret;
  277. u32 testclk = FIELD_PREP(PHY_TST_CTRL0_TESTCLK, !!val);
  278. ret = regmap_update_bits(dphy->regmap, DW_PHY_TST_CTRL0,
  279. PHY_TST_CTRL0_TESTCLK, testclk);
  280. if (ret)
  281. dev_err(dphy->dev, "config testclk failed: %d\n", ret);
  282. return ret;
  283. }
  284. static int dw_dphy_config_testen(struct dw_dphy *dphy, u8 val)
  285. {
  286. int ret;
  287. u32 testen = FIELD_PREP(PHY_TST_CTRL1_TESTEN, !!val);
  288. ret = regmap_update_bits(dphy->regmap, DW_PHY_TST_CTRL1,
  289. PHY_TST_CTRL1_TESTEN, testen);
  290. if (ret)
  291. dev_err(dphy->dev, "config testen failed: %d\n", ret);
  292. return ret;
  293. }
  294. static int __maybe_unused dw_dphy_read_testdout(struct dw_dphy *dphy, u8 *val)
  295. {
  296. int ret;
  297. u32 phy_tst_ctrl1;
  298. ret = regmap_read(dphy->regmap, DW_PHY_TST_CTRL1, &phy_tst_ctrl1);
  299. if (ret) {
  300. dev_err(dphy->dev, "read phy_tst_ctrl1 failed: %d\n", ret);
  301. return ret;
  302. }
  303. *val = FIELD_GET(PHY_TST_CTRL1_TESTOUT, phy_tst_ctrl1);
  304. return 0;
  305. }
  306. static int dw_dphy_config_testdin(struct dw_dphy *dphy, u8 val)
  307. {
  308. int ret;
  309. u32 testdin = FIELD_PREP(PHY_TST_CTRL1_TESTIN, val);
  310. ret = regmap_update_bits(dphy->regmap, DW_PHY_TST_CTRL1,
  311. PHY_TST_CTRL1_TESTIN, testdin);
  312. if (ret)
  313. dev_err(dphy->dev, "config testdin failed: %d\n", ret);
  314. return ret;
  315. }
  316. /* Program Test Code */
  317. static int dw_dphy_phy_write(struct dw_dphy *dphy, u8 test_code,
  318. u8 *test_data, u8 len)
  319. {
  320. int i;
  321. /* set the desired test code */
  322. dw_dphy_config_testclk(dphy, 1);
  323. dw_dphy_config_testdin(dphy, test_code);
  324. dw_dphy_config_testen(dphy, TESTEN_WRITEADDR);
  325. dw_dphy_config_testclk(dphy, 0);
  326. /* enter the necessary test data */
  327. dw_dphy_config_testen(dphy, TESTEN_WRITEDATA);
  328. for (i = 0; i < len; i++) {
  329. pr_info("%s: test_code = %#x, len = %u, data[%d] = %#x\n",
  330. __func__, test_code, len, i, test_data[i]);
  331. dw_dphy_config_testdin(dphy, test_data[i]);
  332. dw_dphy_config_testclk(dphy, 1);
  333. dw_dphy_config_testclk(dphy, 0);
  334. }
  335. return 0;
  336. }
  337. static int dw_dphy_pll_config(struct dw_dphy *dphy, struct dw_dphy_cfg *cfg)
  338. {
  339. u8 data[8];
  340. u32 data_rate = DIV_ROUND_UP_ULL(cfg->hs_clk_rate, 1000000);
  341. data[0] = FIELD_PREP(PLL_PROP_CNTRL, data_rate >= 1150 ? 0xE : 0x8);
  342. dw_dphy_phy_write(dphy, TC_PLL_PROP_CHARGE_PUMP_CTRL, data, 1);
  343. data[0] = FIELD_PREP(PLL_CPBIAS_CNTRL, 0x10);
  344. dw_dphy_phy_write(dphy, TC_PLL_CHARGE_PUMP_BIAS_CTRL, data, 1);
  345. return 0;
  346. }
  347. static int dw_dphy_init(struct phy *phy)
  348. {
  349. struct dw_dphy *dphy = phy_get_drvdata(phy);
  350. pm_runtime_get_sync(dphy->dev);
  351. /* reset testclr */
  352. dw_dphy_config_testclr(dphy, 1);
  353. dw_dphy_config_testclr(dphy, 0);
  354. pm_runtime_put(dphy->dev);
  355. return 0;
  356. }
  357. static int dw_dphy_exit(struct phy *phy)
  358. {
  359. return 0;
  360. }
  361. static int dw_dphy_power_on(struct phy *phy)
  362. {
  363. struct dw_dphy *dphy = phy_get_drvdata(phy);
  364. pm_runtime_get_sync(dphy->dev);
  365. dw_dphy_config_enableclk(dphy, 1);
  366. dw_dphy_config_shutdownz(dphy, 1);
  367. dw_dphy_config_rstz(dphy, 1);
  368. return 0;
  369. }
  370. static int dw_dphy_power_off(struct phy *phy)
  371. {
  372. struct dw_dphy *dphy = phy_get_drvdata(phy);
  373. dw_dphy_config_rstz(dphy, 0);
  374. dw_dphy_config_enableclk(dphy, 0);
  375. dw_dphy_config_shutdownz(dphy, 0);
  376. pm_runtime_put(dphy->dev);
  377. return 0;
  378. }
  379. static int dw_dphy_get_pll_cfg(struct dw_dphy *dphy,
  380. struct phy_configure_opts_mipi_dphy *opts,
  381. struct dw_dphy_cfg *cfg)
  382. {
  383. int i;
  384. u32 n_min, n_max;
  385. u32 delta, best_delta = ~0U;
  386. u32 n, m, vco_div, best_n = 0, best_m = 0;
  387. unsigned long fin, fout;
  388. const struct dw_pll_range *range;
  389. fin = DIV_ROUND_UP_ULL(clk_get_rate(dphy->prefclk), 1000);
  390. if (fin < FCLKIN_FREQ_MIN || fin > FCLKIN_FREQ_MAX)
  391. return -EINVAL;
  392. fout = DIV_ROUND_UP_ULL(opts->hs_clk_rate, 1000) >> 1;
  393. if (fout < FOUT_FREQ_MIN || fout > FOUT_FREQ_MAX)
  394. return -EINVAL;
  395. for (i = 0; i < ARRAY_SIZE(pll_range_table); i++) {
  396. range = &pll_range_table[i];
  397. if (DIV_ROUND_UP_ULL(opts->hs_clk_rate, 1000000) <= range->data_rate)
  398. break;
  399. }
  400. /* update hs_clk_rate */
  401. opts->hs_clk_rate = range->data_rate * 1000000;
  402. vco_div = 1 << (range->vco_range >> 4);
  403. fout = fout * vco_div;
  404. pr_info("%s: vco_div = %u\n", __func__, vco_div);
  405. n_min = DIV_ROUND_UP_ULL(fin, FIN_DIV_N_FREQ_MAX * 1000);
  406. n_max = DIV_ROUND_UP_ULL(fin, FIN_DIV_N_FREQ_MIN * 1000);
  407. for (n = n_min; n < n_max + 1; n++) {
  408. m = DIV_ROUND_UP_ULL(fout * n, fin);
  409. if (m < 64 || m > 625)
  410. continue;
  411. delta = abs(fout * n - fin * m);
  412. if (delta < best_delta) {
  413. best_delta = delta;
  414. best_n = n;
  415. best_m = m;
  416. }
  417. }
  418. WARN_ON(unlikely(best_delta == ~0U));
  419. cfg->hs_clk_rate = opts->hs_clk_rate;
  420. cfg->hsfreqrange = range->hsfreqrange;
  421. cfg->vco_range = range->vco_range;
  422. cfg->n_div = best_n;
  423. cfg->m_div = best_m;
  424. cfg->clk_lp2hs = range->clk_lp2hs;
  425. cfg->clk_hs2lp = range->clk_hs2lp;
  426. cfg->data_lp2hs = range->data_lp2hs;
  427. cfg->data_hs2lp = range->data_hs2lp;
  428. return 0;
  429. }
  430. static int dw_dphy_config_from_opts(struct dw_dphy *dphy,
  431. struct phy_configure_opts_mipi_dphy *opts,
  432. struct dw_dphy_cfg *cfg)
  433. {
  434. int ret;
  435. ret = phy_mipi_dphy_config_validate(opts);
  436. if (ret)
  437. return ret;
  438. ret = dw_dphy_get_pll_cfg(dphy, opts, cfg);
  439. if (ret)
  440. return ret;
  441. return 0;
  442. }
  443. static int dw_dphy_validate(struct phy *phy, enum phy_mode mode,
  444. int submode, union phy_configure_opts *opts)
  445. {
  446. struct dw_dphy_cfg cfg = { 0 };
  447. struct dw_dphy *dphy = phy_get_drvdata(phy);
  448. if (mode != PHY_MODE_MIPI_DPHY)
  449. return -EINVAL;
  450. return dw_dphy_config_from_opts(dphy, &opts->mipi_dphy, &cfg);
  451. }
  452. static int dw_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
  453. {
  454. int ret;
  455. u8 data[8];
  456. u32 phy_if_cfg, hsfreqrange, cfgclkfreqrange;
  457. u32 phy_tmr_lpclk_cfg, phy_tmr_cfg;
  458. unsigned long cfgclk_freq;
  459. struct dw_dphy_cfg cfg = { 0 };
  460. struct dw_dphy *dphy = phy_get_drvdata(phy);
  461. struct phy_configure_opts_mipi_dphy *dphy_opts = &opts->mipi_dphy;
  462. ret = dw_dphy_config_from_opts(dphy, dphy_opts, &cfg);
  463. if (ret)
  464. return ret;
  465. /* configure hsfreqrange and cfgclkfreqrange */
  466. hsfreqrange = FIELD_PREP(MIPIDSI_HSFREQRANGE, cfg.hsfreqrange);
  467. ret = regmap_update_bits(dphy->vosys_regmap, VOSYS_MIPIDSI0_SYSREG,
  468. MIPIDSI_HSFREQRANGE, hsfreqrange);
  469. if (ret) {
  470. dev_err(dphy->dev, "config dsi0 hsfreqrange failed\n");
  471. return ret;
  472. }
  473. hsfreqrange = FIELD_PREP(MIPIDSI_HSFREQRANGE, cfg.hsfreqrange);
  474. ret = regmap_update_bits(dphy->vosys_regmap, VOSYS_MIPIDSI1_SYSREG,
  475. MIPIDSI_HSFREQRANGE, hsfreqrange);
  476. if (ret) {
  477. dev_err(dphy->dev, "config dsi1 hsfreqrange failed\n");
  478. return ret;
  479. }
  480. /* TODO: config prg_on_lane0 */
  481. /* TODO: config cfgclkhsfreqrange:
  482. *
  483. * cfgclkfreqrange[5:0] = round[(Fcfg_clk(MHz)-17)*4]
  484. *
  485. */
  486. cfgclk_freq = DIV_ROUND_UP_ULL(clk_get_rate(dphy->pcfgclk), 1000);
  487. if (cfgclk_freq < CFGCLK_FREQ_MIN || cfgclk_freq > CFGCLK_FREQ_MAX)
  488. return -EINVAL;
  489. cfgclkfreqrange = FIELD_PREP(MIPIDSI_CFGCLKFREQRANGE,
  490. (cfgclk_freq / 1000 - 17) * 4);
  491. ret = regmap_update_bits(dphy->vosys_regmap, VOSYS_MIPIDSI0_SYSREG,
  492. MIPIDSI_CFGCLKFREQRANGE, cfgclkfreqrange);
  493. if (ret) {
  494. dev_err(dphy->dev, "config dsi0 cfgclkfreqrange failed\n");
  495. return ret;
  496. }
  497. ret = regmap_update_bits(dphy->vosys_regmap, VOSYS_MIPIDSI1_SYSREG,
  498. MIPIDSI_CFGCLKFREQRANGE, cfgclkfreqrange);
  499. if (ret) {
  500. dev_err(dphy->dev, "config dsi1 cfgclkfreqrange failed\n");
  501. return ret;
  502. }
  503. /* TODO: disable slew rate calibration */
  504. data[0] = 0x0;
  505. dw_dphy_phy_write(dphy, TC_SR_DDL_LOOP_CONF, data, 1);
  506. data[0] = 0x1;
  507. dw_dphy_phy_write(dphy, TC_SR_FSM_OVR_CNTRL, data, 1);
  508. /* configure prg_on_lane0 */
  509. data[0] = FIELD_PREP(PRG_ON_LANE0, 1);
  510. dw_dphy_phy_write(dphy, TC_PG_LP_BIAS_LANE0, data, 1);
  511. dw_dphy_pll_config(dphy, &cfg);
  512. phy_if_cfg = FIELD_PREP(PHY_IF_CFG_N_LANES, dphy_opts->lanes - 1) |
  513. FIELD_PREP(PHY_IF_CFG_PHY_STOP_WAIT_TIME, 0x2);
  514. regmap_write(dphy->regmap, DW_PHY_IF_CFG, phy_if_cfg);
  515. /* config clock & data lane timers */
  516. phy_tmr_lpclk_cfg = FIELD_PREP(PHY_TMR_LPCLK_CFG_PHY_CLKHS2LP_TIME, cfg.clk_hs2lp) |
  517. FIELD_PREP(PHY_TMR_LPCLK_CFG_PHY_CLKLP2HS_TIME, cfg.clk_lp2hs);
  518. regmap_write(dphy->regmap, DW_PHY_TMR_LPCLK_CFG, phy_tmr_lpclk_cfg);
  519. phy_tmr_cfg = FIELD_PREP(PHY_TMR_CFG_PHY_HS2LP_TIME, cfg.data_hs2lp) |
  520. FIELD_PREP(PHY_TMR_CFG_PHY_LP2HS_TIME, cfg.data_lp2hs);
  521. regmap_write(dphy->regmap, DW_PHY_TMR_CFG, phy_tmr_cfg);
  522. regmap_write(dphy->regmap, DW_PHY_TMR_RD_CFG, 10000);
  523. return 0;
  524. }
  525. static const struct phy_ops dw_dphy_phy_ops = {
  526. .init = dw_dphy_init,
  527. .exit = dw_dphy_exit,
  528. .power_on = dw_dphy_power_on,
  529. .power_off = dw_dphy_power_off,
  530. .validate = dw_dphy_validate,
  531. .configure = dw_dphy_configure,
  532. .owner = THIS_MODULE,
  533. };
  534. static const struct regmap_config dw_dphy_regmap_config = {
  535. .name = "dw-dphy",
  536. .reg_bits = 32,
  537. .val_bits = 32,
  538. .reg_stride = 4,
  539. .max_register = 0x40,
  540. };
  541. static int dw_dphy_probe(struct platform_device *pdev)
  542. {
  543. struct device *dev = &pdev->dev;
  544. struct device_node *np = dev->of_node;
  545. struct phy_provider *provider;
  546. struct dw_dphy *dphy;
  547. dphy = devm_kzalloc(dev, sizeof(*dphy), GFP_KERNEL);
  548. if (!dphy)
  549. return -ENOMEM;
  550. dphy->dev = dev;
  551. dphy->regmap = syscon_regmap_lookup_by_phandle(np, "regmap");
  552. if (IS_ERR(dphy->regmap))
  553. return PTR_ERR(dphy->regmap);
  554. dphy->vosys_regmap = syscon_regmap_lookup_by_phandle(np, "vosys-regmap");
  555. if (IS_ERR(dphy->vosys_regmap))
  556. return PTR_ERR(dphy->vosys_regmap);
  557. dphy->refclk = devm_clk_get(dev, "refclk");
  558. if (IS_ERR(dphy->refclk))
  559. return PTR_ERR(dphy->refclk);
  560. dphy->cfgclk = devm_clk_get(dev, "cfgclk");
  561. if (IS_ERR(dphy->cfgclk))
  562. return PTR_ERR(dphy->cfgclk);
  563. dphy->pclk = devm_clk_get(dev, "pclk");
  564. if (IS_ERR(dphy->pclk))
  565. return PTR_ERR(dphy->pclk);
  566. dphy->prefclk = devm_clk_get(dev, "prefclk");
  567. if (IS_ERR(dphy->prefclk))
  568. return PTR_ERR(dphy->prefclk);
  569. dphy->pcfgclk = devm_clk_get(dev, "pcfgclk");
  570. if (IS_ERR(dphy->pcfgclk))
  571. return PTR_ERR(dphy->pcfgclk);
  572. platform_set_drvdata(pdev, dphy);
  573. pm_suspend_ignore_children(dev, true);
  574. pm_runtime_enable(dev);
  575. dphy->phy = devm_phy_create(dev, np, &dw_dphy_phy_ops);
  576. if (IS_ERR(dphy->phy))
  577. return PTR_ERR(dphy->phy);
  578. phy_set_drvdata(dphy->phy, dphy);
  579. provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
  580. return PTR_ERR_OR_ZERO(provider);
  581. }
  582. static int dw_dphy_remove(struct platform_device *pdev)
  583. {
  584. pm_runtime_disable(&pdev->dev);
  585. return 0;
  586. }
  587. static const struct of_device_id dw_dphy_of_match[] = {
  588. { .compatible = "thead,light-mipi-dphy", .data = NULL, },
  589. };
  590. MODULE_DEVICE_TABLE(of, dw_dphy_of_match);
  591. #ifdef CONFIG_PM
  592. static int dw_dphy_runtime_suspend(struct device *dev)
  593. {
  594. struct dw_dphy *dphy = dev_get_drvdata(dev);
  595. clk_disable_unprepare(dphy->refclk);
  596. clk_disable_unprepare(dphy->cfgclk);
  597. clk_disable_unprepare(dphy->pclk);
  598. return 0;
  599. }
  600. static int dw_dphy_runtime_resume(struct device *dev)
  601. {
  602. int ret;
  603. struct dw_dphy *dphy = dev_get_drvdata(dev);
  604. ret = clk_prepare_enable(dphy->pclk);
  605. if (ret) {
  606. dev_err(dev, "failed to prepare/enable pclk\n");
  607. return ret;
  608. }
  609. ret = clk_prepare_enable(dphy->cfgclk);
  610. if (ret) {
  611. dev_err(dev, "failed to prepare/enable cfgclk\n");
  612. return ret;
  613. }
  614. ret = clk_prepare_enable(dphy->refclk);
  615. if (ret) {
  616. dev_err(dev, "failed to prepare/enable refclk\n");
  617. return ret;
  618. }
  619. return 0;
  620. }
  621. #endif
  622. static const struct dev_pm_ops dw_dphy_pm_ops = {
  623. SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
  624. pm_runtime_force_resume)
  625. SET_RUNTIME_PM_OPS(dw_dphy_runtime_suspend, dw_dphy_runtime_resume, NULL)
  626. };
  627. static struct platform_driver dw_dphy_driver = {
  628. .probe = dw_dphy_probe,
  629. .remove = dw_dphy_remove,
  630. .driver = {
  631. .name = "dw-mipi-dphy",
  632. .of_match_table = dw_dphy_of_match,
  633. .pm = &dw_dphy_pm_ops,
  634. },
  635. };
  636. module_platform_driver(dw_dphy_driver);
  637. MODULE_AUTHOR("You Xiao <youxiao.fc@linux.alibaba.com>");
  638. MODULE_DESCRIPTION("Synopsys DesignWare MIPI DPHY driver");
  639. MODULE_LICENSE("GPL");