mtk_mt2701_hdmi_phy.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2018 MediaTek Inc.
  4. * Author: Chunhui Dai <chunhui.dai@mediatek.com>
  5. */
  6. #include "mtk_hdmi_phy.h"
  7. #define HDMI_CON0 0x00
  8. #define RG_HDMITX_DRV_IBIAS 0
  9. #define RG_HDMITX_DRV_IBIAS_MASK (0x3f << 0)
  10. #define RG_HDMITX_EN_SER 12
  11. #define RG_HDMITX_EN_SER_MASK (0x0f << 12)
  12. #define RG_HDMITX_EN_SLDO 16
  13. #define RG_HDMITX_EN_SLDO_MASK (0x0f << 16)
  14. #define RG_HDMITX_EN_PRED 20
  15. #define RG_HDMITX_EN_PRED_MASK (0x0f << 20)
  16. #define RG_HDMITX_EN_IMP 24
  17. #define RG_HDMITX_EN_IMP_MASK (0x0f << 24)
  18. #define RG_HDMITX_EN_DRV 28
  19. #define RG_HDMITX_EN_DRV_MASK (0x0f << 28)
  20. #define HDMI_CON1 0x04
  21. #define RG_HDMITX_PRED_IBIAS 18
  22. #define RG_HDMITX_PRED_IBIAS_MASK (0x0f << 18)
  23. #define RG_HDMITX_PRED_IMP (0x01 << 22)
  24. #define RG_HDMITX_DRV_IMP 26
  25. #define RG_HDMITX_DRV_IMP_MASK (0x3f << 26)
  26. #define HDMI_CON2 0x08
  27. #define RG_HDMITX_EN_TX_CKLDO (0x01 << 0)
  28. #define RG_HDMITX_EN_TX_POSDIV (0x01 << 1)
  29. #define RG_HDMITX_TX_POSDIV 3
  30. #define RG_HDMITX_TX_POSDIV_MASK (0x03 << 3)
  31. #define RG_HDMITX_EN_MBIAS (0x01 << 6)
  32. #define RG_HDMITX_MBIAS_LPF_EN (0x01 << 7)
  33. #define HDMI_CON4 0x10
  34. #define RG_HDMITX_RESERVE_MASK (0xffffffff << 0)
  35. #define HDMI_CON6 0x18
  36. #define RG_HTPLL_BR 0
  37. #define RG_HTPLL_BR_MASK (0x03 << 0)
  38. #define RG_HTPLL_BC 2
  39. #define RG_HTPLL_BC_MASK (0x03 << 2)
  40. #define RG_HTPLL_BP 4
  41. #define RG_HTPLL_BP_MASK (0x0f << 4)
  42. #define RG_HTPLL_IR 8
  43. #define RG_HTPLL_IR_MASK (0x0f << 8)
  44. #define RG_HTPLL_IC 12
  45. #define RG_HTPLL_IC_MASK (0x0f << 12)
  46. #define RG_HTPLL_POSDIV 16
  47. #define RG_HTPLL_POSDIV_MASK (0x03 << 16)
  48. #define RG_HTPLL_PREDIV 18
  49. #define RG_HTPLL_PREDIV_MASK (0x03 << 18)
  50. #define RG_HTPLL_FBKSEL 20
  51. #define RG_HTPLL_FBKSEL_MASK (0x03 << 20)
  52. #define RG_HTPLL_RLH_EN (0x01 << 22)
  53. #define RG_HTPLL_FBKDIV 24
  54. #define RG_HTPLL_FBKDIV_MASK (0x7f << 24)
  55. #define RG_HTPLL_EN (0x01 << 31)
  56. #define HDMI_CON7 0x1c
  57. #define RG_HTPLL_AUTOK_EN (0x01 << 23)
  58. #define RG_HTPLL_DIVEN 28
  59. #define RG_HTPLL_DIVEN_MASK (0x07 << 28)
  60. static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
  61. {
  62. struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
  63. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
  64. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
  65. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
  66. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
  67. usleep_range(80, 100);
  68. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
  69. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
  70. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
  71. usleep_range(80, 100);
  72. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
  73. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
  74. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
  75. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
  76. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
  77. usleep_range(80, 100);
  78. return 0;
  79. }
  80. static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
  81. {
  82. struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
  83. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
  84. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
  85. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
  86. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
  87. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
  88. usleep_range(80, 100);
  89. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
  90. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
  91. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
  92. usleep_range(80, 100);
  93. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
  94. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
  95. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
  96. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
  97. usleep_range(80, 100);
  98. }
  99. static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
  100. unsigned long parent_rate)
  101. {
  102. struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
  103. u32 pos_div;
  104. if (rate <= 64000000)
  105. pos_div = 3;
  106. else if (rate <= 12800000)
  107. pos_div = 1;
  108. else
  109. pos_div = 1;
  110. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK);
  111. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
  112. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC),
  113. RG_HTPLL_IC_MASK);
  114. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR),
  115. RG_HTPLL_IR_MASK);
  116. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON2, (pos_div << RG_HDMITX_TX_POSDIV),
  117. RG_HDMITX_TX_POSDIV_MASK);
  118. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (1 << RG_HTPLL_FBKSEL),
  119. RG_HTPLL_FBKSEL_MASK);
  120. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (19 << RG_HTPLL_FBKDIV),
  121. RG_HTPLL_FBKDIV_MASK);
  122. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON7, (0x2 << RG_HTPLL_DIVEN),
  123. RG_HTPLL_DIVEN_MASK);
  124. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0xc << RG_HTPLL_BP),
  125. RG_HTPLL_BP_MASK);
  126. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x2 << RG_HTPLL_BC),
  127. RG_HTPLL_BC_MASK);
  128. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_BR),
  129. RG_HTPLL_BR_MASK);
  130. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PRED_IMP);
  131. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x3 << RG_HDMITX_PRED_IBIAS),
  132. RG_HDMITX_PRED_IBIAS_MASK);
  133. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_IMP_MASK);
  134. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x28 << RG_HDMITX_DRV_IMP),
  135. RG_HDMITX_DRV_IMP_MASK);
  136. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, 0x28, RG_HDMITX_RESERVE_MASK);
  137. mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, (0xa << RG_HDMITX_DRV_IBIAS),
  138. RG_HDMITX_DRV_IBIAS_MASK);
  139. return 0;
  140. }
  141. static const struct clk_ops mtk_hdmi_phy_pll_ops = {
  142. .prepare = mtk_hdmi_pll_prepare,
  143. .unprepare = mtk_hdmi_pll_unprepare,
  144. .set_rate = mtk_hdmi_pll_set_rate,
  145. .round_rate = mtk_hdmi_pll_round_rate,
  146. .recalc_rate = mtk_hdmi_pll_recalc_rate,
  147. };
  148. static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
  149. {
  150. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
  151. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
  152. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
  153. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
  154. usleep_range(80, 100);
  155. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
  156. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
  157. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
  158. usleep_range(80, 100);
  159. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
  160. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
  161. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
  162. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
  163. mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
  164. usleep_range(80, 100);
  165. }
  166. static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
  167. {
  168. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
  169. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
  170. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
  171. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
  172. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
  173. usleep_range(80, 100);
  174. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
  175. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
  176. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
  177. usleep_range(80, 100);
  178. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
  179. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
  180. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
  181. mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
  182. usleep_range(80, 100);
  183. }
  184. struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = {
  185. .tz_disabled = true,
  186. .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
  187. .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
  188. .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
  189. };
  190. MODULE_AUTHOR("Chunhui Dai <chunhui.dai@mediatek.com>");
  191. MODULE_DESCRIPTION("MediaTek HDMI PHY Driver");
  192. MODULE_LICENSE("GPL v2");