1 // SPDX-License-Identifier: GPL-2.0
2 #include "ddk750_reg.h"
3 #include "ddk750_chip.h"
4 #include "ddk750_display.h"
5 #include "ddk750_power.h"
6 #include "ddk750_dvi.h"
8 static void setDisplayControl(int ctrl
, int disp_state
)
10 /* state != 0 means turn on both timing & plane en_bit */
11 unsigned long reg
, val
, reserved
;
15 reg
= PANEL_DISPLAY_CTRL
;
16 reserved
= PANEL_DISPLAY_CTRL_RESERVED_MASK
;
18 reg
= CRT_DISPLAY_CTRL
;
19 reserved
= CRT_DISPLAY_CTRL_RESERVED_MASK
;
25 * Timing should be enabled first before enabling the
26 * plane because changing at the same time does not
27 * guarantee that the plane will also enabled or
30 val
|= DISPLAY_CTRL_TIMING
;
33 val
|= DISPLAY_CTRL_PLANE
;
36 * Somehow the register value on the plane is not set
37 * until a few delay. Need to write and read it a
43 } while ((peek32(reg
) & ~reserved
) != (val
& ~reserved
));
44 pr_debug("Set Plane enbit:after tried %d times\n", cnt
);
47 * When turning off, there is no rule on the
48 * programming sequence since whenever the clock is
49 * off, then it does not matter whether the plane is
50 * enabled or disabled. Note: Modifying the plane bit
51 * will take effect on the next vertical sync. Need to
52 * find out if it is necessary to wait for 1 vsync
53 * before modifying the timing enable bit.
55 val
&= ~DISPLAY_CTRL_PLANE
;
58 val
&= ~DISPLAY_CTRL_TIMING
;
63 static void primary_wait_vertical_sync(int delay
)
68 * Do not wait when the Primary PLL is off or display control is
69 * already off. This will prevent the software to wait forever.
71 if (!(peek32(PANEL_PLL_CTRL
) & PLL_CTRL_POWER
) ||
72 !(peek32(PANEL_DISPLAY_CTRL
) & DISPLAY_CTRL_TIMING
))
76 /* Wait for end of vsync. */
78 status
= peek32(SYSTEM_CTRL
);
79 } while (status
& SYSTEM_CTRL_PANEL_VSYNC_ACTIVE
);
81 /* Wait for start of vsync. */
83 status
= peek32(SYSTEM_CTRL
);
84 } while (!(status
& SYSTEM_CTRL_PANEL_VSYNC_ACTIVE
));
88 static void swPanelPowerSequence(int disp
, int delay
)
92 /* disp should be 1 to open sequence */
93 reg
= peek32(PANEL_DISPLAY_CTRL
);
94 reg
|= (disp
? PANEL_DISPLAY_CTRL_FPEN
: 0);
95 poke32(PANEL_DISPLAY_CTRL
, reg
);
96 primary_wait_vertical_sync(delay
);
98 reg
= peek32(PANEL_DISPLAY_CTRL
);
99 reg
|= (disp
? PANEL_DISPLAY_CTRL_DATA
: 0);
100 poke32(PANEL_DISPLAY_CTRL
, reg
);
101 primary_wait_vertical_sync(delay
);
103 reg
= peek32(PANEL_DISPLAY_CTRL
);
104 reg
|= (disp
? PANEL_DISPLAY_CTRL_VBIASEN
: 0);
105 poke32(PANEL_DISPLAY_CTRL
, reg
);
106 primary_wait_vertical_sync(delay
);
108 reg
= peek32(PANEL_DISPLAY_CTRL
);
109 reg
|= (disp
? PANEL_DISPLAY_CTRL_FPEN
: 0);
110 poke32(PANEL_DISPLAY_CTRL
, reg
);
111 primary_wait_vertical_sync(delay
);
114 void ddk750_setLogicalDispOut(disp_output_t output
)
118 if (output
& PNL_2_USAGE
) {
119 /* set panel path controller select */
120 reg
= peek32(PANEL_DISPLAY_CTRL
);
121 reg
&= ~PANEL_DISPLAY_CTRL_SELECT_MASK
;
122 reg
|= (((output
& PNL_2_MASK
) >> PNL_2_OFFSET
) <<
123 PANEL_DISPLAY_CTRL_SELECT_SHIFT
);
124 poke32(PANEL_DISPLAY_CTRL
, reg
);
127 if (output
& CRT_2_USAGE
) {
128 /* set crt path controller select */
129 reg
= peek32(CRT_DISPLAY_CTRL
);
130 reg
&= ~CRT_DISPLAY_CTRL_SELECT_MASK
;
131 reg
|= (((output
& CRT_2_MASK
) >> CRT_2_OFFSET
) <<
132 CRT_DISPLAY_CTRL_SELECT_SHIFT
);
134 reg
&= ~CRT_DISPLAY_CTRL_BLANK
;
135 poke32(CRT_DISPLAY_CTRL
, reg
);
138 if (output
& PRI_TP_USAGE
) {
139 /* set primary timing and plane en_bit */
140 setDisplayControl(0, (output
& PRI_TP_MASK
) >> PRI_TP_OFFSET
);
143 if (output
& SEC_TP_USAGE
) {
144 /* set secondary timing and plane en_bit*/
145 setDisplayControl(1, (output
& SEC_TP_MASK
) >> SEC_TP_OFFSET
);
148 if (output
& PNL_SEQ_USAGE
) {
149 /* set panel sequence */
150 swPanelPowerSequence((output
& PNL_SEQ_MASK
) >> PNL_SEQ_OFFSET
,
154 if (output
& DAC_USAGE
)
155 setDAC((output
& DAC_MASK
) >> DAC_OFFSET
);
157 if (output
& DPMS_USAGE
)
158 ddk750_set_dpms((output
& DPMS_MASK
) >> DPMS_OFFSET
);