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"
7 #define primaryWaitVerticalSync(delay) waitNextVerticalSync(0, delay)
9 static void setDisplayControl(int ctrl, int disp_state)
11 /* state != 0 means turn on both timing & plane en_bit */
12 unsigned long reg, reserved;
17 /* Set the primary display control */
19 reg = PEEK32(PANEL_DISPLAY_CTRL);
20 /* Turn on/off the Panel display control */
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.
26 reg = FIELD_SET(reg, DISPLAY_CTRL, TIMING, ENABLE);
27 POKE32(PANEL_DISPLAY_CTRL, reg);
29 reg = FIELD_SET(reg, DISPLAY_CTRL, PLANE, ENABLE);
31 /* Added some masks to mask out the reserved bits.
32 * Sometimes, the reserved bits are set/reset randomly when
33 * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register
34 * reserved bits are needed to be masked out.
36 reserved = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) |
37 FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) |
38 FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE);
40 /* Somehow the register value on the plane is not set
41 * until a few delay. Need to write
42 * and read it a couple times
46 POKE32(PANEL_DISPLAY_CTRL, reg);
47 } while ((PEEK32(PANEL_DISPLAY_CTRL) & ~reserved) !=
49 printk("Set Panel Plane enbit:after tried %d times\n", cnt);
51 /* When turning off, there is no rule on the programming
52 * sequence since whenever the clock is off, then it does not
53 * matter whether the plane is enabled or disabled.
54 * Note: Modifying the plane bit will take effect on the
55 * next vertical sync. Need to find out if it is necessary to
56 * wait for 1 vsync before modifying the timing enable bit.
58 reg = FIELD_SET(reg, DISPLAY_CTRL, PLANE, DISABLE);
59 POKE32(PANEL_DISPLAY_CTRL, reg);
61 reg = FIELD_SET(reg, DISPLAY_CTRL, TIMING, DISABLE);
62 POKE32(PANEL_DISPLAY_CTRL, reg);
66 /* Set the secondary display control */
67 reg = PEEK32(CRT_DISPLAY_CTRL);
70 /* Timing should be enabled first before enabling the plane because changing at the
71 same time does not guarantee that the plane will also enabled or disabled.
73 reg = FIELD_SET(reg, DISPLAY_CTRL, TIMING, ENABLE);
74 POKE32(CRT_DISPLAY_CTRL, reg);
76 reg = FIELD_SET(reg, DISPLAY_CTRL, PLANE, ENABLE);
78 /* Added some masks to mask out the reserved bits.
79 * Sometimes, the reserved bits are set/reset randomly when
80 * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register
81 * reserved bits are needed to be masked out.
84 reserved = FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) |
85 FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) |
86 FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE) |
87 FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_4_MASK, ENABLE);
91 POKE32(CRT_DISPLAY_CTRL, reg);
92 } while ((PEEK32(CRT_DISPLAY_CTRL) & ~reserved) !=
94 printk("Set Crt Plane enbit:after tried %d times\n", cnt);
96 /* When turning off, there is no rule on the programming
97 * sequence since whenever the clock is off, then it does not
98 * matter whether the plane is enabled or disabled.
99 * Note: Modifying the plane bit will take effect on the next
100 * vertical sync. Need to find out if it is necessary to
101 * wait for 1 vsync before modifying the timing enable bit.
103 reg = FIELD_SET(reg, DISPLAY_CTRL, PLANE, DISABLE);
104 POKE32(CRT_DISPLAY_CTRL, reg);
106 reg = FIELD_SET(reg, DISPLAY_CTRL, TIMING, DISABLE);
107 POKE32(CRT_DISPLAY_CTRL, reg);
112 static void waitNextVerticalSync(int ctrl, int delay)
117 /* primary controller */
119 /* Do not wait when the Primary PLL is off or display control is already off.
120 This will prevent the software to wait forever. */
121 if (!(PEEK32(PANEL_PLL_CTRL) & PLL_CTRL_POWER) ||
122 (FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL),
123 DISPLAY_CTRL, TIMING) ==
124 DISPLAY_CTRL_TIMING_DISABLE)) {
128 while (delay-- > 0) {
129 /* Wait for end of vsync. */
131 status = PEEK32(SYSTEM_CTRL);
132 } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
134 /* Wait for start of vsync. */
136 status = PEEK32(SYSTEM_CTRL);
137 } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE));
142 /* Do not wait when the Primary PLL is off or display control is already off.
143 This will prevent the software to wait forever. */
144 if (!(PEEK32(CRT_PLL_CTRL) & PLL_CTRL_POWER) ||
145 (FIELD_GET(PEEK32(CRT_DISPLAY_CTRL),
146 DISPLAY_CTRL, TIMING) ==
147 DISPLAY_CTRL_TIMING_DISABLE)) {
151 while (delay-- > 0) {
152 /* Wait for end of vsync. */
154 status = PEEK32(SYSTEM_CTRL);
155 } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
157 /* Wait for start of vsync. */
159 status = PEEK32(SYSTEM_CTRL);
160 } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE));
165 static void swPanelPowerSequence(int disp, int delay)
169 /* disp should be 1 to open sequence */
170 reg = PEEK32(PANEL_DISPLAY_CTRL);
171 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
172 POKE32(PANEL_DISPLAY_CTRL, reg);
173 primaryWaitVerticalSync(delay);
175 reg = PEEK32(PANEL_DISPLAY_CTRL);
176 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, DATA, disp);
177 POKE32(PANEL_DISPLAY_CTRL, reg);
178 primaryWaitVerticalSync(delay);
180 reg = PEEK32(PANEL_DISPLAY_CTRL);
181 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, VBIASEN, disp);
182 POKE32(PANEL_DISPLAY_CTRL, reg);
183 primaryWaitVerticalSync(delay);
185 reg = PEEK32(PANEL_DISPLAY_CTRL);
186 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
187 POKE32(PANEL_DISPLAY_CTRL, reg);
188 primaryWaitVerticalSync(delay);
192 void ddk750_setLogicalDispOut(disp_output_t output)
196 if (output & PNL_2_USAGE) {
197 /* set panel path controller select */
198 reg = PEEK32(PANEL_DISPLAY_CTRL);
199 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, SELECT, (output & PNL_2_MASK)>>PNL_2_OFFSET);
200 POKE32(PANEL_DISPLAY_CTRL, reg);
203 if (output & CRT_2_USAGE) {
204 /* set crt path controller select */
205 reg = PEEK32(CRT_DISPLAY_CTRL);
206 reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, SELECT, (output & CRT_2_MASK)>>CRT_2_OFFSET);
208 reg = FIELD_SET(reg, CRT_DISPLAY_CTRL, BLANK, OFF);
209 POKE32(CRT_DISPLAY_CTRL, reg);
213 if (output & PRI_TP_USAGE) {
214 /* set primary timing and plane en_bit */
215 setDisplayControl(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET);
218 if (output & SEC_TP_USAGE) {
219 /* set secondary timing and plane en_bit*/
220 setDisplayControl(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET);
223 if (output & PNL_SEQ_USAGE) {
224 /* set panel sequence */
225 swPanelPowerSequence((output & PNL_SEQ_MASK) >> PNL_SEQ_OFFSET, 4);
228 if (output & DAC_USAGE)
229 setDAC((output & DAC_MASK) >> DAC_OFFSET);
231 if (output & DPMS_USAGE)
232 ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET);