Merge branch 'drm-intel-next' of git://anongit.freedesktop.org/drm-intel into drm...
[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
78376535
JL
71 /* Do not wait when the Primary PLL is off or display control is already off.
72 This will prevent the software to wait forever. */
5557eb17 73 if (!(PEEK32(PANEL_PLL_CTRL) & PLL_CTRL_POWER) ||
6fba39cf 74 !(PEEK32(PANEL_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) {
81dee67e
SM
75 return;
76 }
77
259fef35 78 while (delay-- > 0) {
78376535 79 /* Wait for end of vsync. */
259fef35 80 do {
410c756d
MR
81 status = PEEK32(SYSTEM_CTRL);
82 } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
78376535
JL
83
84 /* Wait for start of vsync. */
259fef35 85 do {
410c756d
MR
86 status = PEEK32(SYSTEM_CTRL);
87 } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE));
78376535 88 }
81dee67e 89
6338a781 90 } else {
81dee67e
SM
91
92 /* Do not wait when the Primary PLL is off or display control is already off.
93 This will prevent the software to wait forever. */
5557eb17 94 if (!(PEEK32(CRT_PLL_CTRL) & PLL_CTRL_POWER) ||
6fba39cf 95 !(PEEK32(CRT_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) {
81dee67e
SM
96 return;
97 }
98
259fef35 99 while (delay-- > 0) {
81dee67e 100 /* Wait for end of vsync. */
259fef35 101 do {
410c756d
MR
102 status = PEEK32(SYSTEM_CTRL);
103 } while (status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
81dee67e
SM
104
105 /* Wait for start of vsync. */
259fef35 106 do {
410c756d
MR
107 status = PEEK32(SYSTEM_CTRL);
108 } while (!(status & SYSTEM_CTRL_PANEL_VSYNC_ACTIVE));
81dee67e
SM
109 }
110 }
111}
112
da295041 113static void swPanelPowerSequence(int disp, int delay)
81dee67e
SM
114{
115 unsigned int reg;
116
117 /* disp should be 1 to open sequence */
118 reg = PEEK32(PANEL_DISPLAY_CTRL);
6fba39cf 119 reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0);
da295041 120 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
121 primaryWaitVerticalSync(delay);
122
81dee67e 123 reg = PEEK32(PANEL_DISPLAY_CTRL);
6fba39cf 124 reg |= (disp ? PANEL_DISPLAY_CTRL_DATA : 0);
da295041 125 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
126 primaryWaitVerticalSync(delay);
127
128 reg = PEEK32(PANEL_DISPLAY_CTRL);
6fba39cf 129 reg |= (disp ? PANEL_DISPLAY_CTRL_VBIASEN : 0);
da295041 130 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
131 primaryWaitVerticalSync(delay);
132
81dee67e 133 reg = PEEK32(PANEL_DISPLAY_CTRL);
6fba39cf 134 reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0);
da295041 135 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
136 primaryWaitVerticalSync(delay);
137
138}
139
140void ddk750_setLogicalDispOut(disp_output_t output)
141{
142 unsigned int reg;
40403c1b 143
8c11f5a2 144 if (output & PNL_2_USAGE) {
81dee67e
SM
145 /* set panel path controller select */
146 reg = PEEK32(PANEL_DISPLAY_CTRL);
c4e893b7
MR
147 reg &= ~PANEL_DISPLAY_CTRL_SELECT_MASK;
148 reg |= (((output & PNL_2_MASK) >> PNL_2_OFFSET) <<
149 PANEL_DISPLAY_CTRL_SELECT_SHIFT);
da295041 150 POKE32(PANEL_DISPLAY_CTRL, reg);
81dee67e
SM
151 }
152
8c11f5a2 153 if (output & CRT_2_USAGE) {
81dee67e
SM
154 /* set crt path controller select */
155 reg = PEEK32(CRT_DISPLAY_CTRL);
cdce1f18
MR
156 reg &= ~CRT_DISPLAY_CTRL_SELECT_MASK;
157 reg |= (((output & CRT_2_MASK) >> CRT_2_OFFSET) <<
158 CRT_DISPLAY_CTRL_SELECT_SHIFT);
81dee67e 159 /*se blank off */
d8264edf 160 reg &= ~CRT_DISPLAY_CTRL_BLANK;
da295041 161 POKE32(CRT_DISPLAY_CTRL, reg);
81dee67e
SM
162
163 }
164
8c11f5a2 165 if (output & PRI_TP_USAGE) {
81dee67e 166 /* set primary timing and plane en_bit */
aeec43da 167 setDisplayControl(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET);
81dee67e
SM
168 }
169
8c11f5a2 170 if (output & SEC_TP_USAGE) {
81dee67e 171 /* set secondary timing and plane en_bit*/
aeec43da 172 setDisplayControl(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET);
81dee67e
SM
173 }
174
8c11f5a2 175 if (output & PNL_SEQ_USAGE) {
81dee67e 176 /* set panel sequence */
aeec43da 177 swPanelPowerSequence((output & PNL_SEQ_MASK) >> PNL_SEQ_OFFSET, 4);
81dee67e
SM
178 }
179
9ccc5f44 180 if (output & DAC_USAGE)
e80ef45d 181 setDAC((output & DAC_MASK) >> DAC_OFFSET);
81dee67e 182
9ccc5f44 183 if (output & DPMS_USAGE)
81dee67e
SM
184 ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET);
185}
This page took 0.298703 seconds and 5 git commands to generate.