diu_ch7301.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2014 Freescale Semiconductor, Inc.
  4. * Copyright 2019 NXP
  5. * Authors: Priyanka Jain <Priyanka.Jain@freescale.com>
  6. * Wang Dongsheng <dongsheng.wang@freescale.com>
  7. *
  8. * This file is copied and modified from the original t1040qds/diu.c.
  9. * Encoder can be used in T104x and LSx Platform.
  10. */
  11. #include <common.h>
  12. #include <stdio_dev.h>
  13. #include <i2c.h>
  14. #include <linux/delay.h>
  15. #define I2C_DVI_INPUT_DATA_FORMAT_REG 0x1F
  16. #define I2C_DVI_PLL_CHARGE_CNTL_REG 0x33
  17. #define I2C_DVI_PLL_DIVIDER_REG 0x34
  18. #define I2C_DVI_PLL_SUPPLY_CNTL_REG 0x35
  19. #define I2C_DVI_PLL_FILTER_REG 0x36
  20. #define I2C_DVI_TEST_PATTERN_REG 0x48
  21. #define I2C_DVI_POWER_MGMT_REG 0x49
  22. #define I2C_DVI_LOCK_STATE_REG 0x4D
  23. #define I2C_DVI_SYNC_POLARITY_REG 0x56
  24. /*
  25. * Set VSYNC/HSYNC to active high. This is polarity of sync signals
  26. * from DIU->DVI. The DIU default is active igh, so DVI is set to
  27. * active high.
  28. */
  29. #define I2C_DVI_INPUT_DATA_FORMAT_VAL 0x98
  30. #define I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL 0x06
  31. #define I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL 0x26
  32. #define I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL 0xA0
  33. #define I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL 0x08
  34. #define I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL 0x16
  35. #define I2C_DVI_PLL_FILTER_LOW_SPEED_VAL 0x60
  36. /* Clear test pattern */
  37. #define I2C_DVI_TEST_PATTERN_VAL 0x18
  38. /* Exit Power-down mode */
  39. #define I2C_DVI_POWER_MGMT_VAL 0xC0
  40. /* Monitor polarity is handled via DVI Sync Polarity Register */
  41. #define I2C_DVI_SYNC_POLARITY_VAL 0x00
  42. /* Programming of HDMI Chrontel CH7301 connector */
  43. int diu_set_dvi_encoder(unsigned int pixclock)
  44. {
  45. int ret;
  46. u8 temp;
  47. temp = I2C_DVI_TEST_PATTERN_VAL;
  48. #if CONFIG_IS_ENABLED(DM_I2C)
  49. struct udevice *dev;
  50. ret = i2c_get_chip_for_busnum(CONFIG_SYS_I2C_DVI_BUS_NUM,
  51. CONFIG_SYS_I2C_DVI_ADDR,
  52. 1, &dev);
  53. if (ret) {
  54. printf("%s: Cannot find udev for a bus %d\n", __func__,
  55. CONFIG_SYS_I2C_DVI_BUS_NUM);
  56. return ret;
  57. }
  58. ret = dm_i2c_write(dev, I2C_DVI_TEST_PATTERN_REG, &temp, 1);
  59. if (ret) {
  60. puts("I2C: failed to select proper dvi test pattern\n");
  61. return ret;
  62. }
  63. temp = I2C_DVI_INPUT_DATA_FORMAT_VAL;
  64. ret = dm_i2c_write(dev, I2C_DVI_INPUT_DATA_FORMAT_REG, &temp, 1);
  65. if (ret) {
  66. puts("I2C: failed to select dvi input data format\n");
  67. return ret;
  68. }
  69. /* Set Sync polarity register */
  70. temp = I2C_DVI_SYNC_POLARITY_VAL;
  71. ret = dm_i2c_write(dev, I2C_DVI_SYNC_POLARITY_REG, &temp, 1);
  72. if (ret) {
  73. puts("I2C: failed to select dvi syc polarity\n");
  74. return ret;
  75. }
  76. /* Set PLL registers based on pixel clock rate*/
  77. if (pixclock > 65000000) {
  78. temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL;
  79. ret = dm_i2c_write(dev, I2C_DVI_PLL_CHARGE_CNTL_REG, &temp, 1);
  80. if (ret) {
  81. puts("I2C: failed to select dvi pll charge_cntl\n");
  82. return ret;
  83. }
  84. temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL;
  85. ret = dm_i2c_write(dev, I2C_DVI_PLL_DIVIDER_REG, &temp, 1);
  86. if (ret) {
  87. puts("I2C: failed to select dvi pll divider\n");
  88. return ret;
  89. }
  90. temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL;
  91. ret = dm_i2c_write(dev, I2C_DVI_PLL_FILTER_REG, &temp, 1);
  92. if (ret) {
  93. puts("I2C: failed to select dvi pll filter\n");
  94. return ret;
  95. }
  96. } else {
  97. temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL;
  98. ret = dm_i2c_write(dev, I2C_DVI_PLL_CHARGE_CNTL_REG, &temp, 1);
  99. if (ret) {
  100. puts("I2C: failed to select dvi pll charge_cntl\n");
  101. return ret;
  102. }
  103. temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL;
  104. ret = dm_i2c_write(dev, I2C_DVI_PLL_DIVIDER_REG, &temp, 1);
  105. if (ret) {
  106. puts("I2C: failed to select dvi pll divider\n");
  107. return ret;
  108. }
  109. temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL;
  110. ret = dm_i2c_write(dev, I2C_DVI_PLL_FILTER_REG, &temp, 1);
  111. if (ret) {
  112. puts("I2C: failed to select dvi pll filter\n");
  113. return ret;
  114. }
  115. }
  116. temp = I2C_DVI_POWER_MGMT_VAL;
  117. ret = dm_i2c_write(dev, I2C_DVI_POWER_MGMT_REG, &temp, 1);
  118. if (ret) {
  119. puts("I2C: failed to select dvi power mgmt\n");
  120. return ret;
  121. }
  122. #else
  123. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_TEST_PATTERN_REG, 1,
  124. &temp, 1);
  125. if (ret) {
  126. puts("I2C: failed to select proper dvi test pattern\n");
  127. return ret;
  128. }
  129. temp = I2C_DVI_INPUT_DATA_FORMAT_VAL;
  130. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_INPUT_DATA_FORMAT_REG,
  131. 1, &temp, 1);
  132. if (ret) {
  133. puts("I2C: failed to select dvi input data format\n");
  134. return ret;
  135. }
  136. /* Set Sync polarity register */
  137. temp = I2C_DVI_SYNC_POLARITY_VAL;
  138. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_SYNC_POLARITY_REG, 1,
  139. &temp, 1);
  140. if (ret) {
  141. puts("I2C: failed to select dvi syc polarity\n");
  142. return ret;
  143. }
  144. /* Set PLL registers based on pixel clock rate*/
  145. if (pixclock > 65000000) {
  146. temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL;
  147. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
  148. I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
  149. if (ret) {
  150. puts("I2C: failed to select dvi pll charge_cntl\n");
  151. return ret;
  152. }
  153. temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL;
  154. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
  155. I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
  156. if (ret) {
  157. puts("I2C: failed to select dvi pll divider\n");
  158. return ret;
  159. }
  160. temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL;
  161. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
  162. I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
  163. if (ret) {
  164. puts("I2C: failed to select dvi pll filter\n");
  165. return ret;
  166. }
  167. } else {
  168. temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL;
  169. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
  170. I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
  171. if (ret) {
  172. puts("I2C: failed to select dvi pll charge_cntl\n");
  173. return ret;
  174. }
  175. temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL;
  176. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
  177. I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
  178. if (ret) {
  179. puts("I2C: failed to select dvi pll divider\n");
  180. return ret;
  181. }
  182. temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL;
  183. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
  184. I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
  185. if (ret) {
  186. puts("I2C: failed to select dvi pll filter\n");
  187. return ret;
  188. }
  189. }
  190. temp = I2C_DVI_POWER_MGMT_VAL;
  191. ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_POWER_MGMT_REG, 1,
  192. &temp, 1);
  193. if (ret) {
  194. puts("I2C: failed to select dvi power mgmt\n");
  195. return ret;
  196. }
  197. #endif
  198. udelay(500);
  199. return 0;
  200. }