ddk750_mode.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include "ddk750_help.h"
  2. #include "ddk750_reg.h"
  3. #include "ddk750_mode.h"
  4. #include "ddk750_chip.h"
  5. /*
  6. SM750LE only:
  7. This function takes care extra registers and bit fields required to set
  8. up a mode in SM750LE
  9. Explanation about Display Control register:
  10. HW only supports 7 predefined pixel clocks, and clock select is
  11. in bit 29:27 of Display Control register.
  12. */
  13. static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl)
  14. {
  15. unsigned long x, y;
  16. x = pModeParam->horizontal_display_end;
  17. y = pModeParam->vertical_display_end;
  18. /* SM750LE has to set up the top-left and bottom-right
  19. registers as well.
  20. Note that normal SM750/SM718 only use those two register for
  21. auto-centering mode.
  22. */
  23. POKE32(CRT_AUTO_CENTERING_TL,
  24. FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0)
  25. | FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0));
  26. POKE32(CRT_AUTO_CENTERING_BR,
  27. FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y-1)
  28. | FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x-1));
  29. /* Assume common fields in dispControl have been properly set before
  30. calling this function.
  31. This function only sets the extra fields in dispControl.
  32. */
  33. /* Clear bit 29:27 of display control register */
  34. dispControl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLK);
  35. /* Set bit 29:27 of display control register for the right clock */
  36. /* Note that SM750LE only need to supported 7 resoluitons. */
  37. if (x == 800 && y == 600)
  38. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL41);
  39. else if (x == 1024 && y == 768)
  40. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL65);
  41. else if (x == 1152 && y == 864)
  42. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80);
  43. else if (x == 1280 && y == 768)
  44. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80);
  45. else if (x == 1280 && y == 720)
  46. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL74);
  47. else if (x == 1280 && y == 960)
  48. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108);
  49. else if (x == 1280 && y == 1024)
  50. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108);
  51. else /* default to VGA clock */
  52. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL25);
  53. /* Set bit 25:24 of display controller */
  54. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CRTSELECT, CRT);
  55. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, RGBBIT, 24BIT);
  56. /* Set bit 14 of display controller */
  57. dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW);
  58. POKE32(CRT_DISPLAY_CTRL, dispControl);
  59. return dispControl;
  60. }
  61. /* only timing related registers will be programed */
  62. static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t *pll)
  63. {
  64. int ret = 0;
  65. int cnt = 0;
  66. unsigned int ulTmpValue, ulReg;
  67. if (pll->clockType == SECONDARY_PLL) {
  68. /* programe secondary pixel clock */
  69. POKE32(CRT_PLL_CTRL, formatPllReg(pll));
  70. POKE32(CRT_HORIZONTAL_TOTAL,
  71. FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1)
  72. | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1));
  73. POKE32(CRT_HORIZONTAL_SYNC,
  74. FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width)
  75. | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1));
  76. POKE32(CRT_VERTICAL_TOTAL,
  77. FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1)
  78. | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1));
  79. POKE32(CRT_VERTICAL_SYNC,
  80. FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height)
  81. | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1));
  82. ulTmpValue = FIELD_VALUE(0, CRT_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)|
  83. FIELD_VALUE(0, CRT_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)|
  84. FIELD_SET(0, CRT_DISPLAY_CTRL, TIMING, ENABLE)|
  85. FIELD_SET(0, CRT_DISPLAY_CTRL, PLANE, ENABLE);
  86. if (getChipType() == SM750LE) {
  87. displayControlAdjust_SM750LE(pModeParam, ulTmpValue);
  88. } else {
  89. ulReg = PEEK32(CRT_DISPLAY_CTRL)
  90. & FIELD_CLEAR(CRT_DISPLAY_CTRL, VSYNC_PHASE)
  91. & FIELD_CLEAR(CRT_DISPLAY_CTRL, HSYNC_PHASE)
  92. & FIELD_CLEAR(CRT_DISPLAY_CTRL, TIMING)
  93. & FIELD_CLEAR(CRT_DISPLAY_CTRL, PLANE);
  94. POKE32(CRT_DISPLAY_CTRL, ulTmpValue|ulReg);
  95. }
  96. } else if (pll->clockType == PRIMARY_PLL) {
  97. unsigned int ulReservedBits;
  98. POKE32(PANEL_PLL_CTRL, formatPllReg(pll));
  99. POKE32(PANEL_HORIZONTAL_TOTAL,
  100. FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1)
  101. | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1));
  102. POKE32(PANEL_HORIZONTAL_SYNC,
  103. FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width)
  104. | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1));
  105. POKE32(PANEL_VERTICAL_TOTAL,
  106. FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1)
  107. | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1));
  108. POKE32(PANEL_VERTICAL_SYNC,
  109. FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height)
  110. | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1));
  111. ulTmpValue = FIELD_VALUE(0, PANEL_DISPLAY_CTRL, VSYNC_PHASE, pModeParam->vertical_sync_polarity)|
  112. FIELD_VALUE(0, PANEL_DISPLAY_CTRL, HSYNC_PHASE, pModeParam->horizontal_sync_polarity)|
  113. FIELD_VALUE(0, PANEL_DISPLAY_CTRL, CLOCK_PHASE, pModeParam->clock_phase_polarity)|
  114. FIELD_SET(0, PANEL_DISPLAY_CTRL, TIMING, ENABLE)|
  115. FIELD_SET(0, PANEL_DISPLAY_CTRL, PLANE, ENABLE);
  116. ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) |
  117. FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) |
  118. FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)|
  119. FIELD_SET(0, PANEL_DISPLAY_CTRL, VSYNC, ACTIVE_LOW);
  120. ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits)
  121. & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE)
  122. & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE)
  123. & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE)
  124. & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING)
  125. & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE);
  126. /* May a hardware bug or just my test chip (not confirmed).
  127. * PANEL_DISPLAY_CTRL register seems requiring few writes
  128. * before a value can be successfully written in.
  129. * Added some masks to mask out the reserved bits.
  130. * Note: This problem happens by design. The hardware will wait for the
  131. * next vertical sync to turn on/off the plane.
  132. */
  133. POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
  134. while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) {
  135. cnt++;
  136. if (cnt > 1000)
  137. break;
  138. POKE32(PANEL_DISPLAY_CTRL, ulTmpValue|ulReg);
  139. }
  140. } else {
  141. ret = -1;
  142. }
  143. return ret;
  144. }
  145. int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
  146. {
  147. pll_value_t pll;
  148. unsigned int uiActualPixelClk;
  149. pll.inputFreq = DEFAULT_INPUT_CLOCK;
  150. pll.clockType = clock;
  151. uiActualPixelClk = calcPllValue(parm->pixel_clock, &pll);
  152. if (getChipType() == SM750LE) {
  153. /* set graphic mode via IO method */
  154. outb_p(0x88, 0x3d4);
  155. outb_p(0x06, 0x3d5);
  156. }
  157. programModeRegisters(parm, &pll);
  158. return 0;
  159. }