hdmi_phy_8x60.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2013 Red Hat
  4. * Author: Rob Clark <robdclark@gmail.com>
  5. */
  6. #include <linux/delay.h>
  7. #include "hdmi.h"
  8. static void hdmi_phy_8x60_powerup(struct hdmi_phy *phy,
  9. unsigned long int pixclock)
  10. {
  11. /* De-serializer delay D/C for non-lbk mode: */
  12. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG0,
  13. HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(3));
  14. if (pixclock == 27000000) {
  15. /* video_format == HDMI_VFRMT_720x480p60_16_9 */
  16. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1,
  17. HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) |
  18. HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(3));
  19. } else {
  20. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1,
  21. HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) |
  22. HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(4));
  23. }
  24. /* No matter what, start from the power down mode: */
  25. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
  26. HDMI_8x60_PHY_REG2_PD_PWRGEN |
  27. HDMI_8x60_PHY_REG2_PD_PLL |
  28. HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
  29. HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
  30. HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
  31. HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
  32. HDMI_8x60_PHY_REG2_PD_DESER);
  33. /* Turn PowerGen on: */
  34. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
  35. HDMI_8x60_PHY_REG2_PD_PLL |
  36. HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
  37. HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
  38. HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
  39. HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
  40. HDMI_8x60_PHY_REG2_PD_DESER);
  41. /* Turn PLL power on: */
  42. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
  43. HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
  44. HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
  45. HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
  46. HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
  47. HDMI_8x60_PHY_REG2_PD_DESER);
  48. /* Write to HIGH after PLL power down de-assert: */
  49. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3,
  50. HDMI_8x60_PHY_REG3_PLL_ENABLE);
  51. /* ASIC power on; PHY REG9 = 0 */
  52. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0);
  53. /* Enable PLL lock detect, PLL lock det will go high after lock
  54. * Enable the re-time logic
  55. */
  56. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12,
  57. HDMI_8x60_PHY_REG12_RETIMING_EN |
  58. HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN);
  59. /* Drivers are on: */
  60. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
  61. HDMI_8x60_PHY_REG2_PD_DESER);
  62. /* If the RX detector is needed: */
  63. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
  64. HDMI_8x60_PHY_REG2_RCV_SENSE_EN |
  65. HDMI_8x60_PHY_REG2_PD_DESER);
  66. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG4, 0);
  67. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG5, 0);
  68. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG6, 0);
  69. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG7, 0);
  70. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG8, 0);
  71. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0);
  72. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG10, 0);
  73. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG11, 0);
  74. /* If we want to use lock enable based on counting: */
  75. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12,
  76. HDMI_8x60_PHY_REG12_RETIMING_EN |
  77. HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN |
  78. HDMI_8x60_PHY_REG12_FORCE_LOCK);
  79. }
  80. static void hdmi_phy_8x60_powerdown(struct hdmi_phy *phy)
  81. {
  82. /* Assert RESET PHY from controller */
  83. hdmi_phy_write(phy, REG_HDMI_PHY_CTRL,
  84. HDMI_PHY_CTRL_SW_RESET);
  85. udelay(10);
  86. /* De-assert RESET PHY from controller */
  87. hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, 0);
  88. /* Turn off Driver */
  89. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
  90. HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
  91. HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
  92. HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
  93. HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
  94. HDMI_8x60_PHY_REG2_PD_DESER);
  95. udelay(10);
  96. /* Disable PLL */
  97. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, 0);
  98. /* Power down PHY, but keep RX-sense: */
  99. hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
  100. HDMI_8x60_PHY_REG2_RCV_SENSE_EN |
  101. HDMI_8x60_PHY_REG2_PD_PWRGEN |
  102. HDMI_8x60_PHY_REG2_PD_PLL |
  103. HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
  104. HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
  105. HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
  106. HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
  107. HDMI_8x60_PHY_REG2_PD_DESER);
  108. }
  109. static const char * const hdmi_phy_8x60_reg_names[] = {
  110. "core-vdda",
  111. };
  112. static const char * const hdmi_phy_8x60_clk_names[] = {
  113. "slave_iface",
  114. };
  115. const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg = {
  116. .type = MSM_HDMI_PHY_8x60,
  117. .powerup = hdmi_phy_8x60_powerup,
  118. .powerdown = hdmi_phy_8x60_powerdown,
  119. .reg_names = hdmi_phy_8x60_reg_names,
  120. .num_regs = ARRAY_SIZE(hdmi_phy_8x60_reg_names),
  121. .clk_names = hdmi_phy_8x60_clk_names,
  122. .num_clks = ARRAY_SIZE(hdmi_phy_8x60_clk_names),
  123. };