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