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 set_display_control(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 sw_panel_power_sequence(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_set_logical_disp_out(enum disp_output 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 set_display_control(0, (output & PRI_TP_MASK) >> PRI_TP_OFFSET);
143 if (output & SEC_TP_USAGE) {
144 /* set secondary timing and plane en_bit*/
145 set_display_control(1, (output & SEC_TP_MASK) >> SEC_TP_OFFSET);
148 if (output & PNL_SEQ_USAGE) {
149 /* set panel sequence */
150 sw_panel_power_sequence((output & PNL_SEQ_MASK) >>
154 if (output & DAC_USAGE)
155 set_DAC((output & DAC_MASK) >> DAC_OFFSET);
157 if (output & DPMS_USAGE)
158 ddk750_set_dpms((output & DPMS_MASK) >> DPMS_OFFSET);