drivers/tty: make pty.c slightly more explicitly non-modular
[firefly-linux-kernel-4.4.55.git] / drivers / staging / sm750fb / ddk750_display.c
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
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                 ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL);
20                 /* Turn on/off the Panel display control */
21                 if (dispState) {
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 (dispState) {
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
120
121 static void waitNextVerticalSync(int ctrl, int delay)
122 {
123         unsigned int status;
124
125         if (!ctrl) {
126                 /* primary controller */
127
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. */
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) ==
133                          PANEL_DISPLAY_CTRL_TIMING_DISABLE)) {
134                         return;
135                 }
136
137                 while (delay-- > 0) {
138                         /* Wait for end of vsync. */
139                         do {
140                                 status = FIELD_GET(PEEK32(SYSTEM_CTRL),
141                                                    SYSTEM_CTRL,
142                                                    PANEL_VSYNC);
143                         } while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
144
145                         /* Wait for start of vsync. */
146                         do {
147                                 status = FIELD_GET(PEEK32(SYSTEM_CTRL),
148                                                    SYSTEM_CTRL,
149                                                    PANEL_VSYNC);
150                         } while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE);
151                 }
152
153         } else {
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) ==
160                          CRT_DISPLAY_CTRL_TIMING_DISABLE)) {
161                         return;
162                 }
163
164                 while (delay-- > 0) {
165                         /* Wait for end of vsync. */
166                         do {
167                                 status = FIELD_GET(PEEK32(SYSTEM_CTRL),
168                                                                    SYSTEM_CTRL,
169                                                                    CRT_VSYNC);
170                         } while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE);
171
172                         /* Wait for start of vsync. */
173                         do {
174                                 status = FIELD_GET(PEEK32(SYSTEM_CTRL),
175                                                                    SYSTEM_CTRL,
176                                                                    CRT_VSYNC);
177                         } while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE);
178                 }
179         }
180 }
181
182 static void swPanelPowerSequence(int disp, int delay)
183 {
184         unsigned int reg;
185
186         /* disp should be 1 to open sequence */
187         reg = PEEK32(PANEL_DISPLAY_CTRL);
188         reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
189         POKE32(PANEL_DISPLAY_CTRL, reg);
190         primaryWaitVerticalSync(delay);
191
192
193         reg = PEEK32(PANEL_DISPLAY_CTRL);
194         reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, DATA, disp);
195         POKE32(PANEL_DISPLAY_CTRL, reg);
196         primaryWaitVerticalSync(delay);
197
198         reg = PEEK32(PANEL_DISPLAY_CTRL);
199         reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, VBIASEN, disp);
200         POKE32(PANEL_DISPLAY_CTRL, reg);
201         primaryWaitVerticalSync(delay);
202
203
204         reg = PEEK32(PANEL_DISPLAY_CTRL);
205         reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, FPEN, disp);
206         POKE32(PANEL_DISPLAY_CTRL, reg);
207         primaryWaitVerticalSync(delay);
208
209 }
210
211 void ddk750_setLogicalDispOut(disp_output_t output)
212 {
213         unsigned int reg;
214
215         if (output & PNL_2_USAGE) {
216                 /* set panel path controller select */
217                 reg = PEEK32(PANEL_DISPLAY_CTRL);
218                 reg = FIELD_VALUE(reg, PANEL_DISPLAY_CTRL, SELECT, (output & PNL_2_MASK)>>PNL_2_OFFSET);
219                 POKE32(PANEL_DISPLAY_CTRL, reg);
220         }
221
222         if (output & CRT_2_USAGE) {
223                 /* set crt path controller select */
224                 reg = PEEK32(CRT_DISPLAY_CTRL);
225                 reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, SELECT, (output & CRT_2_MASK)>>CRT_2_OFFSET);
226                 /*se blank off */
227                 reg = FIELD_SET(reg, CRT_DISPLAY_CTRL, BLANK, OFF);
228                 POKE32(CRT_DISPLAY_CTRL, reg);
229
230         }
231
232         if (output & PRI_TP_USAGE) {
233                 /* set primary timing and plane en_bit */
234                 setDisplayControl(0, (output&PRI_TP_MASK)>>PRI_TP_OFFSET);
235         }
236
237         if (output & SEC_TP_USAGE) {
238                 /* set secondary timing and plane en_bit*/
239                 setDisplayControl(1, (output&SEC_TP_MASK)>>SEC_TP_OFFSET);
240         }
241
242         if (output & PNL_SEQ_USAGE) {
243                 /* set  panel sequence */
244                 swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET, 4);
245         }
246
247         if (output & DAC_USAGE)
248                 setDAC((output & DAC_MASK)>>DAC_OFFSET);
249
250         if (output & DPMS_USAGE)
251                 ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET);
252 }
253
254
255 int ddk750_initDVIDisp(void)
256 {
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 */
275                      ) != 0) && (dviGetVendorID() != 0x0000) && (dviGetDeviceID() != 0x0000)) {
276                 return (-1);
277         }
278
279         /* TODO: Initialize other display component */
280
281         /* Success */
282         return 0;
283
284 }
285