dw_hdmi_tx_phy_gen2.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. #ifndef _DW_HDMI_PHY_GEN2_H_
  2. #define _DW_HDMI_PHY_GEN2_H_
  3. #include <linux/bits.h>
  4. #include <linux/bitfield.h>
  5. #include <linux/kernel.h>
  6. #include <drm/bridge/dw_hdmi.h>
  7. /* PHY registers */
  8. #define DW_HDMI_TX_PHY_GEN2_PWRCTRL 0x00
  9. #define DW_HDMI_TX_PHY_GEN2_SERDIVCTRL 0x01
  10. #define DW_HDMI_TX_PHY_GEN2_SERCKCTRL 0x02
  11. #define DW_HDMI_TX_PHY_GEN2_SERCKKILLCTRL 0x03
  12. #define DW_HDMI_TX_PHY_GEN2_TXRESCALCTRL 0x04
  13. #define DW_HDMI_TX_PHY_GEN2_OPMODE_PLLCFG 0x06
  14. #define DW_HDMI_TX_PHY_GEN2_TXCKMEASCTRL 0x07
  15. #define DW_HDMI_TX_PHY_GEN2_TXMEASCTRL 0x08
  16. #define DW_HDMI_TX_PHY_GEN2_CKSYMTXCTRL 0x09
  17. #define DW_HDMI_TX_PHY_GEN2_CMPSEQCTRL 0x0A
  18. #define DW_HDMI_TX_PHY_GEN2_CMPPWRCTRL 0x0B
  19. #define DW_HDMI_TX_PHY_GEN2_CMPMODECTRL 0x0C
  20. #define DW_HDMI_TX_PHY_GEN2_MEASCTRL 0x0D
  21. #define DW_HDMI_TX_PHY_GEN2_VLEVCTRL_PLLMEASCTRL 0x0E
  22. #define DW_HDMI_TX_PHY_GEN2_D2ACTRL 0x0F
  23. #define DW_HDMI_TX_PHY_GEN2_PLLCURRGMPCTRL 0x10
  24. #define DW_HDMI_TX_PHY_GEN2_PLLDIVCTRL 0x11
  25. #define DW_HDMI_TX_PHY_GEN2_SUPPLLBGCTRL 0x12
  26. #define DW_HDMI_TX_PHY_GEN2_PLLCONFCTRL 0x13
  27. #define DW_HDMI_TX_PHY_GEN2_PLLCTRL 0x14
  28. #define DW_HDMI_TX_PHY_GEN2_PLLDIGTESTCTRL 0x15
  29. #define DW_HDMI_TX_PHY_GEN2_PLLMEASCTRL 0x16
  30. #define DW_HDMI_TX_PHY_GEN2_PLLCLKBISTPHASE 0x17
  31. #define DW_HDMI_TX_PHY_GEN2_COMPRCAL 0x18
  32. #define DW_HDMI_TX_PHY_GEN2_TXTERM 0x19
  33. #define DW_HDMI_TX_PHY_GEN2_PWRSEQ_PATGENSKIP 0x1A
  34. #define DW_HDMI_TX_PHY_GEN2_PATTERNGEN_BISTSEL 0x1B
  35. #define DW_HDMI_TX_PHY_GEN2_CTRL_CLKALIGN_PGMODE_BISTPG 0x1C
  36. #define DW_HDMI_TX_PHY_GEN2_BISTCHSTATUS_CLKALIGN_RCAL 0x1D
  37. #define DW_HDMI_TX_PHY_GEN2_DIGTXMODE 0x1E
  38. #define DW_HDMI_TX_PHY_GEN2_CLKALIGN_RCAL_SOFTRESET 0x1F
  39. #define DW_HDMI_TX_PHY_GEN2_PWRSEQ_PATGENSKIP_RD 0x2E
  40. #define DW_HDMI_TX_PHY_GEN2_PLLCLKBISTPHASE_RD 0x2F
  41. #define DW_HDMI_TX_PHY_GEN2_PLLSTATUS 0x30
  42. #define DW_HDMI_TX_PHY_GEN2_SUPPLLBGSTATUS 0x31
  43. #define DW_HDMI_TX_PHY_GEN2_D2ASTATUS 0x32
  44. #define DW_HDMI_TX_PHY_GEN2_CMPMODESTATUS 0x33
  45. #define DW_HDMI_TX_PHY_GEN2_CMPPWRSTATUS 0x34
  46. #define DW_HDMI_TX_PHY_GEN2_CMPSEQSTATUS 0x35
  47. #define DW_HDMI_TX_PHY_GEN2_CKSYMTXSTATUS 0x36
  48. #define DW_HDMI_TX_PHY_GEN2_TXRESCALSTATUS 0x37
  49. #define DW_HDMI_TX_PHY_GEN2_SERCKKILLSTATUS 0x38
  50. #define DW_HDMI_TX_PHY_GEN2_SERCKSTATUS 0x39
  51. #define DW_HDMI_TX_PHY_GEN2_SERDIVSTATUS 0x3A
  52. #define DW_HDMI_TX_PHY_GEN2_PWRSTATUS 0x3B
  53. /* PHY register bitfields */
  54. #define PWRCTRL_OVERRIDE_0 BIT(15)
  55. #define PWRCTRL_BIAS_ON BIT(5)
  56. #define PWRCTRL_TX_PWRON BIT(4)
  57. #define PWRCTRL_TX_PWRON0 BIT(3)
  58. #define PWRCTRL_TX_PWRON1 BIT(2)
  59. #define PWRCTRL_TX_PWRON2 BIT(1)
  60. #define PWRCTRL_CK_PWRON BIT(0)
  61. #define OPMODE_PLLCFG_PREP_DIV GENMASK(13, 12)
  62. #define OPMODE_PLLCFG_MPLL_CKO_DIV GENMASK(10, 9)
  63. #define OPMODE_PLLCFG_OPMODE GENMASK( 7, 6)
  64. #define OPMODE_PLLCFG_REF_CNTRL GENMASK( 4, 3)
  65. #define OPMODE_PLLCFG_MPLL_N_CNTRL GENMASK( 1, 0)
  66. #define CKSYMTXCTRL_OVERRIDE_5 BIT(15)
  67. #define CKSYMTXCTRL_SLOPE_BOOST GENMASK(13, 10)
  68. #define CKSYMTXCTRL_TX_TRAON BIT(9)
  69. #define CKSYMTXCTRL_TX_TRBON BIT(8)
  70. #define CKSYMTXCTRL_TX_SYMON GENMASK( 7, 4)
  71. #define CKSYMTXCTRL_CK_SYMON GENMASK( 3, 0)
  72. #define VLEVCTRL_PLLMEASCTRL_MPLL_MEAS_17_14 GENMASK(13, 10)
  73. #define VLEVCTRL_PLLMEASCTRL_SUP_TX_LVL GENMASK( 9, 5)
  74. #define PLLCURRGMPCTRL_MPLL_GMP_CNTRL GENMASK(13, 12)
  75. #define PLLCURRGMPCTRL_MPLL_PROP_CNTRL GENMASK(11, 6)
  76. #define PLLCURRGMPCTRL_MPLL_INT_CNTRL GENMASK( 5, 0)
  77. #define PLLDIVCTRL_VCO_CNTRL GENMASK(12, 9)
  78. #define PLLDIVCTRL_MPLL_MULTIPLIER GENMASK( 7, 0)
  79. #define TXTERM_D_TX_TERM GENMASK( 2, 0)
  80. #define TXTERM_50_OHM 0x0
  81. #define TXTERM_57_14_OHM 0x1
  82. #define TXTERM_66_67_OHM 0x2
  83. #define TXTERM_80_OHM 0x3
  84. #define TXTERM_100_OHM 0x4
  85. #define TXTERM_133_33_OHM 0x5
  86. #define TXTERM_200_OHM 0x6
  87. #define TXTERM_OPEN_CIRCUIT 0x7
  88. #define OPMODE_HDMI_14 0
  89. #define OPMODE_HDMI_20 1
  90. struct dw_hdmi_mpll_gen_config{
  91. u64 pixelclock; /* in kHz */
  92. u8 colordepth;
  93. u16 opmode:2;
  94. struct {
  95. u16 prep_div:2;
  96. u16 mpll_cko_div:2;
  97. u16 ref_cntrl:2;
  98. u16 mpll_n_cntrl:2;
  99. u16 vco_cntrl:4;
  100. u16 mpll_multiplier:8;
  101. } divider;
  102. struct {
  103. u16 gmp_cntrl:2;
  104. u16 prop_cntrl:6;
  105. u16 int_cntrl:6;
  106. } charge_pump;
  107. struct {
  108. u16 txterm:3;
  109. u16 sup_txlvl:5;
  110. u16 tx_traon:1;
  111. u16 tx_trbon:1;
  112. u16 tx_symon:4;
  113. u16 ck_symon:4;
  114. } voltage;
  115. };
  116. static const struct dw_hdmi_mpll_gen_config mpll_configs[] = {
  117. {
  118. .pixelclock = 25175,
  119. .colordepth = 8,
  120. .opmode = OPMODE_HDMI_14,
  121. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  122. .mpll_n_cntrl = 0x3, .vco_cntrl = 0x3, .mpll_multiplier = 0x28, },
  123. .charge_pump = { .gmp_cntrl = 0x0, .prop_cntrl = 0xa, .int_cntrl = 0x3, },
  124. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  125. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  126. }, {
  127. .pixelclock = 27000,
  128. .colordepth = 8,
  129. .opmode = OPMODE_HDMI_14,
  130. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  131. .mpll_n_cntrl = 0x3, .vco_cntrl = 0x3, .mpll_multiplier = 0x28, },
  132. .charge_pump = { .gmp_cntrl = 0x0, .prop_cntrl = 0xa, .int_cntrl = 0x3, },
  133. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  134. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  135. }, {
  136. .pixelclock = 31500,
  137. .colordepth = 8,
  138. .opmode = OPMODE_HDMI_14,
  139. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  140. .mpll_n_cntrl = 0x3, .vco_cntrl = 0x3, .mpll_multiplier = 0x28, },
  141. .charge_pump = { .gmp_cntrl = 0x0, .prop_cntrl = 0xa, .int_cntrl = 0x3, },
  142. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  143. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  144. }, {
  145. .pixelclock = 33750,
  146. .colordepth = 8,
  147. .opmode = OPMODE_HDMI_14,
  148. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  149. .mpll_n_cntrl = 0x3, .vco_cntrl = 0x3, .mpll_multiplier = 0x28, },
  150. .charge_pump = { .gmp_cntrl = 0x0, .prop_cntrl = 0xa, .int_cntrl = 0x3, },
  151. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  152. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  153. }, {
  154. .pixelclock = 35500,
  155. .colordepth = 8,
  156. .opmode = OPMODE_HDMI_14,
  157. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  158. .mpll_n_cntrl = 0x3, .vco_cntrl = 0x3, .mpll_multiplier = 0x28, },
  159. .charge_pump = { .gmp_cntrl = 0x0, .prop_cntrl = 0xa, .int_cntrl = 0x3, },
  160. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  161. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  162. }, {
  163. .pixelclock = 36000,
  164. .colordepth = 8,
  165. .opmode = OPMODE_HDMI_14,
  166. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  167. .mpll_n_cntrl = 0x3, .vco_cntrl = 0x1, .mpll_multiplier = 0x28, },
  168. .charge_pump = { .gmp_cntrl = 0x0, .prop_cntrl = 0xa, .int_cntrl = 0x5, },
  169. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  170. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  171. }, {
  172. .pixelclock = 40000,
  173. .colordepth = 8,
  174. .opmode = OPMODE_HDMI_14,
  175. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  176. .mpll_n_cntrl = 0x3, .vco_cntrl = 0x1, .mpll_multiplier = 0x28, },
  177. .charge_pump = { .gmp_cntrl = 0x0, .prop_cntrl = 0xa, .int_cntrl = 0x5, },
  178. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  179. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  180. }, {
  181. .pixelclock = 44900,
  182. .colordepth = 8,
  183. .opmode = OPMODE_HDMI_14,
  184. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  185. .mpll_n_cntrl = 0x3, .vco_cntrl = 0x1, .mpll_multiplier = 0x28, },
  186. .charge_pump = { .gmp_cntrl = 0x0, .prop_cntrl = 0xa, .int_cntrl = 0x5, },
  187. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  188. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  189. }, {
  190. .pixelclock = 49500,
  191. .colordepth = 8,
  192. .opmode = OPMODE_HDMI_14,
  193. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  194. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  195. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  196. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  197. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  198. }, {
  199. .pixelclock = 50000,
  200. .colordepth = 8,
  201. .opmode = OPMODE_HDMI_14,
  202. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  203. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  204. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  205. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  206. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  207. }, {
  208. .pixelclock = 50350,
  209. .colordepth = 8,
  210. .opmode = OPMODE_HDMI_14,
  211. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  212. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  213. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  214. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  215. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  216. }, {
  217. .pixelclock = 54000,
  218. .colordepth = 8,
  219. .opmode = OPMODE_HDMI_14,
  220. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  221. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  222. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  223. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  224. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  225. }, {
  226. .pixelclock = 56250,
  227. .colordepth = 8,
  228. .opmode = OPMODE_HDMI_14,
  229. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  230. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  231. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  232. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  233. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  234. }, {
  235. .pixelclock = 59400,
  236. .colordepth = 8,
  237. .opmode = OPMODE_HDMI_14,
  238. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  239. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  240. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  241. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  242. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  243. }, {
  244. .pixelclock = 65000,
  245. .colordepth = 8,
  246. .opmode = OPMODE_HDMI_14,
  247. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  248. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  249. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  250. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  251. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  252. }, {
  253. .pixelclock = 68250,
  254. .colordepth = 8,
  255. .opmode = OPMODE_HDMI_14,
  256. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  257. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  258. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  259. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  260. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  261. }, {
  262. .pixelclock = 71000,
  263. .colordepth = 8,
  264. .opmode = OPMODE_HDMI_14,
  265. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  266. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x3, .mpll_multiplier = 0x14, },
  267. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x6, .int_cntrl = 0x3, },
  268. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  269. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  270. }, {
  271. .pixelclock = 72000,
  272. .colordepth = 8,
  273. .opmode = OPMODE_HDMI_14,
  274. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  275. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  276. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  277. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  278. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  279. }, {
  280. .pixelclock = 73250,
  281. .colordepth = 8,
  282. .opmode = OPMODE_HDMI_14,
  283. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  284. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  285. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  286. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  287. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  288. }, {
  289. .pixelclock = 74250,
  290. .colordepth = 8,
  291. .opmode = OPMODE_HDMI_14,
  292. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  293. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  294. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  295. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  296. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  297. }, {
  298. .pixelclock = 75000,
  299. .colordepth = 8,
  300. .opmode = OPMODE_HDMI_14,
  301. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  302. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  303. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  304. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  305. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  306. }, {
  307. .pixelclock = 78750,
  308. .colordepth = 8,
  309. .opmode = OPMODE_HDMI_14,
  310. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  311. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  312. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  313. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  314. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  315. }, {
  316. .pixelclock = 79500,
  317. .colordepth = 8,
  318. .opmode = OPMODE_HDMI_14,
  319. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  320. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  321. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  322. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  323. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  324. }, {
  325. .pixelclock = 82500,
  326. .colordepth = 8,
  327. .opmode = OPMODE_HDMI_14,
  328. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  329. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  330. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  331. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  332. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  333. }, {
  334. .pixelclock = 83500,
  335. .colordepth = 8,
  336. .opmode = OPMODE_HDMI_14,
  337. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  338. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  339. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  340. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  341. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  342. }, {
  343. .pixelclock = 85500,
  344. .colordepth = 8,
  345. .opmode = OPMODE_HDMI_14,
  346. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  347. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  348. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  349. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  350. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  351. }, {
  352. .pixelclock = 88750,
  353. .colordepth = 8,
  354. .opmode = OPMODE_HDMI_14,
  355. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  356. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  357. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  358. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  359. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  360. }, {
  361. .pixelclock = 90000,
  362. .colordepth = 8,
  363. .opmode = OPMODE_HDMI_14,
  364. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  365. .mpll_n_cntrl = 0x2, .vco_cntrl = 0x1, .mpll_multiplier = 0x14, },
  366. .charge_pump = { .gmp_cntrl = 0x1, .prop_cntrl = 0x5, .int_cntrl = 0x2, },
  367. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  368. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  369. }, {
  370. .pixelclock = 94500,
  371. .colordepth = 8,
  372. .opmode = OPMODE_HDMI_14,
  373. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  374. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  375. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  376. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  377. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  378. }, {
  379. .pixelclock = 99000,
  380. .colordepth = 8,
  381. .opmode = OPMODE_HDMI_14,
  382. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  383. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  384. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  385. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  386. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  387. }, {
  388. .pixelclock = 100700,
  389. .colordepth = 8,
  390. .opmode = OPMODE_HDMI_14,
  391. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  392. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  393. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  394. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  395. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  396. }, {
  397. .pixelclock = 101000,
  398. .colordepth = 8,
  399. .opmode = OPMODE_HDMI_14,
  400. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  401. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  402. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  403. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  404. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  405. }, {
  406. .pixelclock = 102250,
  407. .colordepth = 8,
  408. .opmode = OPMODE_HDMI_14,
  409. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  410. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  411. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  412. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  413. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  414. }, {
  415. .pixelclock = 106500,
  416. .colordepth = 8,
  417. .opmode = OPMODE_HDMI_14,
  418. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  419. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  420. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  421. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  422. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  423. }, {
  424. .pixelclock = 108000,
  425. .colordepth = 8,
  426. .opmode = OPMODE_HDMI_14,
  427. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  428. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  429. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  430. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  431. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  432. }, {
  433. .pixelclock = 115500,
  434. .colordepth = 8,
  435. .opmode = OPMODE_HDMI_14,
  436. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  437. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  438. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  439. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  440. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  441. }, {
  442. .pixelclock = 117500,
  443. .colordepth = 8,
  444. .opmode = OPMODE_HDMI_14,
  445. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  446. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  447. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  448. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  449. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  450. }, {
  451. .pixelclock = 118800,
  452. .colordepth = 8,
  453. .opmode = OPMODE_HDMI_14,
  454. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  455. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  456. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  457. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  458. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  459. }, {
  460. .pixelclock = 119000,
  461. .colordepth = 8,
  462. .opmode = OPMODE_HDMI_14,
  463. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  464. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  465. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  466. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  467. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  468. }, {
  469. .pixelclock = 121750,
  470. .colordepth = 8,
  471. .opmode = OPMODE_HDMI_14,
  472. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  473. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x3, .mpll_multiplier = 0xa, },
  474. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x3, .int_cntrl = 0x0, },
  475. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  476. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  477. }, {
  478. .pixelclock = 148500,
  479. .colordepth = 8,
  480. .opmode = OPMODE_HDMI_14,
  481. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  482. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x1, .mpll_multiplier = 0xa, },
  483. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x2, .int_cntrl = 0x0, },
  484. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  485. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  486. }, {
  487. .pixelclock = 154000,
  488. .colordepth = 8,
  489. .opmode = OPMODE_HDMI_14,
  490. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  491. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x1, .mpll_multiplier = 0xa, },
  492. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x2, .int_cntrl = 0x0, },
  493. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  494. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  495. }, {
  496. .pixelclock = 162000,
  497. .colordepth = 8,
  498. .opmode = OPMODE_HDMI_14,
  499. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  500. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x1, .mpll_multiplier = 0xa, },
  501. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x2, .int_cntrl = 0x0, },
  502. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  503. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  504. }, {
  505. .pixelclock = 165000,
  506. .colordepth = 8,
  507. .opmode = OPMODE_HDMI_14,
  508. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  509. .mpll_n_cntrl = 0x1, .vco_cntrl = 0x1, .mpll_multiplier = 0xa, },
  510. .charge_pump = { .gmp_cntrl = 0x2, .prop_cntrl = 0x2, .int_cntrl = 0x0, },
  511. .voltage = { .txterm = TXTERM_OPEN_CIRCUIT, .sup_txlvl = 0xd, .tx_traon = 0x0,
  512. .tx_trbon = 0x0, .tx_symon = 0x8, .ck_symon = 0x8, },
  513. }, {
  514. .pixelclock = 185625,
  515. .colordepth = 8,
  516. .opmode = OPMODE_HDMI_14,
  517. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  518. .mpll_n_cntrl = 0x0, .vco_cntrl = 0x3, .mpll_multiplier = 0x5, },
  519. .charge_pump = { .gmp_cntrl = 0x3, .prop_cntrl = 0x1, .int_cntrl = 0x0, },
  520. .voltage = { .txterm = TXTERM_100_OHM, .sup_txlvl = 0x9, .tx_traon = 0x1,
  521. .tx_trbon = 0x1, .tx_symon = 0xc, .ck_symon = 0x8, },
  522. }, {
  523. .pixelclock = 198000,
  524. .colordepth = 8,
  525. .opmode = OPMODE_HDMI_14,
  526. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  527. .mpll_n_cntrl = 0x0, .vco_cntrl = 0x3, .mpll_multiplier = 0x5, },
  528. .charge_pump = { .gmp_cntrl = 0x3, .prop_cntrl = 0x1, .int_cntrl = 0x0, },
  529. .voltage = { .txterm = TXTERM_100_OHM, .sup_txlvl = 0x9, .tx_traon = 0x1,
  530. .tx_trbon = 0x1, .tx_symon = 0xc, .ck_symon = 0x8, },
  531. }, {
  532. .pixelclock = 297000,
  533. .colordepth = 8,
  534. .opmode = OPMODE_HDMI_14,
  535. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x0, .ref_cntrl = 0x0,
  536. .mpll_n_cntrl = 0x0, .vco_cntrl = 0x1, .mpll_multiplier = 0x5, },
  537. .charge_pump = { .gmp_cntrl = 0x3, .prop_cntrl = 0x1, .int_cntrl = 0x1, },
  538. .voltage = { .txterm = TXTERM_133_33_OHM, .sup_txlvl = 0x10, .tx_traon = 0x0,
  539. .tx_trbon = 0x1, .tx_symon = 0xd, .ck_symon = 0xc, },
  540. }, {
  541. .pixelclock = 371250,
  542. .colordepth = 8,
  543. .opmode = OPMODE_HDMI_20,
  544. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x3, .ref_cntrl = 0x0,
  545. .mpll_n_cntrl = 0x0, .vco_cntrl = 0x1, .mpll_multiplier = 0x5, },
  546. .charge_pump = { .gmp_cntrl = 0x3, .prop_cntrl = 0x1, .int_cntrl = 0x1, },
  547. .voltage = { .txterm = TXTERM_50_OHM, .sup_txlvl = 0xa, .tx_traon = 0x0,
  548. .tx_trbon = 0x0, .tx_symon = 0xf, .ck_symon = 0x6, },
  549. }, {
  550. .pixelclock = 495000,
  551. .colordepth = 8,
  552. .opmode = OPMODE_HDMI_20,
  553. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x3, .ref_cntrl = 0x0,
  554. .mpll_n_cntrl = 0x0, .vco_cntrl = 0x0, .mpll_multiplier = 0x5, },
  555. .charge_pump = { .gmp_cntrl = 0x3, .prop_cntrl = 0x2, .int_cntrl = 0x0, },
  556. .voltage = { .txterm = TXTERM_50_OHM, .sup_txlvl = 0xa, .tx_traon = 0x0,
  557. .tx_trbon = 0x0, .tx_symon = 0xf, .ck_symon = 0x6, },
  558. }, {
  559. .pixelclock = 594000,
  560. .colordepth = 8,
  561. .opmode = OPMODE_HDMI_20,
  562. .divider = { .prep_div = 0x0, .mpll_cko_div = 0x3, .ref_cntrl = 0x0,
  563. .mpll_n_cntrl = 0x0, .vco_cntrl = 0x0, .mpll_multiplier = 0x5, },
  564. .charge_pump = { .gmp_cntrl = 0x3, .prop_cntrl = 0x2, .int_cntrl = 0x0, },
  565. .voltage = { .txterm = TXTERM_100_OHM, .sup_txlvl = 0xf, .tx_traon = 0x0,
  566. .tx_trbon = 0x0, .tx_symon = 0xf, .ck_symon = 0xa, },
  567. },
  568. };
  569. static enum drm_mode_status
  570. dw_hdmi_tx_phy_gen2_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
  571. const struct drm_display_info *info,
  572. const struct drm_display_mode *mode)
  573. {
  574. int i;
  575. if (mode->clock < 13500)
  576. return MODE_CLOCK_LOW;
  577. else if (mode->clock > 594000)
  578. return MODE_CLOCK_HIGH;
  579. for (i = 0; i < ARRAY_SIZE(mpll_configs); i++) {
  580. if (abs(mode->clock - mpll_configs[i].pixelclock) <= 100)
  581. return MODE_OK;
  582. else if (mode->clock < mpll_configs[i].pixelclock)
  583. break;
  584. }
  585. return MODE_NOMODE;
  586. }
  587. static int dw_hdmi_tx_phy_gen2_configure(struct dw_hdmi *hdmi, void *data,
  588. unsigned long mpixelclock)
  589. {
  590. int i;
  591. u16 opmode_pllcfg, pllcurrgmpctrl, plldivctrl;
  592. u16 txterm, vlevctrl_pllmeasctrl, cksymtxctrl;
  593. u64 pixclk = mpixelclock / 1000;
  594. const struct dw_hdmi_mpll_gen_config *config;
  595. for (i = 0; i < ARRAY_SIZE(mpll_configs); i++) {
  596. config = &mpll_configs[i];
  597. /* TODO: add colordepth check later */
  598. if (abs(config->pixelclock - pixclk) <= 100)
  599. break;
  600. }
  601. if (i == ARRAY_SIZE(mpll_configs))
  602. return -1;
  603. opmode_pllcfg = FIELD_PREP(OPMODE_PLLCFG_PREP_DIV, config->divider.prep_div) |
  604. FIELD_PREP(OPMODE_PLLCFG_MPLL_CKO_DIV, config->divider.mpll_cko_div) |
  605. FIELD_PREP(OPMODE_PLLCFG_OPMODE, config->opmode) |
  606. FIELD_PREP(OPMODE_PLLCFG_REF_CNTRL, config->divider.ref_cntrl) |
  607. FIELD_PREP(OPMODE_PLLCFG_MPLL_N_CNTRL, config->divider.mpll_n_cntrl);
  608. dw_hdmi_phy_i2c_write(
  609. hdmi,
  610. opmode_pllcfg,
  611. DW_HDMI_TX_PHY_GEN2_OPMODE_PLLCFG
  612. );
  613. pllcurrgmpctrl = FIELD_PREP(PLLCURRGMPCTRL_MPLL_GMP_CNTRL, config->charge_pump.gmp_cntrl) |
  614. FIELD_PREP(PLLCURRGMPCTRL_MPLL_PROP_CNTRL, config->charge_pump.prop_cntrl) |
  615. FIELD_PREP(PLLCURRGMPCTRL_MPLL_INT_CNTRL, config->charge_pump.int_cntrl);
  616. dw_hdmi_phy_i2c_write(
  617. hdmi,
  618. pllcurrgmpctrl,
  619. DW_HDMI_TX_PHY_GEN2_PLLCURRGMPCTRL
  620. );
  621. plldivctrl = FIELD_PREP(PLLDIVCTRL_VCO_CNTRL, config->divider.vco_cntrl) |
  622. FIELD_PREP(PLLDIVCTRL_MPLL_MULTIPLIER, config->divider.mpll_multiplier);
  623. dw_hdmi_phy_i2c_write(
  624. hdmi,
  625. plldivctrl,
  626. DW_HDMI_TX_PHY_GEN2_PLLDIVCTRL
  627. );
  628. txterm = FIELD_PREP(TXTERM_D_TX_TERM, config->voltage.txterm);
  629. dw_hdmi_phy_i2c_write(
  630. hdmi,
  631. txterm,
  632. DW_HDMI_TX_PHY_GEN2_TXTERM
  633. );
  634. vlevctrl_pllmeasctrl = FIELD_PREP(VLEVCTRL_PLLMEASCTRL_SUP_TX_LVL, config->voltage.sup_txlvl);
  635. dw_hdmi_phy_i2c_write(
  636. hdmi,
  637. vlevctrl_pllmeasctrl,
  638. DW_HDMI_TX_PHY_GEN2_VLEVCTRL_PLLMEASCTRL
  639. );
  640. cksymtxctrl = FIELD_PREP(CKSYMTXCTRL_OVERRIDE_5, 0x1) |
  641. FIELD_PREP(CKSYMTXCTRL_TX_TRAON, config->voltage.tx_traon) |
  642. FIELD_PREP(CKSYMTXCTRL_TX_TRBON, config->voltage.tx_trbon) |
  643. FIELD_PREP(CKSYMTXCTRL_TX_SYMON, config->voltage.tx_symon) |
  644. FIELD_PREP(CKSYMTXCTRL_CK_SYMON, config->voltage.ck_symon);
  645. dw_hdmi_phy_i2c_write(
  646. hdmi,
  647. cksymtxctrl,
  648. DW_HDMI_TX_PHY_GEN2_CKSYMTXCTRL
  649. );
  650. return 0;
  651. }
  652. #endif