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 
setDisplayControl(int ctrl,int dispState)9 static 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 
waitNextVerticalSync(int ctrl,int delay)132 static 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 
swPanelPowerSequence(int disp,int delay)204 static 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 
ddk750_setLogicalDispOut(disp_output_t output)233 void 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 
ddk750_initDVIDisp(void)276 int ddk750_initDVIDisp(void)
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 
308