]>
Commit | Line | Data |
---|---|---|
81dee67e SM |
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 | ||
da295041 | 7 | #define primaryWaitVerticalSync(delay) waitNextVerticalSync(0, delay) |
81dee67e | 8 | |
da295041 | 9 | static void setDisplayControl(int ctrl, int dispState) |
81dee67e SM |
10 | { |
11 | /* state != 0 means turn on both timing & plane en_bit */ | |
12 | unsigned long ulDisplayCtrlReg, ulReservedBits; | |
13 | int cnt; | |
14 | ||
15 | cnt = 0; | |
16 | ||
17 | /* Set the primary display control */ | |
259fef35 | 18 | if (!ctrl) { |
81dee67e SM |
19 | ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL); |
20 | /* Turn on/off the Panel display control */ | |
259fef35 | 21 | if (dispState) { |
81dee67e SM |
22 | /* Timing should be enabled first before enabling the plane |
23 | * because changing at the same time does not guarantee that | |
24 | * the plane will also enabled or disabled. | |
78376535 | 25 | */ |
81dee67e SM |
26 | ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, |
27 | PANEL_DISPLAY_CTRL, TIMING, ENABLE); | |
28 | POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); | |
29 | ||
30 | ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, | |
31 | PANEL_DISPLAY_CTRL, PLANE, ENABLE); | |
32 | ||
33 | /* Added some masks to mask out the reserved bits. | |
34 | * Sometimes, the reserved bits are set/reset randomly when | |
35 | * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register | |
36 | * reserved bits are needed to be masked out. | |
37 | */ | |
38 | ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | | |
39 | FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | | |
40 | FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE); | |
41 | ||
42 | /* Somehow the register value on the plane is not set | |
43 | * until a few delay. Need to write | |
44 | * and read it a couple times | |
45 | */ | |
259fef35 | 46 | do { |
81dee67e SM |
47 | cnt++; |
48 | POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); | |
9ccc5f44 | 49 | } while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != |
81dee67e | 50 | (ulDisplayCtrlReg & ~ulReservedBits)); |
da295041 | 51 | printk("Set Panel Plane enbit:after tried %d times\n", cnt); |
259fef35 | 52 | } else { |
81dee67e SM |
53 | /* When turning off, there is no rule on the programming |
54 | * sequence since whenever the clock is off, then it does not | |
55 | * matter whether the plane is enabled or disabled. | |
56 | * Note: Modifying the plane bit will take effect on the | |
57 | * next vertical sync. Need to find out if it is necessary to | |
58 | * wait for 1 vsync before modifying the timing enable bit. | |
59 | * */ | |
60 | ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, | |
61 | PANEL_DISPLAY_CTRL, PLANE, DISABLE); | |
62 | POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); | |
63 | ||
64 | ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, | |
65 | PANEL_DISPLAY_CTRL, TIMING, DISABLE); | |
66 | POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); | |
67 | } | |
68 | ||
259fef35 JL |
69 | } else { |
70 | /* Set the secondary display control */ | |
81dee67e SM |
71 | ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL); |
72 | ||
259fef35 | 73 | if (dispState) { |
81dee67e SM |
74 | /* Timing should be enabled first before enabling the plane because changing at the |
75 | same time does not guarantee that the plane will also enabled or disabled. | |
76 | */ | |
77 | ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, | |
78 | CRT_DISPLAY_CTRL, TIMING, ENABLE); | |
79 | POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); | |
80 | ||
81 | ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, | |
82 | CRT_DISPLAY_CTRL, PLANE, ENABLE); | |
83 | ||
84 | /* Added some masks to mask out the reserved bits. | |
85 | * Sometimes, the reserved bits are set/reset randomly when | |
86 | * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register | |
87 | * reserved bits are needed to be masked out. | |
88 | */ | |
89 | ||
90 | ulReservedBits = FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | | |
91 | FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | | |
92 | FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE) | | |
93 | FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_4_MASK, ENABLE); | |
94 | ||
259fef35 | 95 | do { |
81dee67e SM |
96 | cnt++; |
97 | POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); | |
9ccc5f44 | 98 | } while ((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) != |
81dee67e | 99 | (ulDisplayCtrlReg & ~ulReservedBits)); |
da295041 | 100 | printk("Set Crt Plane enbit:after tried %d times\n", cnt); |
259fef35 | 101 | } else { |
81dee67e SM |
102 | /* When turning off, there is no rule on the programming |
103 | * sequence since whenever the clock is off, then it does not | |
104 | * matter whether the plane is enabled or disabled. | |
105 | * Note: Modifying the plane bit will take effect on the next | |
106 | * vertical sync. Need to find out if it is necessary to | |
107 | * wait for 1 vsync before modifying the timing enable bit. | |
108 | */ | |
109 | ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, | |
110 | CRT_DISPLAY_CTRL, PLANE, DISABLE); | |
111 | POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); | |
112 | ||
113 | ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, | |
114 | CRT_DISPLAY_CTRL, TIMING, DISABLE); | |
115 | POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); | |
116 | } | |
117 | } | |
118 | } | |
119 | ||
120 | ||
da295041 | 121 | static void waitNextVerticalSync(int ctrl, int delay) |
81dee67e SM |
122 | { |
123 | unsigned int status; | |
40403c1b | 124 | |
8c11f5a2 | 125 | if (!ctrl) { |
81dee67e SM |
126 | /* primary controller */ |
127 | ||
78376535 JL |
128 | /* Do not wait when the Primary PLL is off or display control is already off. |
129 | This will prevent the software to wait forever. */ | |
81dee67e SM |
130 | if ((FIELD_GET(PEEK32(PANEL_PLL_CTRL), PANEL_PLL_CTRL, POWER) == |
131 | PANEL_PLL_CTRL_POWER_OFF) || | |
132 | (FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) == | |
259fef35 | 133 | PANEL_DISPLAY_CTRL_TIMING_DISABLE)) { |
81dee67e SM |
134 | return; |
135 | } | |
136 | ||
259fef35 | 137 | while (delay-- > 0) { |
78376535 | 138 | /* Wait for end of vsync. */ |
259fef35 | 139 | do { |
78376535 JL |
140 | status = FIELD_GET(PEEK32(SYSTEM_CTRL), |
141 | SYSTEM_CTRL, | |
142 | PANEL_VSYNC); | |
cebafd8d | 143 | } while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE); |
78376535 JL |
144 | |
145 | /* Wait for start of vsync. */ | |
259fef35 | 146 | do { |
78376535 JL |
147 | status = FIELD_GET(PEEK32(SYSTEM_CTRL), |
148 | SYSTEM_CTRL, | |
149 | PANEL_VSYNC); | |
cebafd8d | 150 | } while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE); |
78376535 | 151 | } |
81dee67e | 152 | |
6338a781 | 153 | } else { |
81dee67e SM |
154 | |
155 | /* Do not wait when the Primary PLL is off or display control is already off. | |
156 | This will prevent the software to wait forever. */ | |
157 | if ((FIELD_GET(PEEK32(CRT_PLL_CTRL), CRT_PLL_CTRL, POWER) == | |
158 | CRT_PLL_CTRL_POWER_OFF) || | |
159 | (FIELD_GET(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) == | |
259fef35 | 160 | CRT_DISPLAY_CTRL_TIMING_DISABLE)) { |
81dee67e SM |
161 | return; |
162 | } | |
163 | ||
259fef35 | 164 | while (delay-- > 0) { |
81dee67e | 165 | /* Wait for end of vsync. */ |
259fef35 | 166 | do { |
81dee67e SM |
167 | status = FIELD_GET(PEEK32(SYSTEM_CTRL), |
168 | SYSTEM_CTRL, | |
169 | CRT_VSYNC); | |
cebafd8d | 170 | } while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE); |
81dee67e SM |
171 | |
172 | /* Wait for start of vsync. */ | |
259fef35 | 173 | do { |
81dee67e SM |
174 | status = FIELD_GET(PEEK32(SYSTEM_CTRL), |
175 | SYSTEM_CTRL, | |
176 | CRT_VSYNC); | |
cebafd8d | 177 | } while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE); |
81dee67e SM |
178 | } |
179 | } | |
180 | } | |
181 | ||
da295041 | 182 | static void swPanelPowerSequence(int disp, int delay) |
81dee67e SM |
183 | { |
184 | unsigned int reg; | |
185 | ||
186 | /* disp should be 1 to open sequence */ | |
187 | reg = PEEK32(PANEL_DISPLAY_CTRL); | |
da295041 IA |
188 | reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp); |
189 | POKE32(PANEL_DISPLAY_CTRL, reg); | |
81dee67e SM |
190 | primaryWaitVerticalSync(delay); |
191 | ||
192 | ||
193 | reg = PEEK32(PANEL_DISPLAY_CTRL); | |
da295041 IA |
194 | reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, DATA, disp); |
195 | POKE32(PANEL_DISPLAY_CTRL, reg); | |
81dee67e SM |
196 | primaryWaitVerticalSync(delay); |
197 | ||
198 | reg = PEEK32(PANEL_DISPLAY_CTRL); | |
da295041 IA |
199 | reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, VBIASEN, disp); |
200 | POKE32(PANEL_DISPLAY_CTRL, reg); | |
81dee67e SM |
201 | primaryWaitVerticalSync(delay); |
202 | ||
203 | ||
204 | reg = PEEK32(PANEL_DISPLAY_CTRL); | |
da295041 IA |
205 | reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp); |
206 | POKE32(PANEL_DISPLAY_CTRL, reg); | |
81dee67e SM |
207 | primaryWaitVerticalSync(delay); |
208 | ||
209 | } | |
210 | ||
211 | void ddk750_setLogicalDispOut(disp_output_t output) | |
212 | { | |
213 | unsigned int reg; | |
40403c1b | 214 | |
8c11f5a2 | 215 | if (output & PNL_2_USAGE) { |
81dee67e SM |
216 | /* set panel path controller select */ |
217 | reg = PEEK32(PANEL_DISPLAY_CTRL); | |
da295041 IA |
218 | reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, SELECT, (output & PNL_2_MASK)>>PNL_2_OFFSET); |
219 | POKE32(PANEL_DISPLAY_CTRL, reg); | |
81dee67e SM |
220 | } |
221 | ||
8c11f5a2 | 222 | if (output & CRT_2_USAGE) { |
81dee67e SM |
223 | /* set crt path controller select */ |
224 | reg = PEEK32(CRT_DISPLAY_CTRL); | |
da295041 | 225 | reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, SELECT, (output & CRT_2_MASK)>>CRT_2_OFFSET); |
81dee67e | 226 | /*se blank off */ |
da295041 IA |
227 | reg = FIELD_SET(reg, CRT_DISPLAY_CTRL, BLANK, OFF); |
228 | POKE32(CRT_DISPLAY_CTRL, reg); | |
81dee67e SM |
229 | |
230 | } | |
231 | ||
8c11f5a2 | 232 | if (output & PRI_TP_USAGE) { |
81dee67e | 233 | /* set primary timing and plane en_bit */ |
da295041 | 234 | setDisplayControl(0, (output&PRI_TP_MASK)>>PRI_TP_OFFSET); |
81dee67e SM |
235 | } |
236 | ||
8c11f5a2 | 237 | if (output & SEC_TP_USAGE) { |
81dee67e | 238 | /* set secondary timing and plane en_bit*/ |
da295041 | 239 | setDisplayControl(1, (output&SEC_TP_MASK)>>SEC_TP_OFFSET); |
81dee67e SM |
240 | } |
241 | ||
8c11f5a2 | 242 | if (output & PNL_SEQ_USAGE) { |
81dee67e | 243 | /* set panel sequence */ |
da295041 | 244 | swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET, 4); |
81dee67e SM |
245 | } |
246 | ||
9ccc5f44 | 247 | if (output & DAC_USAGE) |
81dee67e SM |
248 | setDAC((output & DAC_MASK)>>DAC_OFFSET); |
249 | ||
9ccc5f44 | 250 | if (output & DPMS_USAGE) |
81dee67e SM |
251 | ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET); |
252 | } | |
253 | ||
254 | ||
6fa7db83 | 255 | int ddk750_initDVIDisp(void) |
81dee67e | 256 | { |
78376535 JL |
257 | /* Initialize DVI. If the dviInit fail and the VendorID or the DeviceID are |
258 | not zeroed, then set the failure flag. If it is zeroe, it might mean | |
259 | that the system is in Dual CRT Monitor configuration. */ | |
260 | ||
261 | /* De-skew enabled with default 111b value. | |
262 | This will fix some artifacts problem in some mode on board 2.2. | |
263 | Somehow this fix does not affect board 2.1. | |
264 | */ | |
265 | if ((dviInit(1, /* Select Rising Edge */ | |
266 | 1, /* Select 24-bit bus */ | |
267 | 0, /* Select Single Edge clock */ | |
268 | 1, /* Enable HSync as is */ | |
269 | 1, /* Enable VSync as is */ | |
270 | 1, /* Enable De-skew */ | |
271 | 7, /* Set the de-skew setting to maximum setup */ | |
272 | 1, /* Enable continuous Sync */ | |
273 | 1, /* Enable PLL Filter */ | |
274 | 4 /* Use the recommended value for PLL Filter value */ | |
259fef35 | 275 | ) != 0) && (dviGetVendorID() != 0x0000) && (dviGetDeviceID() != 0x0000)) { |
78376535 JL |
276 | return (-1); |
277 | } | |
278 | ||
279 | /* TODO: Initialize other display component */ | |
280 | ||
281 | /* Success */ | |
282 | return 0; | |
81dee67e SM |
283 | |
284 | } | |
285 |