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
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
276int 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