Merge remote-tracking branch 'staging/staging-next'
[deliverable/linux.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
edb23022 9static void setDisplayControl(int ctrl, int disp_state)
81dee67e
SM
10{
11 /* state != 0 means turn on both timing & plane en_bit */
b117b637
MR
12 unsigned long reg, val, reserved;
13 int cnt = 0;
81dee67e 14
259fef35 15 if (!ctrl) {
b117b637
MR
16 reg = PANEL_DISPLAY_CTRL;
17 reserved = PANEL_DISPLAY_CTRL_RESERVED_MASK;
259fef35 18 } else {
b117b637
MR
19 reg = CRT_DISPLAY_CTRL;
20 reserved = CRT_DISPLAY_CTRL_RESERVED_MASK;
21 }
81dee67e 22
b117b637
MR
23 val = PEEK32(reg);
24 if (disp_state) {
25 /*
26 * Timing should be enabled first before enabling the
27 * plane because changing at the same time does not
28 * guarantee that the plane will also enabled or
29 * disabled.
30 */
6fba39cf 31 val |= DISPLAY_CTRL_TIMING;
b117b637
MR
32 POKE32(reg, val);
33
6fba39cf 34 val |= DISPLAY_CTRL_PLANE;
b117b637
MR
35
36 /*
37 * Somehow the register value on the plane is not set
38 * until a few delay. Need to write and read it a
39 * couple times
40 */
41 do {
42 cnt++;
43 POKE32(reg, val);
44 } while ((PEEK32(reg) & ~reserved) != (val & ~reserved));
45 pr_debug("Set Plane enbit:after tried %d times\n", cnt);
46 } else {
47 /*
48 * When turning off, there is no rule on the
49 * programming sequence since whenever the clock is
50 * off, then it does not matter whether the plane is
51 * enabled or disabled. Note: Modifying the plane bit
52 * will take effect on the next vertical sync. Need to
53 * find out if it is necessary to wait for 1 vsync
54 * before modifying the timing enable bit.
55 */
6fba39cf 56 val &= ~DISPLAY_CTRL_PLANE;
b117b637
MR
57 POKE32(reg, val);
58
6fba39cf 59 val &= ~DISPLAY_CTRL_TIMING;
b117b637 60 POKE32(reg, val);
81dee67e
SM
61 }
62}
63
da295041 64static void waitNextVerticalSync(int ctrl, int delay)
81dee67e
SM
65{
66 unsigned int status;
40403c1b 67
8c11f5a2 68 if (!ctrl) {
81dee67e
SM
69 /* primary controller */
70
c9d67dc4
K
71 /*
72 * Do not wait when the Primary PLL is off or display control is
73 * already off. This will prevent the software to wait forever.
74 */
5557eb17 75 if (!(PEEK32(PANEL_PLL_CTRL) & PLL_CTRL_POWER) ||
6fba39cf 76 !(PEEK32(PANEL_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) {
81dee67e
SM
77 return;
78 }
79
259fef35 80 while (delay-- > 0) {
78376535 81 /* Wait for end of vsync. */
259fef35 82 do {
410c756d
MR
83 status = PEEK32(SYSTEM_CTRL);
84 } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
78376535
JL
85
86 /* Wait for start of vsync. */
259fef35 87 do {
410c756d
MR
88 status = PEEK32(SYSTEM_CTRL);
89 } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE));
78376535 90 }
81dee67e 91
6338a781 92 } else {
c9d67dc4
K
93 /*
94 * Do not wait when the Primary PLL is off or display control is
95 * already off. This will prevent the software to wait forever.
96 */
5557eb17 97 if (!(PEEK32(CRT_PLL_CTRL) & PLL_CTRL_POWER) ||
6fba39cf 98 !(PEEK32(CRT_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) {
81dee67e
SM
99 return;
100 }
101
259fef35 102 while (delay-- > 0) {
81dee67e 103 /* Wait for end of vsync. */
259fef35 104 do {
410c756d
MR
105 status = PEEK32(SYSTEM_CTRL);
106 } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
81dee67e
SM
107
108 /* Wait for start of vsync. */
259fef35 109 do {
410c756d
MR
110 status = PEEK32(SYSTEM_CTRL);
111 } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE));
81dee67e
SM
112 }
113 }
114}
115
da295041 116static void swPanelPowerSequence(int disp, int delay)
81dee67e
SM
117{
118 unsigned int reg;
119
120 /* disp should be 1 to open sequence */
121 reg = PEEK32(PANEL_DISPLAY_CTRL);
6fba39cf 122 reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0);
da295041 123 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
124 primaryWaitVerticalSync(delay);
125
81dee67e 126 reg = PEEK32(PANEL_DISPLAY_CTRL);
6fba39cf 127 reg |= (disp ? PANEL_DISPLAY_CTRL_DATA : 0);
da295041 128 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
129 primaryWaitVerticalSync(delay);
130
131 reg = PEEK32(PANEL_DISPLAY_CTRL);
6fba39cf 132 reg |= (disp ? PANEL_DISPLAY_CTRL_VBIASEN : 0);
da295041 133 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
134 primaryWaitVerticalSync(delay);
135
81dee67e 136 reg = PEEK32(PANEL_DISPLAY_CTRL);
6fba39cf 137 reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0);
da295041 138 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
139 primaryWaitVerticalSync(delay);
140
141}
142
143void ddk750_setLogicalDispOut(disp_output_t output)
144{
145 unsigned int reg;
40403c1b 146
8c11f5a2 147 if (output & PNL_2_USAGE) {
81dee67e
SM
148 /* set panel path controller select */
149 reg = PEEK32(PANEL_DISPLAY_CTRL);
c4e893b7
MR
150 reg &= ~PANEL_DISPLAY_CTRL_SELECT_MASK;
151 reg |= (((output & PNL_2_MASK) >> PNL_2_OFFSET) <<
152 PANEL_DISPLAY_CTRL_SELECT_SHIFT);
da295041 153 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
154 }
155
8c11f5a2 156 if (output & CRT_2_USAGE) {
81dee67e
SM
157 /* set crt path controller select */
158 reg = PEEK32(CRT_DISPLAY_CTRL);
cdce1f18
MR
159 reg &= ~CRT_DISPLAY_CTRL_SELECT_MASK;
160 reg |= (((output & CRT_2_MASK) >> CRT_2_OFFSET) <<
161 CRT_DISPLAY_CTRL_SELECT_SHIFT);
81dee67e 162 /*se blank off */
d8264edf 163 reg &= ~CRT_DISPLAY_CTRL_BLANK;
da295041 164 POKE32(CRT_DISPLAY_CTRL, reg);
81dee67e
SM
165
166 }
167
8c11f5a2 168 if (output & PRI_TP_USAGE) {
81dee67e 169 /* set primary timing and plane en_bit */
aeec43da 170 setDisplayControl(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET);
81dee67e
SM
171 }
172
8c11f5a2 173 if (output & SEC_TP_USAGE) {
81dee67e 174 /* set secondary timing and plane en_bit*/
aeec43da 175 setDisplayControl(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET);
81dee67e
SM
176 }
177
8c11f5a2 178 if (output & PNL_SEQ_USAGE) {
81dee67e 179 /* set panel sequence */
aeec43da 180 swPanelPowerSequence((output & PNL_SEQ_MASK) >> PNL_SEQ_OFFSET, 4);
81dee67e
SM
181 }
182
9ccc5f44 183 if (output & DAC_USAGE)
e80ef45d 184 setDAC((output & DAC_MASK) >> DAC_OFFSET);
81dee67e 185
9ccc5f44 186 if (output & DPMS_USAGE)
81dee67e
SM
187 ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET);
188}
This page took 0.224441 seconds and 5 git commands to generate.