]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/sm750fb/ddk750_display.c
Merge tag 'ecryptfs-4.3-rc1-stale-dcache' of git://git.kernel.org/pub/scm/linux/kerne...
[mirror_ubuntu-bionic-kernel.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
da295041 7#define primaryWaitVerticalSync(delay) waitNextVerticalSync(0, delay)
81dee67e 8
da295041 9static void setDisplayControl(int ctrl, int dispState)
81dee67e
SM
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 */
259fef35 18 if (!ctrl) {
81dee67e
SM
19 ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL);
20 /* Turn on/off the Panel display control */
259fef35 21 if (dispState) {
81dee67e
SM
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.
78376535 25 */
81dee67e
SM
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 */
259fef35 46 do {
81dee67e
SM
47 cnt++;
48 POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg);
9ccc5f44 49 } while ((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) !=
81dee67e 50 (ulDisplayCtrlReg & ~ulReservedBits));
da295041 51 printk("Set Panel Plane enbit:after tried %d times\n", cnt);
259fef35 52 } else {
81dee67e
SM
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
259fef35
JL
69 } else {
70 /* Set the secondary display control */
81dee67e
SM
71 ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL);
72
259fef35 73 if (dispState) {
81dee67e
SM
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
259fef35 95 do {
81dee67e
SM
96 cnt++;
97 POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg);
9ccc5f44 98 } while ((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) !=
81dee67e 99 (ulDisplayCtrlReg & ~ulReservedBits));
da295041 100 printk("Set Crt Plane enbit:after tried %d times\n", cnt);
259fef35 101 } else {
81dee67e
SM
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
120
da295041 121static void waitNextVerticalSync(int ctrl, int delay)
81dee67e
SM
122{
123 unsigned int status;
40403c1b 124
8c11f5a2 125 if (!ctrl) {
81dee67e
SM
126 /* primary controller */
127
78376535
JL
128 /* Do not wait when the Primary PLL is off or display control is already off.
129 This will prevent the software to wait forever. */
81dee67e
SM
130 if ((FIELD_GET(PEEK32(PANEL_PLL_CTRL), PANEL_PLL_CTRL, POWER) ==
131 PANEL_PLL_CTRL_POWER_OFF) ||
132 (FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) ==
259fef35 133 PANEL_DISPLAY_CTRL_TIMING_DISABLE)) {
81dee67e
SM
134 return;
135 }
136
259fef35 137 while (delay-- > 0) {
78376535 138 /* Wait for end of vsync. */
259fef35 139 do {
78376535
JL
140 status = FIELD_GET(PEEK32(SYSTEM_CTRL),
141 SYSTEM_CTRL,
142 PANEL_VSYNC);
cebafd8d 143 } while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
78376535
JL
144
145 /* Wait for start of vsync. */
259fef35 146 do {
78376535
JL
147 status = FIELD_GET(PEEK32(SYSTEM_CTRL),
148 SYSTEM_CTRL,
149 PANEL_VSYNC);
cebafd8d 150 } while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE);
78376535 151 }
81dee67e 152
6338a781 153 } else {
81dee67e
SM
154
155 /* Do not wait when the Primary PLL is off or display control is already off.
156 This will prevent the software to wait forever. */
157 if ((FIELD_GET(PEEK32(CRT_PLL_CTRL), CRT_PLL_CTRL, POWER) ==
158 CRT_PLL_CTRL_POWER_OFF) ||
159 (FIELD_GET(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) ==
259fef35 160 CRT_DISPLAY_CTRL_TIMING_DISABLE)) {
81dee67e
SM
161 return;
162 }
163
259fef35 164 while (delay-- > 0) {
81dee67e 165 /* Wait for end of vsync. */
259fef35 166 do {
81dee67e
SM
167 status = FIELD_GET(PEEK32(SYSTEM_CTRL),
168 SYSTEM_CTRL,
169 CRT_VSYNC);
cebafd8d 170 } while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE);
81dee67e
SM
171
172 /* Wait for start of vsync. */
259fef35 173 do {
81dee67e
SM
174 status = FIELD_GET(PEEK32(SYSTEM_CTRL),
175 SYSTEM_CTRL,
176 CRT_VSYNC);
cebafd8d 177 } while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE);
81dee67e
SM
178 }
179 }
180}
181
da295041 182static void swPanelPowerSequence(int disp, int delay)
81dee67e
SM
183{
184 unsigned int reg;
185
186 /* disp should be 1 to open sequence */
187 reg = PEEK32(PANEL_DISPLAY_CTRL);
da295041
IA
188 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
189 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
190 primaryWaitVerticalSync(delay);
191
192
193 reg = PEEK32(PANEL_DISPLAY_CTRL);
da295041
IA
194 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, DATA, disp);
195 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
196 primaryWaitVerticalSync(delay);
197
198 reg = PEEK32(PANEL_DISPLAY_CTRL);
da295041
IA
199 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, VBIASEN, disp);
200 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
201 primaryWaitVerticalSync(delay);
202
203
204 reg = PEEK32(PANEL_DISPLAY_CTRL);
da295041
IA
205 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
206 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
207 primaryWaitVerticalSync(delay);
208
209}
210
211void ddk750_setLogicalDispOut(disp_output_t output)
212{
213 unsigned int reg;
40403c1b 214
8c11f5a2 215 if (output & PNL_2_USAGE) {
81dee67e
SM
216 /* set panel path controller select */
217 reg = PEEK32(PANEL_DISPLAY_CTRL);
da295041
IA
218 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, SELECT, (output & PNL_2_MASK)>>PNL_2_OFFSET);
219 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
220 }
221
8c11f5a2 222 if (output & CRT_2_USAGE) {
81dee67e
SM
223 /* set crt path controller select */
224 reg = PEEK32(CRT_DISPLAY_CTRL);
da295041 225 reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, SELECT, (output & CRT_2_MASK)>>CRT_2_OFFSET);
81dee67e 226 /*se blank off */
da295041
IA
227 reg = FIELD_SET(reg, CRT_DISPLAY_CTRL, BLANK, OFF);
228 POKE32(CRT_DISPLAY_CTRL, reg);
81dee67e
SM
229
230 }
231
8c11f5a2 232 if (output & PRI_TP_USAGE) {
81dee67e 233 /* set primary timing and plane en_bit */
da295041 234 setDisplayControl(0, (output&PRI_TP_MASK)>>PRI_TP_OFFSET);
81dee67e
SM
235 }
236
8c11f5a2 237 if (output & SEC_TP_USAGE) {
81dee67e 238 /* set secondary timing and plane en_bit*/
da295041 239 setDisplayControl(1, (output&SEC_TP_MASK)>>SEC_TP_OFFSET);
81dee67e
SM
240 }
241
8c11f5a2 242 if (output & PNL_SEQ_USAGE) {
81dee67e 243 /* set panel sequence */
da295041 244 swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET, 4);
81dee67e
SM
245 }
246
9ccc5f44 247 if (output & DAC_USAGE)
81dee67e
SM
248 setDAC((output & DAC_MASK)>>DAC_OFFSET);
249
9ccc5f44 250 if (output & DPMS_USAGE)
81dee67e
SM
251 ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET);
252}
253
254
6fa7db83 255int ddk750_initDVIDisp(void)
81dee67e 256{
78376535
JL
257 /* Initialize DVI. If the dviInit fail and the VendorID or the DeviceID are
258 not zeroed, then set the failure flag. If it is zeroe, it might mean
259 that the system is in Dual CRT Monitor configuration. */
260
261 /* De-skew enabled with default 111b value.
262 This will fix some artifacts problem in some mode on board 2.2.
263 Somehow this fix does not affect board 2.1.
264 */
265 if ((dviInit(1, /* Select Rising Edge */
266 1, /* Select 24-bit bus */
267 0, /* Select Single Edge clock */
268 1, /* Enable HSync as is */
269 1, /* Enable VSync as is */
270 1, /* Enable De-skew */
271 7, /* Set the de-skew setting to maximum setup */
272 1, /* Enable continuous Sync */
273 1, /* Enable PLL Filter */
274 4 /* Use the recommended value for PLL Filter value */
259fef35 275 ) != 0) && (dviGetVendorID() != 0x0000) && (dviGetDeviceID() != 0x0000)) {
78376535
JL
276 return (-1);
277 }
278
279 /* TODO: Initialize other display component */
280
281 /* Success */
282 return 0;
81dee67e
SM
283
284}
285