• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 disp_state)9 static void setDisplayControl(int ctrl, int disp_state)
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 		ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL);
20 		/* Turn on/off the Panel display control */
21 		if (disp_state) {
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.
25 			 */
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 			 */
46 			do {
47 				cnt++;
48 				POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
49 			} while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) !=
50 					(ulDisplayCtrlReg & ~ulReservedBits));
51 			printk("Set Panel Plane enbit:after tried %d times\n", cnt);
52 		} else {
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 
69 	} else {
70 		/* Set the secondary display control */
71 		ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL);
72 
73 		if (disp_state) {
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 
95 			do {
96 				cnt++;
97 				POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
98 			} while ((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) !=
99 					(ulDisplayCtrlReg & ~ulReservedBits));
100 				printk("Set Crt Plane enbit:after tried %d times\n", cnt);
101 		} else {
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 
waitNextVerticalSync(int ctrl,int delay)120 static void waitNextVerticalSync(int ctrl, int delay)
121 {
122 	unsigned int status;
123 
124 	if (!ctrl) {
125 		/* primary controller */
126 
127 		/* Do not wait when the Primary PLL is off or display control is already off.
128 		   This will prevent the software to wait forever. */
129 		if ((FIELD_GET(PEEK32(PANEL_PLL_CTRL), PANEL_PLL_CTRL, POWER) ==
130 			 PANEL_PLL_CTRL_POWER_OFF) ||
131 			(FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) ==
132 			 PANEL_DISPLAY_CTRL_TIMING_DISABLE)) {
133 			return;
134 		}
135 
136 		while (delay-- > 0) {
137 			/* Wait for end of vsync. */
138 			do {
139 				status = FIELD_GET(PEEK32(SYSTEM_CTRL),
140 						   SYSTEM_CTRL,
141 						   PANEL_VSYNC);
142 			} while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
143 
144 			/* Wait for start of vsync. */
145 			do {
146 				status = FIELD_GET(PEEK32(SYSTEM_CTRL),
147 						   SYSTEM_CTRL,
148 						   PANEL_VSYNC);
149 			} while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE);
150 		}
151 
152 	} else {
153 
154 		/* Do not wait when the Primary PLL is off or display control is already off.
155 			   This will prevent the software to wait forever. */
156 		if ((FIELD_GET(PEEK32(CRT_PLL_CTRL), CRT_PLL_CTRL, POWER) ==
157 			 CRT_PLL_CTRL_POWER_OFF) ||
158 			(FIELD_GET(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) ==
159 			 CRT_DISPLAY_CTRL_TIMING_DISABLE)) {
160 			return;
161 		}
162 
163 		while (delay-- > 0) {
164 			/* Wait for end of vsync. */
165 			do {
166 				status = FIELD_GET(PEEK32(SYSTEM_CTRL),
167 								   SYSTEM_CTRL,
168 								   CRT_VSYNC);
169 			} while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE);
170 
171 			/* Wait for start of vsync. */
172 			do {
173 				status = FIELD_GET(PEEK32(SYSTEM_CTRL),
174 								   SYSTEM_CTRL,
175 								   CRT_VSYNC);
176 			} while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE);
177 		}
178 	}
179 }
180 
swPanelPowerSequence(int disp,int delay)181 static void swPanelPowerSequence(int disp, int delay)
182 {
183 	unsigned int reg;
184 
185 	/* disp should be 1 to open sequence */
186 	reg = PEEK32(PANEL_DISPLAY_CTRL);
187 	reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
188 	POKE32(PANEL_DISPLAY_CTRL, reg);
189 	primaryWaitVerticalSync(delay);
190 
191 	reg = PEEK32(PANEL_DISPLAY_CTRL);
192 	reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, DATA, disp);
193 	POKE32(PANEL_DISPLAY_CTRL, reg);
194 	primaryWaitVerticalSync(delay);
195 
196 	reg = PEEK32(PANEL_DISPLAY_CTRL);
197 	reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, VBIASEN, disp);
198 	POKE32(PANEL_DISPLAY_CTRL, reg);
199 	primaryWaitVerticalSync(delay);
200 
201 	reg = PEEK32(PANEL_DISPLAY_CTRL);
202 	reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
203 	POKE32(PANEL_DISPLAY_CTRL, reg);
204 	primaryWaitVerticalSync(delay);
205 
206 }
207 
ddk750_setLogicalDispOut(disp_output_t output)208 void ddk750_setLogicalDispOut(disp_output_t output)
209 {
210 	unsigned int reg;
211 
212 	if (output & PNL_2_USAGE) {
213 		/* set panel path controller select */
214 		reg = PEEK32(PANEL_DISPLAY_CTRL);
215 		reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, SELECT, (output & PNL_2_MASK)>>PNL_2_OFFSET);
216 		POKE32(PANEL_DISPLAY_CTRL, reg);
217 	}
218 
219 	if (output & CRT_2_USAGE) {
220 		/* set crt path controller select */
221 		reg = PEEK32(CRT_DISPLAY_CTRL);
222 		reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, SELECT, (output & CRT_2_MASK)>>CRT_2_OFFSET);
223 		/*se blank off */
224 		reg = FIELD_SET(reg, CRT_DISPLAY_CTRL, BLANK, OFF);
225 		POKE32(CRT_DISPLAY_CTRL, reg);
226 
227 	}
228 
229 	if (output & PRI_TP_USAGE) {
230 		/* set primary timing and plane en_bit */
231 		setDisplayControl(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET);
232 	}
233 
234 	if (output & SEC_TP_USAGE) {
235 		/* set secondary timing and plane en_bit*/
236 		setDisplayControl(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET);
237 	}
238 
239 	if (output & PNL_SEQ_USAGE) {
240 		/* set  panel sequence */
241 		swPanelPowerSequence((output & PNL_SEQ_MASK) >> PNL_SEQ_OFFSET, 4);
242 	}
243 
244 	if (output & DAC_USAGE)
245 		setDAC((output & DAC_MASK) >> DAC_OFFSET);
246 
247 	if (output & DPMS_USAGE)
248 		ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET);
249 }
250