2 #include "ddk750_reg.h"
3 #include "ddk750_mode.h"
4 #include "ddk750_chip.h"
8 * This function takes care extra registers and bit fields required to set
11 * Explanation about Display Control register:
12 * HW only supports 7 predefined pixel clocks, and clock select is
13 * in bit 29:27 of Display Control register.
15 static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl)
19 x = pModeParam->horizontal_display_end;
20 y = pModeParam->vertical_display_end;
23 * SM750LE has to set up the top-left and bottom-right
25 * Note that normal SM750/SM718 only use those two register for
26 * auto-centering mode.
28 poke32(CRT_AUTO_CENTERING_TL, 0);
30 poke32(CRT_AUTO_CENTERING_BR,
31 (((y - 1) << CRT_AUTO_CENTERING_BR_BOTTOM_SHIFT) &
32 CRT_AUTO_CENTERING_BR_BOTTOM_MASK) |
33 ((x - 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK));
36 * Assume common fields in dispControl have been properly set before
37 * calling this function.
38 * This function only sets the extra fields in dispControl.
41 /* Clear bit 29:27 of display control register */
42 dispControl &= ~CRT_DISPLAY_CTRL_CLK_MASK;
44 /* Set bit 29:27 of display control register for the right clock */
45 /* Note that SM750LE only need to supported 7 resolutions. */
46 if (x == 800 && y == 600)
47 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL41;
48 else if (x == 1024 && y == 768)
49 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL65;
50 else if (x == 1152 && y == 864)
51 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80;
52 else if (x == 1280 && y == 768)
53 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL80;
54 else if (x == 1280 && y == 720)
55 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL74;
56 else if (x == 1280 && y == 960)
57 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108;
58 else if (x == 1280 && y == 1024)
59 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL108;
60 else /* default to VGA clock */
61 dispControl |= CRT_DISPLAY_CTRL_CLK_PLL25;
63 /* Set bit 25:24 of display controller */
64 dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT);
66 /* Set bit 14 of display controller */
67 dispControl |= DISPLAY_CTRL_CLOCK_PHASE;
69 poke32(CRT_DISPLAY_CTRL, dispControl);
76 /* only timing related registers will be programed */
77 static int programModeRegisters(mode_parameter_t *pModeParam,
78 struct pll_value *pll)
82 unsigned int tmp, reg;
84 if (pll->clockType == SECONDARY_PLL) {
85 /* programe secondary pixel clock */
86 poke32(CRT_PLL_CTRL, sm750_format_pll_reg(pll));
87 poke32(CRT_HORIZONTAL_TOTAL,
88 (((pModeParam->horizontal_total - 1) <<
89 CRT_HORIZONTAL_TOTAL_TOTAL_SHIFT) &
90 CRT_HORIZONTAL_TOTAL_TOTAL_MASK) |
91 ((pModeParam->horizontal_display_end - 1) &
92 CRT_HORIZONTAL_TOTAL_DISPLAY_END_MASK));
94 poke32(CRT_HORIZONTAL_SYNC,
95 ((pModeParam->horizontal_sync_width <<
96 CRT_HORIZONTAL_SYNC_WIDTH_SHIFT) &
97 CRT_HORIZONTAL_SYNC_WIDTH_MASK) |
98 ((pModeParam->horizontal_sync_start - 1) &
99 CRT_HORIZONTAL_SYNC_START_MASK));
101 poke32(CRT_VERTICAL_TOTAL,
102 (((pModeParam->vertical_total - 1) <<
103 CRT_VERTICAL_TOTAL_TOTAL_SHIFT) &
104 CRT_VERTICAL_TOTAL_TOTAL_MASK) |
105 ((pModeParam->vertical_display_end - 1) &
106 CRT_VERTICAL_TOTAL_DISPLAY_END_MASK));
108 poke32(CRT_VERTICAL_SYNC,
109 ((pModeParam->vertical_sync_height <<
110 CRT_VERTICAL_SYNC_HEIGHT_SHIFT) &
111 CRT_VERTICAL_SYNC_HEIGHT_MASK) |
112 ((pModeParam->vertical_sync_start - 1) &
113 CRT_VERTICAL_SYNC_START_MASK));
116 tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE;
117 if (pModeParam->vertical_sync_polarity)
118 tmp |= DISPLAY_CTRL_VSYNC_PHASE;
119 if (pModeParam->horizontal_sync_polarity)
120 tmp |= DISPLAY_CTRL_HSYNC_PHASE;
122 if (sm750_get_chip_type() == SM750LE) {
123 displayControlAdjust_SM750LE(pModeParam, tmp);
125 reg = peek32(CRT_DISPLAY_CTRL) &
126 ~(DISPLAY_CTRL_VSYNC_PHASE |
127 DISPLAY_CTRL_HSYNC_PHASE |
128 DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE);
130 poke32(CRT_DISPLAY_CTRL, tmp | reg);
133 } else if (pll->clockType == PRIMARY_PLL) {
134 unsigned int reserved;
136 poke32(PANEL_PLL_CTRL, sm750_format_pll_reg(pll));
138 reg = ((pModeParam->horizontal_total - 1) <<
139 PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT) &
140 PANEL_HORIZONTAL_TOTAL_TOTAL_MASK;
141 reg |= ((pModeParam->horizontal_display_end - 1) &
142 PANEL_HORIZONTAL_TOTAL_DISPLAY_END_MASK);
143 poke32(PANEL_HORIZONTAL_TOTAL, reg);
145 poke32(PANEL_HORIZONTAL_SYNC,
146 ((pModeParam->horizontal_sync_width <<
147 PANEL_HORIZONTAL_SYNC_WIDTH_SHIFT) &
148 PANEL_HORIZONTAL_SYNC_WIDTH_MASK) |
149 ((pModeParam->horizontal_sync_start - 1) &
150 PANEL_HORIZONTAL_SYNC_START_MASK));
152 poke32(PANEL_VERTICAL_TOTAL,
153 (((pModeParam->vertical_total - 1) <<
154 PANEL_VERTICAL_TOTAL_TOTAL_SHIFT) &
155 PANEL_VERTICAL_TOTAL_TOTAL_MASK) |
156 ((pModeParam->vertical_display_end - 1) &
157 PANEL_VERTICAL_TOTAL_DISPLAY_END_MASK));
159 poke32(PANEL_VERTICAL_SYNC,
160 ((pModeParam->vertical_sync_height <<
161 PANEL_VERTICAL_SYNC_HEIGHT_SHIFT) &
162 PANEL_VERTICAL_SYNC_HEIGHT_MASK) |
163 ((pModeParam->vertical_sync_start - 1) &
164 PANEL_VERTICAL_SYNC_START_MASK));
166 tmp = DISPLAY_CTRL_TIMING | DISPLAY_CTRL_PLANE;
167 if (pModeParam->vertical_sync_polarity)
168 tmp |= DISPLAY_CTRL_VSYNC_PHASE;
169 if (pModeParam->horizontal_sync_polarity)
170 tmp |= DISPLAY_CTRL_HSYNC_PHASE;
171 if (pModeParam->clock_phase_polarity)
172 tmp |= DISPLAY_CTRL_CLOCK_PHASE;
174 reserved = PANEL_DISPLAY_CTRL_RESERVED_MASK |
175 PANEL_DISPLAY_CTRL_VSYNC;
177 reg = (peek32(PANEL_DISPLAY_CTRL) & ~reserved) &
178 ~(DISPLAY_CTRL_CLOCK_PHASE | DISPLAY_CTRL_VSYNC_PHASE |
179 DISPLAY_CTRL_HSYNC_PHASE | DISPLAY_CTRL_TIMING |
183 * May a hardware bug or just my test chip (not confirmed).
184 * PANEL_DISPLAY_CTRL register seems requiring few writes
185 * before a value can be successfully written in.
186 * Added some masks to mask out the reserved bits.
187 * Note: This problem happens by design. The hardware will wait
188 * for the next vertical sync to turn on/off the plane.
190 poke32(PANEL_DISPLAY_CTRL, tmp | reg);
192 while ((peek32(PANEL_DISPLAY_CTRL) & ~reserved) !=
197 poke32(PANEL_DISPLAY_CTRL, tmp | reg);
205 int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
207 struct pll_value pll;
208 unsigned int uiActualPixelClk;
210 pll.inputFreq = DEFAULT_INPUT_CLOCK;
211 pll.clockType = clock;
213 uiActualPixelClk = sm750_calc_pll_value(parm->pixel_clock, &pll);
214 if (sm750_get_chip_type() == SM750LE) {
215 /* set graphic mode via IO method */
219 programModeRegisters(parm, &pll);