1 // SPDX-License-Identifier: GPL-2.0
3 #include "ddk750_reg.h"
4 #include "ddk750_mode.h"
5 #include "ddk750_chip.h"
9 * This function takes care extra registers and bit fields required to set
10 * up a mode in SM750LE
12 * Explanation about Display Control register:
13 * HW only supports 7 predefined pixel clocks, and clock select is
14 * in bit 29:27 of Display Control register.
16 static unsigned long displayControlAdjust_SM750LE(struct mode_parameter
*pModeParam
,
17 unsigned long dispControl
)
21 x
= pModeParam
->horizontal_display_end
;
22 y
= pModeParam
->vertical_display_end
;
25 * SM750LE has to set up the top-left and bottom-right
27 * Note that normal SM750/SM718 only use those two register for
28 * auto-centering mode.
30 poke32(CRT_AUTO_CENTERING_TL
, 0);
32 poke32(CRT_AUTO_CENTERING_BR
,
33 (((y
- 1) << CRT_AUTO_CENTERING_BR_BOTTOM_SHIFT
) &
34 CRT_AUTO_CENTERING_BR_BOTTOM_MASK
) |
35 ((x
- 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK
));
38 * Assume common fields in dispControl have been properly set before
39 * calling this function.
40 * This function only sets the extra fields in dispControl.
43 /* Clear bit 29:27 of display control register */
44 dispControl
&= ~CRT_DISPLAY_CTRL_CLK_MASK
;
46 /* Set bit 29:27 of display control register for the right clock */
47 /* Note that SM750LE only need to supported 7 resolutions. */
48 if (x
== 800 && y
== 600)
49 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL41
;
50 else if (x
== 1024 && y
== 768)
51 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL65
;
52 else if (x
== 1152 && y
== 864)
53 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL80
;
54 else if (x
== 1280 && y
== 768)
55 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL80
;
56 else if (x
== 1280 && y
== 720)
57 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL74
;
58 else if (x
== 1280 && y
== 960)
59 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL108
;
60 else if (x
== 1280 && y
== 1024)
61 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL108
;
62 else /* default to VGA clock */
63 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL25
;
65 /* Set bit 25:24 of display controller */
66 dispControl
|= (CRT_DISPLAY_CTRL_CRTSELECT
| CRT_DISPLAY_CTRL_RGBBIT
);
68 /* Set bit 14 of display controller */
69 dispControl
|= DISPLAY_CTRL_CLOCK_PHASE
;
71 poke32(CRT_DISPLAY_CTRL
, dispControl
);
76 /* only timing related registers will be programed */
77 static int programModeRegisters(struct mode_parameter
*pModeParam
,
78 struct pll_value
*pll
)
82 unsigned int tmp
, reg
;
84 if (pll
->clockType
== SECONDARY_PLL
) {
85 /* programe secondary pixel clock */
86 poke32(CRT_PLL_CTRL
, sm750_format_pll_reg(pll
));
88 tmp
= ((pModeParam
->horizontal_total
- 1) <<
89 CRT_HORIZONTAL_TOTAL_TOTAL_SHIFT
) &
90 CRT_HORIZONTAL_TOTAL_TOTAL_MASK
;
91 tmp
|= (pModeParam
->horizontal_display_end
- 1) &
92 CRT_HORIZONTAL_TOTAL_DISPLAY_END_MASK
;
94 poke32(CRT_HORIZONTAL_TOTAL
, tmp
);
96 tmp
= (pModeParam
->horizontal_sync_width
<<
97 CRT_HORIZONTAL_SYNC_WIDTH_SHIFT
) &
98 CRT_HORIZONTAL_SYNC_WIDTH_MASK
;
99 tmp
|= (pModeParam
->horizontal_sync_start
- 1) &
100 CRT_HORIZONTAL_SYNC_START_MASK
;
102 poke32(CRT_HORIZONTAL_SYNC
, tmp
);
104 tmp
= ((pModeParam
->vertical_total
- 1) <<
105 CRT_VERTICAL_TOTAL_TOTAL_SHIFT
) &
106 CRT_VERTICAL_TOTAL_TOTAL_MASK
;
107 tmp
|= (pModeParam
->vertical_display_end
- 1) &
108 CRT_VERTICAL_TOTAL_DISPLAY_END_MASK
;
110 poke32(CRT_VERTICAL_TOTAL
, tmp
);
112 tmp
= ((pModeParam
->vertical_sync_height
<<
113 CRT_VERTICAL_SYNC_HEIGHT_SHIFT
)) &
114 CRT_VERTICAL_SYNC_HEIGHT_MASK
;
115 tmp
|= (pModeParam
->vertical_sync_start
- 1) &
116 CRT_VERTICAL_SYNC_START_MASK
;
118 poke32(CRT_VERTICAL_SYNC
, tmp
);
120 tmp
= DISPLAY_CTRL_TIMING
| DISPLAY_CTRL_PLANE
;
121 if (pModeParam
->vertical_sync_polarity
)
122 tmp
|= DISPLAY_CTRL_VSYNC_PHASE
;
123 if (pModeParam
->horizontal_sync_polarity
)
124 tmp
|= DISPLAY_CTRL_HSYNC_PHASE
;
126 if (sm750_get_chip_type() == SM750LE
) {
127 displayControlAdjust_SM750LE(pModeParam
, tmp
);
129 reg
= peek32(CRT_DISPLAY_CTRL
) &
130 ~(DISPLAY_CTRL_VSYNC_PHASE
|
131 DISPLAY_CTRL_HSYNC_PHASE
|
132 DISPLAY_CTRL_TIMING
| DISPLAY_CTRL_PLANE
);
134 poke32(CRT_DISPLAY_CTRL
, tmp
| reg
);
137 } else if (pll
->clockType
== PRIMARY_PLL
) {
138 unsigned int reserved
;
140 poke32(PANEL_PLL_CTRL
, sm750_format_pll_reg(pll
));
142 reg
= ((pModeParam
->horizontal_total
- 1) <<
143 PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT
) &
144 PANEL_HORIZONTAL_TOTAL_TOTAL_MASK
;
145 reg
|= ((pModeParam
->horizontal_display_end
- 1) &
146 PANEL_HORIZONTAL_TOTAL_DISPLAY_END_MASK
);
147 poke32(PANEL_HORIZONTAL_TOTAL
, reg
);
149 poke32(PANEL_HORIZONTAL_SYNC
,
150 ((pModeParam
->horizontal_sync_width
<<
151 PANEL_HORIZONTAL_SYNC_WIDTH_SHIFT
) &
152 PANEL_HORIZONTAL_SYNC_WIDTH_MASK
) |
153 ((pModeParam
->horizontal_sync_start
- 1) &
154 PANEL_HORIZONTAL_SYNC_START_MASK
));
156 poke32(PANEL_VERTICAL_TOTAL
,
157 (((pModeParam
->vertical_total
- 1) <<
158 PANEL_VERTICAL_TOTAL_TOTAL_SHIFT
) &
159 PANEL_VERTICAL_TOTAL_TOTAL_MASK
) |
160 ((pModeParam
->vertical_display_end
- 1) &
161 PANEL_VERTICAL_TOTAL_DISPLAY_END_MASK
));
163 poke32(PANEL_VERTICAL_SYNC
,
164 ((pModeParam
->vertical_sync_height
<<
165 PANEL_VERTICAL_SYNC_HEIGHT_SHIFT
) &
166 PANEL_VERTICAL_SYNC_HEIGHT_MASK
) |
167 ((pModeParam
->vertical_sync_start
- 1) &
168 PANEL_VERTICAL_SYNC_START_MASK
));
170 tmp
= DISPLAY_CTRL_TIMING
| DISPLAY_CTRL_PLANE
;
171 if (pModeParam
->vertical_sync_polarity
)
172 tmp
|= DISPLAY_CTRL_VSYNC_PHASE
;
173 if (pModeParam
->horizontal_sync_polarity
)
174 tmp
|= DISPLAY_CTRL_HSYNC_PHASE
;
175 if (pModeParam
->clock_phase_polarity
)
176 tmp
|= DISPLAY_CTRL_CLOCK_PHASE
;
178 reserved
= PANEL_DISPLAY_CTRL_RESERVED_MASK
|
179 PANEL_DISPLAY_CTRL_VSYNC
;
181 reg
= (peek32(PANEL_DISPLAY_CTRL
) & ~reserved
) &
182 ~(DISPLAY_CTRL_CLOCK_PHASE
| DISPLAY_CTRL_VSYNC_PHASE
|
183 DISPLAY_CTRL_HSYNC_PHASE
| DISPLAY_CTRL_TIMING
|
187 * May a hardware bug or just my test chip (not confirmed).
188 * PANEL_DISPLAY_CTRL register seems requiring few writes
189 * before a value can be successfully written in.
190 * Added some masks to mask out the reserved bits.
191 * Note: This problem happens by design. The hardware will wait
192 * for the next vertical sync to turn on/off the plane.
194 poke32(PANEL_DISPLAY_CTRL
, tmp
| reg
);
196 while ((peek32(PANEL_DISPLAY_CTRL
) & ~reserved
) !=
201 poke32(PANEL_DISPLAY_CTRL
, tmp
| reg
);
209 int ddk750_setModeTiming(struct mode_parameter
*parm
, clock_type_t clock
)
211 struct pll_value pll
;
212 unsigned int uiActualPixelClk
;
214 pll
.inputFreq
= DEFAULT_INPUT_CLOCK
;
215 pll
.clockType
= clock
;
217 uiActualPixelClk
= sm750_calc_pll_value(parm
->pixel_clock
, &pll
);
218 if (sm750_get_chip_type() == SM750LE
) {
219 /* set graphic mode via IO method */
223 programModeRegisters(parm
, &pll
);