phy-mtk-hdmi-mt8173.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2014 MediaTek Inc.
  4. * Author: Jie Qiu <[email protected]>
  5. */
  6. #include "phy-mtk-hdmi.h"
  7. #include "phy-mtk-io.h"
  8. #define HDMI_CON0 0x00
  9. #define RG_HDMITX_PLL_EN BIT(31)
  10. #define RG_HDMITX_PLL_FBKDIV GENMASK(30, 24)
  11. #define RG_HDMITX_PLL_FBKSEL GENMASK(23, 22)
  12. #define RG_HDMITX_PLL_PREDIV GENMASK(21, 20)
  13. #define RG_HDMITX_PLL_POSDIV GENMASK(19, 18)
  14. #define RG_HDMITX_PLL_RST_DLY GENMASK(17, 16)
  15. #define RG_HDMITX_PLL_IR GENMASK(15, 12)
  16. #define RG_HDMITX_PLL_IC GENMASK(11, 8)
  17. #define RG_HDMITX_PLL_BP GENMASK(7, 4)
  18. #define RG_HDMITX_PLL_BR GENMASK(3, 2)
  19. #define RG_HDMITX_PLL_BC GENMASK(1, 0)
  20. #define HDMI_CON1 0x04
  21. #define RG_HDMITX_PLL_DIVEN GENMASK(31, 29)
  22. #define RG_HDMITX_PLL_AUTOK_EN BIT(28)
  23. #define RG_HDMITX_PLL_AUTOK_KF GENMASK(27, 26)
  24. #define RG_HDMITX_PLL_AUTOK_KS GENMASK(25, 24)
  25. #define RG_HDMITX_PLL_AUTOK_LOAD BIT(23)
  26. #define RG_HDMITX_PLL_BAND GENMASK(21, 16)
  27. #define RG_HDMITX_PLL_REF_SEL BIT(15)
  28. #define RG_HDMITX_PLL_BIAS_EN BIT(14)
  29. #define RG_HDMITX_PLL_BIAS_LPF_EN BIT(13)
  30. #define RG_HDMITX_PLL_TXDIV_EN BIT(12)
  31. #define RG_HDMITX_PLL_TXDIV GENMASK(11, 10)
  32. #define RG_HDMITX_PLL_LVROD_EN BIT(9)
  33. #define RG_HDMITX_PLL_MONVC_EN BIT(8)
  34. #define RG_HDMITX_PLL_MONCK_EN BIT(7)
  35. #define RG_HDMITX_PLL_MONREF_EN BIT(6)
  36. #define RG_HDMITX_PLL_TST_EN BIT(5)
  37. #define RG_HDMITX_PLL_TST_CK_EN BIT(4)
  38. #define RG_HDMITX_PLL_TST_SEL GENMASK(3, 0)
  39. #define HDMI_CON2 0x08
  40. #define RGS_HDMITX_PLL_AUTOK_BAND GENMASK(14, 8)
  41. #define RGS_HDMITX_PLL_AUTOK_FAIL BIT(1)
  42. #define RG_HDMITX_EN_TX_CKLDO BIT(0)
  43. #define HDMI_CON3 0x0c
  44. #define RG_HDMITX_SER_EN GENMASK(31, 28)
  45. #define RG_HDMITX_PRD_EN GENMASK(27, 24)
  46. #define RG_HDMITX_PRD_IMP_EN GENMASK(23, 20)
  47. #define RG_HDMITX_DRV_EN GENMASK(19, 16)
  48. #define RG_HDMITX_DRV_IMP_EN GENMASK(15, 12)
  49. #define RG_HDMITX_MHLCK_FORCE BIT(10)
  50. #define RG_HDMITX_MHLCK_PPIX_EN BIT(9)
  51. #define RG_HDMITX_MHLCK_EN BIT(8)
  52. #define RG_HDMITX_SER_DIN_SEL GENMASK(7, 4)
  53. #define RG_HDMITX_SER_5T1_BIST_EN BIT(3)
  54. #define RG_HDMITX_SER_BIST_TOG BIT(2)
  55. #define RG_HDMITX_SER_DIN_TOG BIT(1)
  56. #define RG_HDMITX_SER_CLKDIG_INV BIT(0)
  57. #define HDMI_CON4 0x10
  58. #define RG_HDMITX_PRD_IBIAS_CLK GENMASK(27, 24)
  59. #define RG_HDMITX_PRD_IBIAS_D2 GENMASK(19, 16)
  60. #define RG_HDMITX_PRD_IBIAS_D1 GENMASK(11, 8)
  61. #define RG_HDMITX_PRD_IBIAS_D0 GENMASK(3, 0)
  62. #define HDMI_CON5 0x14
  63. #define RG_HDMITX_DRV_IBIAS_CLK GENMASK(29, 24)
  64. #define RG_HDMITX_DRV_IBIAS_D2 GENMASK(21, 16)
  65. #define RG_HDMITX_DRV_IBIAS_D1 GENMASK(13, 8)
  66. #define RG_HDMITX_DRV_IBIAS_D0 GENMASK(5, 0)
  67. #define HDMI_CON6 0x18
  68. #define RG_HDMITX_DRV_IMP_CLK GENMASK(29, 24)
  69. #define RG_HDMITX_DRV_IMP_D2 GENMASK(21, 16)
  70. #define RG_HDMITX_DRV_IMP_D1 GENMASK(13, 8)
  71. #define RG_HDMITX_DRV_IMP_D0 GENMASK(5, 0)
  72. #define HDMI_CON7 0x1c
  73. #define RG_HDMITX_MHLCK_DRV_IBIAS GENMASK(31, 27)
  74. #define RG_HDMITX_SER_DIN GENMASK(25, 16)
  75. #define RG_HDMITX_CHLDC_TST GENMASK(15, 12)
  76. #define RG_HDMITX_CHLCK_TST GENMASK(11, 8)
  77. #define RG_HDMITX_RESERVE GENMASK(7, 0)
  78. #define HDMI_CON8 0x20
  79. #define RGS_HDMITX_2T1_LEV GENMASK(19, 16)
  80. #define RGS_HDMITX_2T1_EDG GENMASK(15, 12)
  81. #define RGS_HDMITX_5T1_LEV GENMASK(11, 8)
  82. #define RGS_HDMITX_5T1_EDG GENMASK(7, 4)
  83. #define RGS_HDMITX_PLUG_TST BIT(0)
  84. static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
  85. {
  86. struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
  87. void __iomem *base = hdmi_phy->regs;
  88. mtk_phy_set_bits(base + HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
  89. mtk_phy_set_bits(base + HDMI_CON0, RG_HDMITX_PLL_POSDIV);
  90. mtk_phy_clear_bits(base + HDMI_CON3, RG_HDMITX_MHLCK_EN);
  91. mtk_phy_set_bits(base + HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
  92. usleep_range(100, 150);
  93. mtk_phy_set_bits(base + HDMI_CON0, RG_HDMITX_PLL_EN);
  94. usleep_range(100, 150);
  95. mtk_phy_set_bits(base + HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
  96. mtk_phy_set_bits(base + HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
  97. return 0;
  98. }
  99. static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
  100. {
  101. struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
  102. void __iomem *base = hdmi_phy->regs;
  103. mtk_phy_clear_bits(base + HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
  104. mtk_phy_clear_bits(base + HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
  105. usleep_range(100, 150);
  106. mtk_phy_clear_bits(base + HDMI_CON0, RG_HDMITX_PLL_EN);
  107. usleep_range(100, 150);
  108. mtk_phy_clear_bits(base + HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
  109. mtk_phy_clear_bits(base + HDMI_CON0, RG_HDMITX_PLL_POSDIV);
  110. mtk_phy_clear_bits(base + HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
  111. usleep_range(100, 150);
  112. }
  113. static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
  114. unsigned long *parent_rate)
  115. {
  116. struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
  117. hdmi_phy->pll_rate = rate;
  118. if (rate <= 74250000)
  119. *parent_rate = rate;
  120. else
  121. *parent_rate = rate / 2;
  122. return rate;
  123. }
  124. static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
  125. unsigned long parent_rate)
  126. {
  127. struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
  128. void __iomem *base = hdmi_phy->regs;
  129. unsigned int pre_div;
  130. unsigned int div;
  131. unsigned int pre_ibias;
  132. unsigned int hdmi_ibias;
  133. unsigned int imp_en;
  134. dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__,
  135. rate, parent_rate);
  136. if (rate <= 27000000) {
  137. pre_div = 0;
  138. div = 3;
  139. } else if (rate <= 74250000) {
  140. pre_div = 1;
  141. div = 2;
  142. } else {
  143. pre_div = 1;
  144. div = 1;
  145. }
  146. mtk_phy_update_field(base + HDMI_CON0, RG_HDMITX_PLL_PREDIV, pre_div);
  147. mtk_phy_set_bits(base + HDMI_CON0, RG_HDMITX_PLL_POSDIV);
  148. mtk_phy_update_bits(base + HDMI_CON0,
  149. RG_HDMITX_PLL_IC | RG_HDMITX_PLL_IR,
  150. FIELD_PREP(RG_HDMITX_PLL_IC, 0x1) |
  151. FIELD_PREP(RG_HDMITX_PLL_IR, 0x1));
  152. mtk_phy_update_field(base + HDMI_CON1, RG_HDMITX_PLL_TXDIV, div);
  153. mtk_phy_update_bits(base + HDMI_CON0,
  154. RG_HDMITX_PLL_FBKSEL | RG_HDMITX_PLL_FBKDIV,
  155. FIELD_PREP(RG_HDMITX_PLL_FBKSEL, 0x1) |
  156. FIELD_PREP(RG_HDMITX_PLL_FBKDIV, 19));
  157. mtk_phy_update_field(base + HDMI_CON1, RG_HDMITX_PLL_DIVEN, 0x2);
  158. mtk_phy_update_bits(base + HDMI_CON0,
  159. RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC |
  160. RG_HDMITX_PLL_BR,
  161. FIELD_PREP(RG_HDMITX_PLL_BP, 0xc) |
  162. FIELD_PREP(RG_HDMITX_PLL_BC, 0x2) |
  163. FIELD_PREP(RG_HDMITX_PLL_BR, 0x1));
  164. if (rate < 165000000) {
  165. mtk_phy_clear_bits(base + HDMI_CON3, RG_HDMITX_PRD_IMP_EN);
  166. pre_ibias = 0x3;
  167. imp_en = 0x0;
  168. hdmi_ibias = hdmi_phy->ibias;
  169. } else {
  170. mtk_phy_set_bits(base + HDMI_CON3, RG_HDMITX_PRD_IMP_EN);
  171. pre_ibias = 0x6;
  172. imp_en = 0xf;
  173. hdmi_ibias = hdmi_phy->ibias_up;
  174. }
  175. mtk_phy_update_bits(base + HDMI_CON4,
  176. RG_HDMITX_PRD_IBIAS_CLK | RG_HDMITX_PRD_IBIAS_D2 |
  177. RG_HDMITX_PRD_IBIAS_D1 | RG_HDMITX_PRD_IBIAS_D0,
  178. FIELD_PREP(RG_HDMITX_PRD_IBIAS_CLK, pre_ibias) |
  179. FIELD_PREP(RG_HDMITX_PRD_IBIAS_D2, pre_ibias) |
  180. FIELD_PREP(RG_HDMITX_PRD_IBIAS_D1, pre_ibias) |
  181. FIELD_PREP(RG_HDMITX_PRD_IBIAS_D0, pre_ibias));
  182. mtk_phy_update_field(base + HDMI_CON3, RG_HDMITX_DRV_IMP_EN, imp_en);
  183. mtk_phy_update_bits(base + HDMI_CON6,
  184. RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 |
  185. RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0,
  186. FIELD_PREP(RG_HDMITX_DRV_IMP_CLK, hdmi_phy->drv_imp_clk) |
  187. FIELD_PREP(RG_HDMITX_DRV_IMP_D2, hdmi_phy->drv_imp_d2) |
  188. FIELD_PREP(RG_HDMITX_DRV_IMP_D1, hdmi_phy->drv_imp_d1) |
  189. FIELD_PREP(RG_HDMITX_DRV_IMP_D0, hdmi_phy->drv_imp_d0));
  190. mtk_phy_update_bits(base + HDMI_CON5,
  191. RG_HDMITX_DRV_IBIAS_CLK | RG_HDMITX_DRV_IBIAS_D2 |
  192. RG_HDMITX_DRV_IBIAS_D1 | RG_HDMITX_DRV_IBIAS_D0,
  193. FIELD_PREP(RG_HDMITX_DRV_IBIAS_CLK, hdmi_ibias) |
  194. FIELD_PREP(RG_HDMITX_DRV_IBIAS_D2, hdmi_ibias) |
  195. FIELD_PREP(RG_HDMITX_DRV_IBIAS_D1, hdmi_ibias) |
  196. FIELD_PREP(RG_HDMITX_DRV_IBIAS_D0, hdmi_ibias));
  197. return 0;
  198. }
  199. static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
  200. unsigned long parent_rate)
  201. {
  202. struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
  203. return hdmi_phy->pll_rate;
  204. }
  205. static const struct clk_ops mtk_hdmi_phy_pll_ops = {
  206. .prepare = mtk_hdmi_pll_prepare,
  207. .unprepare = mtk_hdmi_pll_unprepare,
  208. .set_rate = mtk_hdmi_pll_set_rate,
  209. .round_rate = mtk_hdmi_pll_round_rate,
  210. .recalc_rate = mtk_hdmi_pll_recalc_rate,
  211. };
  212. static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
  213. {
  214. mtk_phy_set_bits(hdmi_phy->regs + HDMI_CON3,
  215. RG_HDMITX_SER_EN | RG_HDMITX_PRD_EN |
  216. RG_HDMITX_DRV_EN);
  217. usleep_range(100, 150);
  218. }
  219. static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
  220. {
  221. mtk_phy_clear_bits(hdmi_phy->regs + HDMI_CON3,
  222. RG_HDMITX_DRV_EN | RG_HDMITX_PRD_EN |
  223. RG_HDMITX_SER_EN);
  224. }
  225. struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = {
  226. .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
  227. .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
  228. .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
  229. .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
  230. };
  231. MODULE_AUTHOR("Jie Qiu <[email protected]>");
  232. MODULE_DESCRIPTION("MediaTek MT8173 HDMI PHY Driver");
  233. MODULE_LICENSE("GPL v2");