drm: userspace rip out TTM API
[platform/upstream/libdrm.git] / shared-core / radeon_ms_crtc.c
1 /*
2  * Copyright © 2007 Alex Deucher
3  * Copyright © 2007 Dave Airlie
4  * Copyright © 2007 Michel Dänzer
5  * Copyright © 2007 Jerome Glisse
6  *
7  * All Rights Reserved.
8  *
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:
16  *
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.
20  *
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.
29  */
30 #include "drmP.h"
31 #include "drm.h"
32 #include "drm_crtc.h"
33 #include "radeon_ms.h"
34
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);
42
43 /**
44  * radeon_ms_crtc1_init - initialize CRTC state
45  * @dev_priv: radeon private structure
46  * @state: state structure to initialize to default value
47  *
48  * Initialize CRTC state to default values
49  */
50 static void radeon_ms_crtc1_init(struct drm_radeon_private *dev_priv,
51                                  struct radeon_state *state)
52 {
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) {
93         case CHIP_R100:
94         case CHIP_R200:
95         case CHIP_RV200:
96         case CHIP_RV250:
97         case CHIP_RV280:
98         case CHIP_RS300:
99                 break;
100         case CHIP_R300:
101         case CHIP_R350:
102         case CHIP_R360:
103         case CHIP_RV350:
104         case CHIP_RV370:
105         case CHIP_RV380:
106         case CHIP_RS400:
107         case CHIP_RV410:
108         case CHIP_R420:
109         case CHIP_R430:
110         case CHIP_R480:
111                 state->crtc_offset_cntl |= REG_S(CRTC_OFFSET_CNTL,
112                                 CRTC_MICRO_TILE_BUFFER_MODE,
113                                 CRTC_MICRO_TILE_BUFFER_MODE__DIS);
114                 break;
115         default:
116                 DRM_ERROR("Unknown radeon family, aborting\n");
117                 return;
118         }
119         radeon_pll1_init(dev_priv, state);
120 }
121
122 /**
123  * radeon_pll1_init - initialize PLL1 state
124  * @dev_priv: radeon private structure
125  * @state: state structure to initialize to default value
126  *
127  * Initialize PLL1 state to default values
128  */
129 static void radeon_pll1_init(struct drm_radeon_private *dev_priv,
130                              struct radeon_state *state)
131 {
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;
150 }
151
152 /**
153  * radeon_ms_crtc1_restore - restore CRTC state
154  * @dev_priv: radeon private structure
155  * @state: CRTC state to restore
156  */
157 void radeon_ms_crtc1_restore(struct drm_device *dev, struct radeon_state *state)
158 {
159         struct drm_radeon_private *dev_priv = dev->dev_private;
160
161         /* We prevent the CRTC from hitting the memory controller until
162          * fully programmed
163          */
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);
211 }
212
213 /**
214  * radeon_pll1_restore - restore PLL1 state
215  * @dev_priv: radeon private structure
216  * @state: PLL1 state to restore
217  */
218 static void radeon_pll1_restore(struct drm_radeon_private *dev_priv,
219                                 struct radeon_state *state)
220 {
221         uint32_t tmp;
222
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; 
231
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);
239
240         /* update */
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))) {
246                       break;
247                 }
248                 DRM_UDELAY(10);
249         }
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);
253 }
254
255 /**
256  * radeon_ms_crtc1_save - save CRTC state
257  * @dev_priv: radeon private structure
258  * @state: state where saving current CRTC state
259  */
260 void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state)
261 {
262         struct drm_radeon_private *dev_priv = dev->dev_private;
263
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);
305 }
306
307 /**
308  * radeon_pll1_save - save PLL1 state
309  * @dev_priv: radeon private structure
310  * @state: state where saving current PLL1 state
311  */
312 static void radeon_pll1_save(struct drm_radeon_private *dev_priv,
313                              struct radeon_state *state)
314 {
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);
324 }
325
326 static void radeon_ms_crtc1_dpms(struct drm_crtc *crtc, int mode)
327 {
328         struct drm_radeon_private *dev_priv = crtc->dev->dev_private;
329         struct radeon_state *state = &dev_priv->driver_state;
330
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;
335         switch(mode) {
336         case DPMSModeOn:
337                 break;
338         case DPMSModeStandby:
339                 state->crtc_ext_cntl |=
340                         CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
341                         CRTC_EXT_CNTL__CRTC_HSYNC_DIS;
342                 break;
343         case DPMSModeSuspend:
344                 state->crtc_ext_cntl |=
345                         CRTC_EXT_CNTL__CRTC_DISPLAY_DIS |
346                         CRTC_EXT_CNTL__CRTC_VSYNC_DIS;
347                 break;
348         case DPMSModeOff:
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;
355                 break;
356         }
357         MMIO_W(CRTC_GEN_CNTL, state->crtc_gen_cntl);
358         MMIO_W(CRTC_EXT_CNTL, state->crtc_ext_cntl);
359
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);
364
365         if (mode != DPMSModeOff) {
366                 radeon_ms_crtc_load_lut(crtc);
367         }
368 }
369
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)
373 {
374         return true;
375 }
376
377 static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc)
378 {
379         crtc->funcs->dpms(crtc, DPMSModeOff);
380 }
381
382 /* compute PLL registers values for requested video mode */
383 static int radeon_pll1_constraint(struct drm_device *dev,
384                                   int clock, int rdiv,
385                                   int fdiv, int pdiv,
386                                   int rfrq, int pfrq)
387 {
388         struct drm_radeon_private *dev_priv = dev->dev_private;
389         int dfrq;
390
391         if (rdiv < 2 || fdiv < 4) {
392                 return 0;
393         }
394         dfrq = rfrq / rdiv;
395         if (dfrq < 2000 || dfrq > 3300) {
396                 return 0;
397         }
398         if (pfrq < dev_priv->properties.pll_min_pll_freq ||
399             pfrq > dev_priv->properties.pll_max_pll_freq) {
400                 return 0;
401         }
402         return 1;
403 }
404
405 static void radeon_pll1_compute(struct drm_crtc *crtc,
406                                 struct drm_display_mode *mode)
407 {
408         struct {
409                 int divider;
410                 int divider_id;
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]).
416                  */
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              */
425                 {  0, 0 }
426         };
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;
431         int pdiv = 1;
432         int pdiv_id = 0;
433         int rdiv_best = 2;
434         int fdiv_best = 4;
435         int tfrq_best = 0;
436         int pfrq_best = 0;
437         int diff_cpfrq_best = 350000;
438         int vco_freq;
439         int vco_gain;
440         int rdiv = 0;
441         int fdiv = 0;
442         int tfrq = 35000;
443         int pfrq = 35000;
444         int diff_cpfrq = 350000;
445
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;
449         }
450         if ((clock * 12) < dev_priv->properties.pll_min_pll_freq) {
451                 clock = dev_priv->properties.pll_min_pll_freq / 12;
452         }
453
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) {
458                         break;
459                 }
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 &&
470                                      rdiv > rdiv_best)) {
471                                         rdiv_best = rdiv;
472                                         fdiv_best = fdiv;
473                                         tfrq_best = tfrq;
474                                         pfrq_best = pfrq;
475                                         pdiv = post_div->divider;
476                                         pdiv_id = post_div->divider_id;
477                                         diff_cpfrq_best = diff_cpfrq;
478                                 }
479                         }
480                 }
481         }
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);
487
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.
491          */
492         if (vco_freq >= 300000) {
493                 /* [300..max] MHz : 7 */
494                 vco_gain = 7;
495         } else if (vco_freq >= 180000) {
496                 /* [180..300) MHz : 4 */
497                 vco_gain = 4;
498         } else {
499                 /* [0..180) MHz : 1 */
500                 vco_gain = 1;
501         }
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);
516 }
517
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,
521                                      int x, int y)
522 {
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;
527
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");
542                 return;
543         }
544
545         /* only support RGB555,RGB565,ARGB8888 should satisfy all users */
546         switch (crtc->fb->bits_per_pixel) {
547         case 16:
548                 if (crtc->fb->depth == 15) {
549                         format = 3;
550                 } else {
551                         format = 4;
552                 }
553                 break;
554         case 24:
555         case 32:
556                 format = 6;
557                 break;
558         default:
559                 DRM_ERROR("Unknown color depth %d\n", crtc->fb->bits_per_pixel);
560                 return;
561         }
562         radeon_pll1_compute(crtc, adjusted_mode);
563
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;
570         }
571         if (adjusted_mode->flags & V_CSYNC) {
572                 state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_C_SYNC_EN;
573         }
574         if (adjusted_mode->flags & V_INTERLACE) {
575                 state->crtc_gen_cntl |= CRTC_GEN_CNTL__CRTC_INTERLACE_EN;
576         }
577         state->crtc_more_cntl = 0;
578         state->crtc_h_total_disp =
579                 REG_S(CRTC_H_TOTAL_DISP,
580                                 CRTC_H_TOTAL,
581                                 (adjusted_mode->crtc_htotal/8) - 1) |
582                 REG_S(CRTC_H_TOTAL_DISP,
583                                 CRTC_H_DISP,
584                                 (adjusted_mode->crtc_hdisplay/8) - 1);
585         hsync_wid = (adjusted_mode->crtc_hsync_end -
586                      adjusted_mode->crtc_hsync_start) / 8;
587         if (!hsync_wid) {
588                 hsync_wid = 1;
589         }
590         if (hsync_wid > 0x3f) {
591                 hsync_wid = 0x3f;
592         }
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;
605         }
606
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;
614         if (!vsync_wid) {
615                 vsync_wid = 1;
616         }
617         if (vsync_wid > 0x1f) {
618                 vsync_wid = 0x1f;
619         }
620         state->crtc_v_sync_strt_wid =
621                 REG_S(CRTC_V_SYNC_STRT_WID,
622                                 CRTC_V_SYNC_WID,
623                                 vsync_wid) |
624                 REG_S(CRTC_V_SYNC_STRT_WID,
625                                 CRTC_V_SYNC_STRT,
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;
630         }
631
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);
637
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;
642
643         radeon_ms_crtc1_restore(dev, state);
644 }
645
646 static void radeon_ms_crtc1_mode_set_base(struct drm_crtc *crtc, int x, int y)
647 {
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;
651
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);
655 }
656
657 static void radeon_ms_crtc_mode_commit(struct drm_crtc *crtc)
658 {
659         crtc->funcs->dpms(crtc, DPMSModeOn);
660 }
661
662 static void radeon_ms_crtc_gamma_set(struct drm_crtc *crtc, u16 r,
663                                      u16 g, u16 b, int regno)
664 {
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;
668         uint32_t color;
669
670         if (regno >= 256) {
671                 return;
672         }
673         DRM_INFO("[radeon_ms] gamma[%d]=(%d, %d, %d)\n", regno, r, g, b);
674         switch(radeon_ms_crtc->crtc) {
675         case 1:
676                 state->dac_cntl2 &= ~DAC_CNTL2__PALETTE_ACCESS_CNTL;
677                 break;
678         case 2:
679                 state->dac_cntl2 |= DAC_CNTL2__PALETTE_ACCESS_CNTL;
680                 break;
681         }
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));
687         color = 0;
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));
694         color = 0;
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);
699 }
700
701 static void radeon_ms_crtc_load_lut(struct drm_crtc *crtc)
702 {
703         struct radeon_ms_crtc *radeon_ms_crtc = crtc->driver_private;
704         int i;
705
706         if (!crtc->enabled)
707                 return;
708
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],
714                                 i);
715         }
716 }
717
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 */
729 };
730
731 int radeon_ms_crtc_create(struct drm_device *dev, int crtc)
732 {
733         struct drm_radeon_private *dev_priv = dev->dev_private;
734         struct drm_crtc *drm_crtc;
735         struct radeon_ms_crtc *radeon_ms_crtc;
736         int i;
737
738         switch (crtc) {
739         case 1:
740                 radeon_ms_crtc1_init(dev_priv, &dev_priv->driver_state);
741                 drm_crtc = drm_crtc_create(dev, &radeon_ms_crtc1_funcs);
742                 break;
743         case 2:
744         default:
745                 return -EINVAL;
746         }
747         if (drm_crtc == NULL) {
748                 return -ENOMEM;
749         }
750
751         radeon_ms_crtc = drm_alloc(sizeof(struct radeon_ms_crtc), DRM_MEM_DRIVER);
752         if (radeon_ms_crtc == NULL) {
753                 kfree(drm_crtc);
754                 return -ENOMEM;
755         }
756
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;
762         }
763         drm_crtc->driver_private = radeon_ms_crtc;
764         return 0;
765 }