2 #include "ddk750_reg.h"
3 #include "ddk750_mode.h"
4 #include "ddk750_chip.h"
8 * This function takes care extra registers and bit fields required to set
11 * Explanation about Display Control register:
12 * HW only supports 7 predefined pixel clocks, and clock select is
13 * in bit 29:27 of Display Control register.
15 static unsigned long displayControlAdjust_SM750LE(struct mode_parameter
*pModeParam
,
16 unsigned long dispControl
)
20 x
= pModeParam
->horizontal_display_end
;
21 y
= pModeParam
->vertical_display_end
;
24 * SM750LE has to set up the top-left and bottom-right
26 * Note that normal SM750/SM718 only use those two register for
27 * auto-centering mode.
29 poke32(CRT_AUTO_CENTERING_TL
, 0);
31 poke32(CRT_AUTO_CENTERING_BR
,
32 (((y
- 1) << CRT_AUTO_CENTERING_BR_BOTTOM_SHIFT
) &
33 CRT_AUTO_CENTERING_BR_BOTTOM_MASK
) |
34 ((x
- 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK
));
37 * Assume common fields in dispControl have been properly set before
38 * calling this function.
39 * This function only sets the extra fields in dispControl.
42 /* Clear bit 29:27 of display control register */
43 dispControl
&= ~CRT_DISPLAY_CTRL_CLK_MASK
;
45 /* Set bit 29:27 of display control register for the right clock */
46 /* Note that SM750LE only need to supported 7 resolutions. */
47 if (x
== 800 && y
== 600)
48 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL41
;
49 else if (x
== 1024 && y
== 768)
50 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL65
;
51 else if (x
== 1152 && y
== 864)
52 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL80
;
53 else if (x
== 1280 && y
== 768)
54 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL80
;
55 else if (x
== 1280 && y
== 720)
56 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL74
;
57 else if (x
== 1280 && y
== 960)
58 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL108
;
59 else if (x
== 1280 && y
== 1024)
60 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL108
;
61 else /* default to VGA clock */
62 dispControl
|= CRT_DISPLAY_CTRL_CLK_PLL25
;
64 /* Set bit 25:24 of display controller */
65 dispControl
|= (CRT_DISPLAY_CTRL_CRTSELECT
| CRT_DISPLAY_CTRL_RGBBIT
);
67 /* Set bit 14 of display controller */
68 dispControl
|= DISPLAY_CTRL_CLOCK_PHASE
;
70 poke32(CRT_DISPLAY_CTRL
, dispControl
);
75 /* only timing related registers will be programed */
76 static int programModeRegisters(struct mode_parameter
*pModeParam
,
77 struct pll_value
*pll
)
81 unsigned int tmp
, reg
;
83 if (pll
->clockType
== SECONDARY_PLL
) {
84 /* programe secondary pixel clock */
85 poke32(CRT_PLL_CTRL
, sm750_format_pll_reg(pll
));
87 tmp
= ((pModeParam
->horizontal_total
- 1) <<
88 CRT_HORIZONTAL_TOTAL_TOTAL_SHIFT
) &
89 CRT_HORIZONTAL_TOTAL_TOTAL_MASK
;
90 tmp
|= (pModeParam
->horizontal_display_end
- 1) &
91 CRT_HORIZONTAL_TOTAL_DISPLAY_END_MASK
;
93 poke32(CRT_HORIZONTAL_TOTAL
, tmp
);
95 tmp
= (pModeParam
->horizontal_sync_width
<<
96 CRT_HORIZONTAL_SYNC_WIDTH_SHIFT
) &
97 CRT_HORIZONTAL_SYNC_WIDTH_MASK
;
98 tmp
|= (pModeParam
->horizontal_sync_start
- 1) &
99 CRT_HORIZONTAL_SYNC_START_MASK
;
101 poke32(CRT_HORIZONTAL_SYNC
, tmp
);
103 tmp
= ((pModeParam
->vertical_total
- 1) <<
104 CRT_VERTICAL_TOTAL_TOTAL_SHIFT
) &
105 CRT_VERTICAL_TOTAL_TOTAL_MASK
;
106 tmp
|= (pModeParam
->vertical_display_end
- 1) &
107 CRT_VERTICAL_TOTAL_DISPLAY_END_MASK
;
109 poke32(CRT_VERTICAL_TOTAL
, tmp
);
111 tmp
= ((pModeParam
->vertical_sync_height
<<
112 CRT_VERTICAL_SYNC_HEIGHT_SHIFT
)) &
113 CRT_VERTICAL_SYNC_HEIGHT_MASK
;
114 tmp
|= (pModeParam
->vertical_sync_start
- 1) &
115 CRT_VERTICAL_SYNC_START_MASK
;
117 poke32(CRT_VERTICAL_SYNC
, tmp
);
119 tmp
= DISPLAY_CTRL_TIMING
| DISPLAY_CTRL_PLANE
;
120 if (pModeParam
->vertical_sync_polarity
)
121 tmp
|= DISPLAY_CTRL_VSYNC_PHASE
;
122 if (pModeParam
->horizontal_sync_polarity
)
123 tmp
|= DISPLAY_CTRL_HSYNC_PHASE
;
125 if (sm750_get_chip_type() == SM750LE
) {
126 displayControlAdjust_SM750LE(pModeParam
, tmp
);
128 reg
= peek32(CRT_DISPLAY_CTRL
) &
129 ~(DISPLAY_CTRL_VSYNC_PHASE
|
130 DISPLAY_CTRL_HSYNC_PHASE
|
131 DISPLAY_CTRL_TIMING
| DISPLAY_CTRL_PLANE
);
133 poke32(CRT_DISPLAY_CTRL
, tmp
| reg
);
136 } else if (pll
->clockType
== PRIMARY_PLL
) {
137 unsigned int reserved
;
139 poke32(PANEL_PLL_CTRL
, sm750_format_pll_reg(pll
));
141 reg
= ((pModeParam
->horizontal_total
- 1) <<
142 PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT
) &
143 PANEL_HORIZONTAL_TOTAL_TOTAL_MASK
;
144 reg
|= ((pModeParam
->horizontal_display_end
- 1) &
145 PANEL_HORIZONTAL_TOTAL_DISPLAY_END_MASK
);
146 poke32(PANEL_HORIZONTAL_TOTAL
, reg
);
148 poke32(PANEL_HORIZONTAL_SYNC
,
149 ((pModeParam
->horizontal_sync_width
<<
150 PANEL_HORIZONTAL_SYNC_WIDTH_SHIFT
) &
151 PANEL_HORIZONTAL_SYNC_WIDTH_MASK
) |
152 ((pModeParam
->horizontal_sync_start
- 1) &
153 PANEL_HORIZONTAL_SYNC_START_MASK
));
155 poke32(PANEL_VERTICAL_TOTAL
,
156 (((pModeParam
->vertical_total
- 1) <<
157 PANEL_VERTICAL_TOTAL_TOTAL_SHIFT
) &
158 PANEL_VERTICAL_TOTAL_TOTAL_MASK
) |
159 ((pModeParam
->vertical_display_end
- 1) &
160 PANEL_VERTICAL_TOTAL_DISPLAY_END_MASK
));
162 poke32(PANEL_VERTICAL_SYNC
,
163 ((pModeParam
->vertical_sync_height
<<
164 PANEL_VERTICAL_SYNC_HEIGHT_SHIFT
) &
165 PANEL_VERTICAL_SYNC_HEIGHT_MASK
) |
166 ((pModeParam
->vertical_sync_start
- 1) &
167 PANEL_VERTICAL_SYNC_START_MASK
));
169 tmp
= DISPLAY_CTRL_TIMING
| DISPLAY_CTRL_PLANE
;
170 if (pModeParam
->vertical_sync_polarity
)
171 tmp
|= DISPLAY_CTRL_VSYNC_PHASE
;
172 if (pModeParam
->horizontal_sync_polarity
)
173 tmp
|= DISPLAY_CTRL_HSYNC_PHASE
;
174 if (pModeParam
->clock_phase_polarity
)
175 tmp
|= DISPLAY_CTRL_CLOCK_PHASE
;
177 reserved
= PANEL_DISPLAY_CTRL_RESERVED_MASK
|
178 PANEL_DISPLAY_CTRL_VSYNC
;
180 reg
= (peek32(PANEL_DISPLAY_CTRL
) & ~reserved
) &
181 ~(DISPLAY_CTRL_CLOCK_PHASE
| DISPLAY_CTRL_VSYNC_PHASE
|
182 DISPLAY_CTRL_HSYNC_PHASE
| DISPLAY_CTRL_TIMING
|
186 * May a hardware bug or just my test chip (not confirmed).
187 * PANEL_DISPLAY_CTRL register seems requiring few writes
188 * before a value can be successfully written in.
189 * Added some masks to mask out the reserved bits.
190 * Note: This problem happens by design. The hardware will wait
191 * for the next vertical sync to turn on/off the plane.
193 poke32(PANEL_DISPLAY_CTRL
, tmp
| reg
);
195 while ((peek32(PANEL_DISPLAY_CTRL
) & ~reserved
) !=
200 poke32(PANEL_DISPLAY_CTRL
, tmp
| reg
);
208 int ddk750_setModeTiming(struct mode_parameter
*parm
, clock_type_t clock
)
210 struct pll_value pll
;
211 unsigned int uiActualPixelClk
;
213 pll
.inputFreq
= DEFAULT_INPUT_CLOCK
;
214 pll
.clockType
= clock
;
216 uiActualPixelClk
= sm750_calc_pll_value(parm
->pixel_clock
, &pll
);
217 if (sm750_get_chip_type() == SM750LE
) {
218 /* set graphic mode via IO method */
222 programModeRegisters(parm
, &pll
);