ddk750_display.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "ddk750_reg.h"
  2. #include "ddk750_help.h"
  3. #include "ddk750_display.h"
  4. #include "ddk750_power.h"
  5. #include "ddk750_dvi.h"
  6. #define primaryWaitVerticalSync(delay) waitNextVerticalSync(0, delay)
  7. static void setDisplayControl(int ctrl, int disp_state)
  8. {
  9. /* state != 0 means turn on both timing & plane en_bit */
  10. unsigned long ulDisplayCtrlReg, ulReservedBits;
  11. int cnt;
  12. cnt = 0;
  13. /* Set the primary display control */
  14. if (!ctrl) {
  15. ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL);
  16. /* Turn on/off the Panel display control */
  17. if (disp_state) {
  18. /* Timing should be enabled first before enabling the plane
  19. * because changing at the same time does not guarantee that
  20. * the plane will also enabled or disabled.
  21. */
  22. ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg,
  23. PANEL_DISPLAY_CTRL, TIMING, ENABLE);
  24. POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
  25. ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg,
  26. PANEL_DISPLAY_CTRL, PLANE, ENABLE);
  27. /* Added some masks to mask out the reserved bits.
  28. * Sometimes, the reserved bits are set/reset randomly when
  29. * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register
  30. * reserved bits are needed to be masked out.
  31. */
  32. ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) |
  33. FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) |
  34. FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE);
  35. /* Somehow the register value on the plane is not set
  36. * until a few delay. Need to write
  37. * and read it a couple times
  38. */
  39. do {
  40. cnt++;
  41. POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
  42. } while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) !=
  43. (ulDisplayCtrlReg & ~ulReservedBits));
  44. printk("Set Panel Plane enbit:after tried %d times\n", cnt);
  45. } else {
  46. /* When turning off, there is no rule on the programming
  47. * sequence since whenever the clock is off, then it does not
  48. * matter whether the plane is enabled or disabled.
  49. * Note: Modifying the plane bit will take effect on the
  50. * next vertical sync. Need to find out if it is necessary to
  51. * wait for 1 vsync before modifying the timing enable bit.
  52. * */
  53. ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg,
  54. PANEL_DISPLAY_CTRL, PLANE, DISABLE);
  55. POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
  56. ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg,
  57. PANEL_DISPLAY_CTRL, TIMING, DISABLE);
  58. POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
  59. }
  60. } else {
  61. /* Set the secondary display control */
  62. ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL);
  63. if (disp_state) {
  64. /* Timing should be enabled first before enabling the plane because changing at the
  65. same time does not guarantee that the plane will also enabled or disabled.
  66. */
  67. ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg,
  68. CRT_DISPLAY_CTRL, TIMING, ENABLE);
  69. POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
  70. ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg,
  71. CRT_DISPLAY_CTRL, PLANE, ENABLE);
  72. /* Added some masks to mask out the reserved bits.
  73. * Sometimes, the reserved bits are set/reset randomly when
  74. * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register
  75. * reserved bits are needed to be masked out.
  76. */
  77. ulReservedBits = FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) |
  78. FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) |
  79. FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE) |
  80. FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_4_MASK, ENABLE);
  81. do {
  82. cnt++;
  83. POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
  84. } while ((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) !=
  85. (ulDisplayCtrlReg & ~ulReservedBits));
  86. printk("Set Crt Plane enbit:after tried %d times\n", cnt);
  87. } else {
  88. /* When turning off, there is no rule on the programming
  89. * sequence since whenever the clock is off, then it does not
  90. * matter whether the plane is enabled or disabled.
  91. * Note: Modifying the plane bit will take effect on the next
  92. * vertical sync. Need to find out if it is necessary to
  93. * wait for 1 vsync before modifying the timing enable bit.
  94. */
  95. ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg,
  96. CRT_DISPLAY_CTRL, PLANE, DISABLE);
  97. POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
  98. ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg,
  99. CRT_DISPLAY_CTRL, TIMING, DISABLE);
  100. POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
  101. }
  102. }
  103. }
  104. static void waitNextVerticalSync(int ctrl, int delay)
  105. {
  106. unsigned int status;
  107. if (!ctrl) {
  108. /* primary controller */
  109. /* Do not wait when the Primary PLL is off or display control is already off.
  110. This will prevent the software to wait forever. */
  111. if ((FIELD_GET(PEEK32(PANEL_PLL_CTRL), PANEL_PLL_CTRL, POWER) ==
  112. PANEL_PLL_CTRL_POWER_OFF) ||
  113. (FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) ==
  114. PANEL_DISPLAY_CTRL_TIMING_DISABLE)) {
  115. return;
  116. }
  117. while (delay-- > 0) {
  118. /* Wait for end of vsync. */
  119. do {
  120. status = FIELD_GET(PEEK32(SYSTEM_CTRL),
  121. SYSTEM_CTRL,
  122. PANEL_VSYNC);
  123. } while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
  124. /* Wait for start of vsync. */
  125. do {
  126. status = FIELD_GET(PEEK32(SYSTEM_CTRL),
  127. SYSTEM_CTRL,
  128. PANEL_VSYNC);
  129. } while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE);
  130. }
  131. } else {
  132. /* Do not wait when the Primary PLL is off or display control is already off.
  133. This will prevent the software to wait forever. */
  134. if ((FIELD_GET(PEEK32(CRT_PLL_CTRL), CRT_PLL_CTRL, POWER) ==
  135. CRT_PLL_CTRL_POWER_OFF) ||
  136. (FIELD_GET(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) ==
  137. CRT_DISPLAY_CTRL_TIMING_DISABLE)) {
  138. return;
  139. }
  140. while (delay-- > 0) {
  141. /* Wait for end of vsync. */
  142. do {
  143. status = FIELD_GET(PEEK32(SYSTEM_CTRL),
  144. SYSTEM_CTRL,
  145. CRT_VSYNC);
  146. } while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE);
  147. /* Wait for start of vsync. */
  148. do {
  149. status = FIELD_GET(PEEK32(SYSTEM_CTRL),
  150. SYSTEM_CTRL,
  151. CRT_VSYNC);
  152. } while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE);
  153. }
  154. }
  155. }
  156. static void swPanelPowerSequence(int disp, int delay)
  157. {
  158. unsigned int reg;
  159. /* disp should be 1 to open sequence */
  160. reg = PEEK32(PANEL_DISPLAY_CTRL);
  161. reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
  162. POKE32(PANEL_DISPLAY_CTRL, reg);
  163. primaryWaitVerticalSync(delay);
  164. reg = PEEK32(PANEL_DISPLAY_CTRL);
  165. reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, DATA, disp);
  166. POKE32(PANEL_DISPLAY_CTRL, reg);
  167. primaryWaitVerticalSync(delay);
  168. reg = PEEK32(PANEL_DISPLAY_CTRL);
  169. reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, VBIASEN, disp);
  170. POKE32(PANEL_DISPLAY_CTRL, reg);
  171. primaryWaitVerticalSync(delay);
  172. reg = PEEK32(PANEL_DISPLAY_CTRL);
  173. reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
  174. POKE32(PANEL_DISPLAY_CTRL, reg);
  175. primaryWaitVerticalSync(delay);
  176. }
  177. void ddk750_setLogicalDispOut(disp_output_t output)
  178. {
  179. unsigned int reg;
  180. if (output & PNL_2_USAGE) {
  181. /* set panel path controller select */
  182. reg = PEEK32(PANEL_DISPLAY_CTRL);
  183. reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, SELECT, (output & PNL_2_MASK)>>PNL_2_OFFSET);
  184. POKE32(PANEL_DISPLAY_CTRL, reg);
  185. }
  186. if (output & CRT_2_USAGE) {
  187. /* set crt path controller select */
  188. reg = PEEK32(CRT_DISPLAY_CTRL);
  189. reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, SELECT, (output & CRT_2_MASK)>>CRT_2_OFFSET);
  190. /*se blank off */
  191. reg = FIELD_SET(reg, CRT_DISPLAY_CTRL, BLANK, OFF);
  192. POKE32(CRT_DISPLAY_CTRL, reg);
  193. }
  194. if (output & PRI_TP_USAGE) {
  195. /* set primary timing and plane en_bit */
  196. setDisplayControl(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET);
  197. }
  198. if (output & SEC_TP_USAGE) {
  199. /* set secondary timing and plane en_bit*/
  200. setDisplayControl(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET);
  201. }
  202. if (output & PNL_SEQ_USAGE) {
  203. /* set panel sequence */
  204. swPanelPowerSequence((output & PNL_SEQ_MASK) >> PNL_SEQ_OFFSET, 4);
  205. }
  206. if (output & DAC_USAGE)
  207. setDAC((output & DAC_MASK) >> DAC_OFFSET);
  208. if (output & DPMS_USAGE)
  209. ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET);
  210. }