2 * Copyright © 2007 Alex Deucher
3 * Copyright © 2007 Dave Airlie
4 * Copyright © 2007 Michel Dänzer
5 * Copyright © 2007 Jerome Glisse
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation on the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so,
15 * subject to the following conditions:
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial
19 * portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
25 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
33 #include "radeon_ms.h"
35 static void radeon_pll1_init(struct drm_radeon_private *dev_priv,
36 struct radeon_state *state);
37 static void radeon_pll1_restore(struct drm_radeon_private *dev_priv,
38 struct radeon_state *state);
39 static void radeon_pll1_save(struct drm_radeon_private *dev_priv,
40 struct radeon_state *state);
41 static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc);
44 * radeon_ms_crtc1_init - initialize CRTC state
45 * @dev_priv: radeon private structure
46 * @state: state structure to initialize to default value
48 * Initialize CRTC state to default values
50 static void radeon_ms_crtc1_init(struct drm_radeon_private *dev_priv,
51 struct radeon_state *state)
53 state->surface_cntl = SURFACE_CNTL__SURF_TRANSLATION_DIS;
54 state->surface0_info = 0;
55 state->surface0_lower_bound = 0;
56 state->surface0_upper_bound = 0;
57 state->surface1_info = 0;
58 state->surface1_lower_bound = 0;
59 state->surface1_upper_bound = 0;
60 state->surface2_info = 0;
61 state->surface2_lower_bound = 0;
62 state->surface2_upper_bound = 0;
63 state->surface3_info = 0;
64 state->surface3_lower_bound = 0;
65 state->surface3_upper_bound = 0;
66 state->surface4_info = 0;
67 state->surface4_lower_bound = 0;
68 state->surface4_upper_bound = 0;
69 state->surface5_info = 0;
70 state->surface5_lower_bound = 0;
71 state->surface5_upper_bound = 0;
72 state->surface6_info = 0;
73 state->surface6_lower_bound = 0;
74 state->surface6_upper_bound = 0;
75 state->surface7_info = 0;
76 state->surface7_lower_bound = 0;
77 state->surface7_upper_bound = 0;
78 state->crtc_gen_cntl = CRTC_GEN_CNTL__CRTC_EXT_DISP_EN |
79 CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
80 state->crtc_ext_cntl = CRTC_EXT_CNTL__VGA_ATI_LINEAR |
81 CRTC_EXT_CNTL__VGA_XCRT_CNT_EN |
82 CRTC_EXT_CNTL__CRT_ON;
83 state->crtc_h_total_disp = 0;
84 state->crtc_h_sync_strt_wid = 0;
85 state->crtc_v_total_disp = 0;
86 state->crtc_v_sync_strt_wid = 0;
87 state->crtc_offset = 0;
88 state->crtc_pitch = 0;
89 state->crtc_more_cntl = 0;
90 state->crtc_tile_x0_y0 = 0;
91 state->crtc_offset_cntl = 0;
92 switch (dev_priv->family) {
111 state->crtc_offset_cntl |= REG_S(CRTC_OFFSET_CNTL,
112 CRTC_MICRO_TILE_BUFFER_MODE,
113 CRTC_MICRO_TILE_BUFFER_MODE__DIS);
116 DRM_ERROR("Unknown radeon family, aborting\n");
119 radeon_pll1_init(dev_priv, state);
123 * radeon_pll1_init - initialize PLL1 state
124 * @dev_priv: radeon private structure
125 * @state: state structure to initialize to default value
127 * Initialize PLL1 state to default values
129 static void radeon_pll1_init(struct drm_radeon_private *dev_priv,
130 struct radeon_state *state)
132 state->clock_cntl_index = 0;
133 state->ppll_cntl = PPLL_R(PPLL_CNTL);
134 state->ppll_cntl |= PPLL_CNTL__PPLL_ATOMIC_UPDATE_EN |
135 PPLL_CNTL__PPLL_ATOMIC_UPDATE_SYNC |
136 PPLL_CNTL__PPLL_VGA_ATOMIC_UPDATE_EN;
137 state->ppll_cntl &= ~PPLL_CNTL__PPLL_TST_EN;
138 state->ppll_cntl &= ~PPLL_CNTL__PPLL_TCPOFF;
139 state->ppll_cntl &= ~PPLL_CNTL__PPLL_TVCOMAX;
140 state->ppll_cntl &= ~PPLL_CNTL__PPLL_DISABLE_AUTO_RESET;
141 state->ppll_ref_div = 0;
142 state->ppll_ref_div = REG_S(PPLL_REF_DIV, PPLL_REF_DIV, 12) |
143 REG_S(PPLL_REF_DIV, PPLL_REF_DIV_SRC, PPLL_REF_DIV_SRC__XTALIN);
144 state->ppll_div_0 = 0;
145 state->ppll_div_1 = 0;
146 state->ppll_div_2 = 0;
147 state->ppll_div_3 = 0;
148 state->vclk_ecp_cntl = 0;
149 state->htotal_cntl = 0;
153 * radeon_ms_crtc1_restore - restore CRTC state
154 * @dev_priv: radeon private structure
155 * @state: CRTC state to restore
157 void radeon_ms_crtc1_restore(struct drm_device *dev, struct radeon_state *state)
159 struct drm_radeon_private *dev_priv = dev->dev_private;
161 /* We prevent the CRTC from hitting the memory controller until
164 MMIO_W(CRTC_GEN_CNTL, ~CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B &
165 state->crtc_gen_cntl);
166 MMIO_W(CRTC_EXT_CNTL, CRTC_EXT_CNTL__CRTC_VSYNC_DIS |
167 CRTC_EXT_CNTL__CRTC_HSYNC_DIS |
168 CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
169 state->crtc_ext_cntl);
170 MMIO_W(SURFACE_CNTL, state->surface_cntl);
171 MMIO_W(SURFACE0_INFO, state->surface0_info);
172 MMIO_W(SURFACE0_LOWER_BOUND, state->surface0_lower_bound);
173 MMIO_W(SURFACE0_UPPER_BOUND, state->surface0_upper_bound);
174 MMIO_W(SURFACE1_INFO, state->surface1_info);
175 MMIO_W(SURFACE1_LOWER_BOUND, state->surface1_lower_bound);
176 MMIO_W(SURFACE1_UPPER_BOUND, state->surface1_upper_bound);
177 MMIO_W(SURFACE2_INFO, state->surface2_info);
178 MMIO_W(SURFACE2_LOWER_BOUND, state->surface2_lower_bound);
179 MMIO_W(SURFACE2_UPPER_BOUND, state->surface2_upper_bound);
180 MMIO_W(SURFACE3_INFO, state->surface3_info);
181 MMIO_W(SURFACE3_LOWER_BOUND, state->surface3_lower_bound);
182 MMIO_W(SURFACE3_UPPER_BOUND, state->surface3_upper_bound);
183 MMIO_W(SURFACE4_INFO, state->surface4_info);
184 MMIO_W(SURFACE4_LOWER_BOUND, state->surface4_lower_bound);
185 MMIO_W(SURFACE4_UPPER_BOUND, state->surface4_upper_bound);
186 MMIO_W(SURFACE5_INFO, state->surface5_info);
187 MMIO_W(SURFACE5_LOWER_BOUND, state->surface5_lower_bound);
188 MMIO_W(SURFACE5_UPPER_BOUND, state->surface5_upper_bound);
189 MMIO_W(SURFACE6_INFO, state->surface6_info);
190 MMIO_W(SURFACE6_LOWER_BOUND, state->surface6_lower_bound);
191 MMIO_W(SURFACE6_UPPER_BOUND, state->surface6_upper_bound);
192 MMIO_W(SURFACE7_INFO, state->surface7_info);
193 MMIO_W(SURFACE7_LOWER_BOUND, state->surface7_lower_bound);
194 MMIO_W(SURFACE7_UPPER_BOUND, state->surface7_upper_bound);
195 MMIO_W(CRTC_H_TOTAL_DISP, state->crtc_h_total_disp);
196 MMIO_W(CRTC_H_SYNC_STRT_WID, state->crtc_h_sync_strt_wid);
197 MMIO_W(CRTC_V_TOTAL_DISP, state->crtc_v_total_disp);
198 MMIO_W(CRTC_V_SYNC_STRT_WID, state->crtc_v_sync_strt_wid);
199 MMIO_W(FP_H_SYNC_STRT_WID, state->fp_h_sync_strt_wid);
200 MMIO_W(FP_V_SYNC_STRT_WID, state->fp_v_sync_strt_wid);
201 MMIO_W(FP_CRTC_H_TOTAL_DISP, state->fp_crtc_h_total_disp);
202 MMIO_W(FP_CRTC_V_TOTAL_DISP, state->fp_crtc_v_total_disp);
203 MMIO_W(CRTC_TILE_X0_Y0, state->crtc_tile_x0_y0);
204 MMIO_W(CRTC_OFFSET_CNTL, state->crtc_offset_cntl);
205 MMIO_W(CRTC_OFFSET, state->crtc_offset);
206 MMIO_W(CRTC_PITCH, state->crtc_pitch);
207 radeon_pll1_restore(dev_priv, state);
208 MMIO_W(CRTC_MORE_CNTL, state->crtc_more_cntl);
209 MMIO_W(CRTC_GEN_CNTL, state->crtc_gen_cntl);
210 MMIO_W(CRTC_EXT_CNTL, state->crtc_ext_cntl);
214 * radeon_pll1_restore - restore PLL1 state
215 * @dev_priv: radeon private structure
216 * @state: PLL1 state to restore
218 static void radeon_pll1_restore(struct drm_radeon_private *dev_priv,
219 struct radeon_state *state)
223 /* switch to gpu clock while programing new clock */
224 MMIO_W(CLOCK_CNTL_INDEX, state->clock_cntl_index);
225 tmp = state->vclk_ecp_cntl;
226 tmp = REG_S(VCLK_ECP_CNTL, VCLK_SRC_SEL, VCLK_SRC_SEL__CPUCLK);
227 PPLL_W(VCLK_ECP_CNTL, tmp);
228 /* reset PLL and update atomicly */
229 state->ppll_cntl |= PPLL_CNTL__PPLL_ATOMIC_UPDATE_EN |
230 PPLL_CNTL__PPLL_ATOMIC_UPDATE_SYNC;
232 PPLL_W(PPLL_CNTL, state->ppll_cntl | PPLL_CNTL__PPLL_RESET);
233 PPLL_W(PPLL_REF_DIV, state->ppll_ref_div);
234 PPLL_W(PPLL_DIV_0, state->ppll_div_0);
235 PPLL_W(PPLL_DIV_1, state->ppll_div_1);
236 PPLL_W(PPLL_DIV_2, state->ppll_div_2);
237 PPLL_W(PPLL_DIV_3, state->ppll_div_3);
238 PPLL_W(HTOTAL_CNTL, state->htotal_cntl);
241 PPLL_W(PPLL_REF_DIV, state->ppll_ref_div |
242 PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_W);
243 for (tmp = 0; tmp < 100; tmp++) {
244 if (!(PPLL_REF_DIV__PPLL_ATOMIC_UPDATE_R &
245 PPLL_R(PPLL_REF_DIV))) {
250 state->ppll_cntl &= ~PPLL_CNTL__PPLL_RESET;
251 PPLL_W(PPLL_CNTL, state->ppll_cntl);
252 PPLL_W(VCLK_ECP_CNTL, state->vclk_ecp_cntl);
256 * radeon_ms_crtc1_save - save CRTC state
257 * @dev_priv: radeon private structure
258 * @state: state where saving current CRTC state
260 void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state)
262 struct drm_radeon_private *dev_priv = dev->dev_private;
264 state->surface_cntl = MMIO_R(SURFACE_CNTL);
265 state->surface0_info = MMIO_R(SURFACE0_INFO);
266 state->surface0_lower_bound = MMIO_R(SURFACE0_LOWER_BOUND);
267 state->surface0_upper_bound = MMIO_R(SURFACE0_UPPER_BOUND);
268 state->surface1_info = MMIO_R(SURFACE1_INFO);
269 state->surface1_lower_bound = MMIO_R(SURFACE1_LOWER_BOUND);
270 state->surface1_upper_bound = MMIO_R(SURFACE1_UPPER_BOUND);
271 state->surface2_info = MMIO_R(SURFACE2_INFO);
272 state->surface2_lower_bound = MMIO_R(SURFACE2_LOWER_BOUND);
273 state->surface2_upper_bound = MMIO_R(SURFACE2_UPPER_BOUND);
274 state->surface3_info = MMIO_R(SURFACE3_INFO);
275 state->surface3_lower_bound = MMIO_R(SURFACE3_LOWER_BOUND);
276 state->surface3_upper_bound = MMIO_R(SURFACE3_UPPER_BOUND);
277 state->surface4_info = MMIO_R(SURFACE4_INFO);
278 state->surface4_lower_bound = MMIO_R(SURFACE4_LOWER_BOUND);
279 state->surface4_upper_bound = MMIO_R(SURFACE4_UPPER_BOUND);
280 state->surface5_info = MMIO_R(SURFACE5_INFO);
281 state->surface5_lower_bound = MMIO_R(SURFACE5_LOWER_BOUND);
282 state->surface5_upper_bound = MMIO_R(SURFACE5_UPPER_BOUND);
283 state->surface6_info = MMIO_R(SURFACE6_INFO);
284 state->surface6_lower_bound = MMIO_R(SURFACE6_LOWER_BOUND);
285 state->surface6_upper_bound = MMIO_R(SURFACE6_UPPER_BOUND);
286 state->surface7_info = MMIO_R(SURFACE7_INFO);
287 state->surface7_lower_bound = MMIO_R(SURFACE7_LOWER_BOUND);
288 state->surface7_upper_bound = MMIO_R(SURFACE7_UPPER_BOUND);
289 state->crtc_gen_cntl = MMIO_R(CRTC_GEN_CNTL);
290 state->crtc_ext_cntl = MMIO_R(CRTC_EXT_CNTL);
291 state->crtc_h_total_disp = MMIO_R(CRTC_H_TOTAL_DISP);
292 state->crtc_h_sync_strt_wid = MMIO_R(CRTC_H_SYNC_STRT_WID);
293 state->crtc_v_total_disp = MMIO_R(CRTC_V_TOTAL_DISP);
294 state->crtc_v_sync_strt_wid = MMIO_R(CRTC_V_SYNC_STRT_WID);
295 state->fp_h_sync_strt_wid = MMIO_R(FP_H_SYNC_STRT_WID);
296 state->fp_v_sync_strt_wid = MMIO_R(FP_V_SYNC_STRT_WID);
297 state->fp_crtc_h_total_disp = MMIO_R(FP_CRTC_H_TOTAL_DISP);
298 state->fp_crtc_v_total_disp = MMIO_R(FP_CRTC_V_TOTAL_DISP);
299 state->crtc_offset = MMIO_R(CRTC_OFFSET);
300 state->crtc_offset_cntl = MMIO_R(CRTC_OFFSET_CNTL);
301 state->crtc_pitch = MMIO_R(CRTC_PITCH);
302 state->crtc_more_cntl = MMIO_R(CRTC_MORE_CNTL);
303 state->crtc_tile_x0_y0 = MMIO_R(CRTC_TILE_X0_Y0);
304 radeon_pll1_save(dev_priv,state);
308 * radeon_pll1_save - save PLL1 state
309 * @dev_priv: radeon private structure
310 * @state: state where saving current PLL1 state
312 static void radeon_pll1_save(struct drm_radeon_private *dev_priv,
313 struct radeon_state *state)
315 state->clock_cntl_index = MMIO_R(CLOCK_CNTL_INDEX);
316 state->ppll_cntl = PPLL_R(PPLL_CNTL);
317 state->ppll_ref_div = PPLL_R(PPLL_REF_DIV);
318 state->ppll_div_0 = PPLL_R(PPLL_DIV_0);
319 state->ppll_div_1 = PPLL_R(PPLL_DIV_1);
320 state->ppll_div_2 = PPLL_R(PPLL_DIV_2);
321 state->ppll_div_3 = PPLL_R(PPLL_DIV_3);
322 state->vclk_ecp_cntl = PPLL_R(VCLK_ECP_CNTL);
323 state->htotal_cntl = PPLL_R(HTOTAL_CNTL);
326 static void radeon_ms_crtc1_dpms(struct drm_crtc *crtc, int mode)
328 struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
329 struct radeon_state *state = &dev_priv->driver_state;
331 state->crtc_gen_cntl &= ~CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
332 state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_DISPLAY_DIS;
333 state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_HSYNC_DIS;
334 state->crtc_ext_cntl &= ~CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
338 case DPMSModeStandby:
339 state->crtc_ext_cntl |=
340 CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
341 CRTC_EXT_CNTL__CRTC_HSYNC_DIS;
343 case DPMSModeSuspend:
344 state->crtc_ext_cntl |=
345 CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
346 CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
349 state->crtc_ext_cntl |=
350 CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
351 CRTC_EXT_CNTL__CRTC_HSYNC_DIS |
352 CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
353 state->crtc_gen_cntl |=
354 CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B;
357 MMIO_W(CRTC_GEN_CNTL, state->crtc_gen_cntl);
358 MMIO_W(CRTC_EXT_CNTL, state->crtc_ext_cntl);
360 dev_priv->crtc1_dpms = mode;
361 /* FIXME: once adding crtc2 remove this */
362 dev_priv->crtc2_dpms = mode;
363 radeon_ms_gpu_dpms(crtc->dev);
365 if (mode != DPMSModeOff) {
366 radeon_ms_crtc_load_lut(crtc);
370 static bool radeon_ms_crtc_mode_fixup(struct drm_crtc *crtc,
371 struct drm_display_mode *mode,
372 struct drm_display_mode *adjusted_mode)
377 static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc)
379 crtc->funcs->dpms(crtc, DPMSModeOff);
382 /* compute PLL registers values for requested video mode */
383 static int radeon_pll1_constraint(struct drm_device *dev,
388 struct drm_radeon_private *dev_priv = dev->dev_private;
391 if (rdiv < 2 || fdiv < 4) {
395 if (dfrq < 2000 || dfrq > 3300) {
398 if (pfrq < dev_priv->properties.pll_min_pll_freq ||
399 pfrq > dev_priv->properties.pll_max_pll_freq) {
405 static void radeon_pll1_compute(struct drm_crtc *crtc,
406 struct drm_display_mode *mode)
411 } *post_div, post_divs[] = {
412 /* From RAGE 128 VR/RAGE 128 GL Register
413 * Reference Manual (Technical Reference
414 * Manual P/N RRG-G04100-C Rev. 0.04), page
415 * 3-17 (PLL_DIV_[3:0]).
417 { 1, 0 }, /* VCLK_SRC */
418 { 2, 1 }, /* VCLK_SRC/2 */
419 { 4, 2 }, /* VCLK_SRC/4 */
420 { 8, 3 }, /* VCLK_SRC/8 */
421 { 3, 4 }, /* VCLK_SRC/3 */
422 { 16, 5 }, /* VCLK_SRC/16 */
423 { 6, 6 }, /* VCLK_SRC/6 */
424 { 12, 7 }, /* VCLK_SRC/12 */
427 struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
428 struct radeon_state *state = &dev_priv->driver_state;
429 int clock = mode->clock;
430 int rfrq = dev_priv->properties.pll_reference_freq;
437 int diff_cpfrq_best = 350000;
444 int diff_cpfrq = 350000;
446 /* clamp frequency into pll [min; max] frequency range */
447 if (clock > dev_priv->properties.pll_max_pll_freq) {
448 clock = dev_priv->properties.pll_max_pll_freq;
450 if ((clock * 12) < dev_priv->properties.pll_min_pll_freq) {
451 clock = dev_priv->properties.pll_min_pll_freq / 12;
454 /* maximize pll_ref_div while staying in boundary and minimizing
455 * the difference btw target frequency and programmed frequency */
456 for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
457 if (post_div->divider == 0) {
460 tfrq = clock * post_div->divider;
461 for (fdiv = 1023; fdiv >= 4; fdiv--) {
462 rdiv = (fdiv * rfrq) / tfrq;
463 if (radeon_pll1_constraint(crtc->dev, clock, rdiv,
464 fdiv, pdiv, rfrq, tfrq)) {
465 pfrq = (fdiv * rfrq) / rdiv;
466 diff_cpfrq = pfrq - tfrq;
467 if ((diff_cpfrq >= 0 &&
468 diff_cpfrq < diff_cpfrq_best) ||
469 (diff_cpfrq == diff_cpfrq_best &&
475 pdiv = post_div->divider;
476 pdiv_id = post_div->divider_id;
477 diff_cpfrq_best = diff_cpfrq;
482 state->ppll_ref_div =
483 REG_S(PPLL_REF_DIV, PPLL_REF_DIV, rdiv_best) |
484 REG_S(PPLL_REF_DIV, PPLL_REF_DIV_ACC, rdiv_best);
485 state->ppll_div_0 = REG_S(PPLL_DIV_0, PPLL_FB0_DIV, fdiv_best) |
486 REG_S(PPLL_DIV_0, PPLL_POST0_DIV, pdiv_id);
488 vco_freq = (fdiv_best * rfrq) / rdiv_best;
489 /* This is horribly crude: the VCO frequency range is divided into
490 * 3 parts, each part having a fixed PLL gain value.
492 if (vco_freq >= 300000) {
493 /* [300..max] MHz : 7 */
495 } else if (vco_freq >= 180000) {
496 /* [180..300) MHz : 4 */
499 /* [0..180) MHz : 1 */
502 state->ppll_cntl |= REG_S(PPLL_CNTL, PPLL_PVG, vco_gain);
503 state->vclk_ecp_cntl |= REG_S(VCLK_ECP_CNTL, VCLK_SRC_SEL,
504 VCLK_SRC_SEL__PPLLCLK);
505 state->htotal_cntl = 0;
506 DRM_INFO("rdiv: %d\n", rdiv_best);
507 DRM_INFO("fdiv: %d\n", fdiv_best);
508 DRM_INFO("pdiv: %d\n", pdiv);
509 DRM_INFO("pdiv: %d\n", pdiv_id);
510 DRM_INFO("tfrq: %d\n", tfrq_best);
511 DRM_INFO("pfrq: %d\n", pfrq_best);
512 DRM_INFO("PPLL_REF_DIV: 0x%08X\n", state->ppll_ref_div);
513 DRM_INFO("PPLL_DIV_0: 0x%08X\n", state->ppll_div_0);
514 DRM_INFO("PPLL_CNTL: 0x%08X\n", state->ppll_cntl);
515 DRM_INFO("VCLK_ECP_CNTL: 0x%08X\n", state->vclk_ecp_cntl);
518 static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc,
519 struct drm_display_mode *mode,
520 struct drm_display_mode *adjusted_mode,
523 struct drm_device *dev = crtc->dev;
524 struct drm_radeon_private *dev_priv = dev->dev_private;
525 struct radeon_state *state = &dev_priv->driver_state;
526 int format, hsync_wid, vsync_wid, pitch;
528 DRM_INFO("[radeon_ms] set modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x\n",
529 mode->mode_id, mode->name, mode->vrefresh, mode->clock,
530 mode->hdisplay, mode->hsync_start,
531 mode->hsync_end, mode->htotal,
532 mode->vdisplay, mode->vsync_start,
533 mode->vsync_end, mode->vtotal, mode->type);
534 DRM_INFO("[radeon_ms] set modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x (adjusted)\n",
535 adjusted_mode->mode_id, adjusted_mode->name, adjusted_mode->vrefresh, adjusted_mode->clock,
536 adjusted_mode->hdisplay, adjusted_mode->hsync_start,
537 adjusted_mode->hsync_end, adjusted_mode->htotal,
538 adjusted_mode->vdisplay, adjusted_mode->vsync_start,
539 adjusted_mode->vsync_end, adjusted_mode->vtotal, adjusted_mode->type);
540 if (crtc->fb == NULL) {
541 DRM_INFO("[radeon_ms] no FB bound\n");
545 /* only support RGB555,RGB565,ARGB8888 should satisfy all users */
546 switch (crtc->fb->bits_per_pixel) {
548 if (crtc->fb->depth == 15) {
559 DRM_ERROR("Unknown color depth %d\n", crtc->fb->bits_per_pixel);
562 radeon_pll1_compute(crtc, adjusted_mode);
564 state->crtc_offset = REG_S(CRTC_OFFSET, CRTC_OFFSET, crtc->fb->bo->offset);
565 state->crtc_gen_cntl = CRTC_GEN_CNTL__CRTC_EXT_DISP_EN |
566 CRTC_GEN_CNTL__CRTC_EN |
567 REG_S(CRTC_GEN_CNTL, CRTC_PIX_WIDTH, format);
568 if (adjusted_mode->flags & V_DBLSCAN) {
569 state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN;
571 if (adjusted_mode->flags & V_CSYNC) {
572 state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_C_SYNC_EN;
574 if (adjusted_mode->flags & V_INTERLACE) {
575 state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_INTERLACE_EN;
577 state->crtc_more_cntl = 0;
578 state->crtc_h_total_disp =
579 REG_S(CRTC_H_TOTAL_DISP,
581 (adjusted_mode->crtc_htotal/8) - 1) |
582 REG_S(CRTC_H_TOTAL_DISP,
584 (adjusted_mode->crtc_hdisplay/8) - 1);
585 hsync_wid = (adjusted_mode->crtc_hsync_end -
586 adjusted_mode->crtc_hsync_start) / 8;
590 if (hsync_wid > 0x3f) {
593 state->crtc_h_sync_strt_wid =
594 REG_S(CRTC_H_SYNC_STRT_WID,
595 CRTC_H_SYNC_WID, hsync_wid) |
596 REG_S(CRTC_H_SYNC_STRT_WID,
597 CRTC_H_SYNC_STRT_PIX,
598 adjusted_mode->crtc_hsync_start) |
599 REG_S(CRTC_H_SYNC_STRT_WID,
600 CRTC_H_SYNC_STRT_CHAR,
601 adjusted_mode->crtc_hsync_start/8);
602 if (adjusted_mode->flags & V_NHSYNC) {
603 state->crtc_h_sync_strt_wid |=
604 CRTC_H_SYNC_STRT_WID__CRTC_H_SYNC_POL;
607 state->crtc_v_total_disp =
608 REG_S(CRTC_V_TOTAL_DISP, CRTC_V_TOTAL,
609 adjusted_mode->crtc_vtotal - 1) |
610 REG_S(CRTC_V_TOTAL_DISP, CRTC_V_DISP,
611 adjusted_mode->crtc_vdisplay - 1);
612 vsync_wid = adjusted_mode->crtc_vsync_end -
613 adjusted_mode->crtc_vsync_start;
617 if (vsync_wid > 0x1f) {
620 state->crtc_v_sync_strt_wid =
621 REG_S(CRTC_V_SYNC_STRT_WID,
624 REG_S(CRTC_V_SYNC_STRT_WID,
626 adjusted_mode->crtc_vsync_start);
627 if (adjusted_mode->flags & V_NVSYNC) {
628 state->crtc_v_sync_strt_wid |=
629 CRTC_V_SYNC_STRT_WID__CRTC_V_SYNC_POL;
632 pitch = (crtc->fb->width * crtc->fb->bits_per_pixel +
633 ((crtc->fb->bits_per_pixel * 8)- 1)) /
634 (crtc->fb->bits_per_pixel * 8);
635 state->crtc_pitch = REG_S(CRTC_PITCH, CRTC_PITCH, pitch) |
636 REG_S(CRTC_PITCH, CRTC_PITCH_RIGHT, pitch);
638 state->fp_h_sync_strt_wid = state->crtc_h_sync_strt_wid;
639 state->fp_v_sync_strt_wid = state->crtc_v_sync_strt_wid;
640 state->fp_crtc_h_total_disp = state->crtc_h_total_disp;
641 state->fp_crtc_v_total_disp = state->crtc_v_total_disp;
643 radeon_ms_crtc1_restore(dev, state);
646 static void radeon_ms_crtc1_mode_set_base(struct drm_crtc *crtc, int x, int y)
648 struct drm_device *dev = crtc->dev;
649 struct drm_radeon_private *dev_priv = dev->dev_private;
650 struct radeon_state *state = &dev_priv->driver_state;
652 DRM_INFO("mode_set_base 0x%lX\n", crtc->fb->bo->offset);
653 state->crtc_offset = REG_S(CRTC_OFFSET, CRTC_OFFSET, crtc->fb->bo->offset);
654 radeon_ms_crtc1_restore(dev, state);
657 static void radeon_ms_crtc_mode_commit(struct drm_crtc *crtc)
659 crtc->funcs->dpms(crtc, DPMSModeOn);
662 static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r,
663 u16 g, u16 b, int regno)
665 struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
666 struct radeon_ms_crtc *radeon_ms_crtc = crtc->driver_private;
667 struct radeon_state *state = &dev_priv->driver_state;
673 DRM_INFO("[radeon_ms] gamma[%d]=(%d, %d, %d)\n", regno, r, g, b);
674 switch(radeon_ms_crtc->crtc) {
676 state->dac_cntl2 &= ~DAC_CNTL2__PALETTE_ACCESS_CNTL;
679 state->dac_cntl2 |= DAC_CNTL2__PALETTE_ACCESS_CNTL;
682 MMIO_W(DAC_CNTL2, state->dac_cntl2);
683 radeon_ms_crtc->lut_r[regno] = r;
684 radeon_ms_crtc->lut_g[regno] = g;
685 radeon_ms_crtc->lut_b[regno] = b;
686 MMIO_W(PALETTE_INDEX, REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno));
688 color = REG_S(PALETTE_DATA, PALETTE_DATA_R, r >> 8) |
689 REG_S(PALETTE_DATA, PALETTE_DATA_G, g >> 8) |
690 REG_S(PALETTE_DATA, PALETTE_DATA_B, b >> 8);
691 MMIO_W(PALETTE_DATA, color);
692 MMIO_W(PALETTE_INDEX,
693 REG_S(PALETTE_INDEX, PALETTE_W_INDEX, regno));
695 color = REG_S(PALETTE_30_DATA, PALETTE_DATA_R, r >> 6) |
696 REG_S(PALETTE_30_DATA, PALETTE_DATA_G, g >> 6) |
697 REG_S(PALETTE_30_DATA, PALETTE_DATA_B, b >> 6);
698 MMIO_W(PALETTE_30_DATA, color);
701 static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc)
703 struct radeon_ms_crtc *radeon_ms_crtc = crtc->driver_private;
709 for (i = 0; i < 256; i++) {
710 radeon_ms_crtc_gamma_set(crtc,
711 radeon_ms_crtc->lut_r[i],
712 radeon_ms_crtc->lut_g[i],
713 radeon_ms_crtc->lut_b[i],
718 static const struct drm_crtc_funcs radeon_ms_crtc1_funcs= {
719 .dpms = radeon_ms_crtc1_dpms,
720 .save = NULL, /* XXX */
721 .restore = NULL, /* XXX */
722 .prepare = radeon_ms_crtc_mode_prepare,
723 .commit = radeon_ms_crtc_mode_commit,
724 .mode_fixup = radeon_ms_crtc_mode_fixup,
725 .mode_set = radeon_ms_crtc1_mode_set,
726 .mode_set_base = radeon_ms_crtc1_mode_set_base,
727 .gamma_set = radeon_ms_crtc_gamma_set,
728 .cleanup = NULL, /* XXX */
731 int radeon_ms_crtc_create(struct drm_device *dev, int crtc)
733 struct drm_radeon_private *dev_priv = dev->dev_private;
734 struct drm_crtc *drm_crtc;
735 struct radeon_ms_crtc *radeon_ms_crtc;
740 radeon_ms_crtc1_init(dev_priv, &dev_priv->driver_state);
741 drm_crtc = drm_crtc_create(dev, &radeon_ms_crtc1_funcs);
747 if (drm_crtc == NULL) {
751 radeon_ms_crtc = drm_alloc(sizeof(struct radeon_ms_crtc), DRM_MEM_DRIVER);
752 if (radeon_ms_crtc == NULL) {
757 radeon_ms_crtc->crtc = crtc;
758 for (i = 0; i < 256; i++) {
759 radeon_ms_crtc->lut_r[i] = i << 8;
760 radeon_ms_crtc->lut_g[i] = i << 8;
761 radeon_ms_crtc->lut_b[i] = i << 8;
763 drm_crtc->driver_private = radeon_ms_crtc;