blob: c9d6f10ba92eb833620d1c686c234ffc574eb81a [file] [log] [blame]
Jesse Barnes79e53942008-11-07 14:24:08 -08001/*
2 * Copyright © 2006-2007 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 */
26
27#include <linux/i2c.h>
28#include "drmP.h"
29#include "intel_drv.h"
30#include "i915_drm.h"
31#include "i915_drv.h"
32
33#include "drm_crtc_helper.h"
34
35bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
36
37typedef struct {
38 /* given values */
39 int n;
40 int m1, m2;
41 int p1, p2;
42 /* derived values */
43 int dot;
44 int vco;
45 int m;
46 int p;
47} intel_clock_t;
48
49typedef struct {
50 int min, max;
51} intel_range_t;
52
53typedef struct {
54 int dot_limit;
55 int p2_slow, p2_fast;
56} intel_p2_t;
57
58#define INTEL_P2_NUM 2
Ma Lingd4906092009-03-18 20:13:27 +080059typedef struct intel_limit intel_limit_t;
60struct intel_limit {
Jesse Barnes79e53942008-11-07 14:24:08 -080061 intel_range_t dot, vco, n, m, m1, m2, p, p1;
62 intel_p2_t p2;
Ma Lingd4906092009-03-18 20:13:27 +080063 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
64 int, int, intel_clock_t *);
65};
Jesse Barnes79e53942008-11-07 14:24:08 -080066
67#define I8XX_DOT_MIN 25000
68#define I8XX_DOT_MAX 350000
69#define I8XX_VCO_MIN 930000
70#define I8XX_VCO_MAX 1400000
71#define I8XX_N_MIN 3
72#define I8XX_N_MAX 16
73#define I8XX_M_MIN 96
74#define I8XX_M_MAX 140
75#define I8XX_M1_MIN 18
76#define I8XX_M1_MAX 26
77#define I8XX_M2_MIN 6
78#define I8XX_M2_MAX 16
79#define I8XX_P_MIN 4
80#define I8XX_P_MAX 128
81#define I8XX_P1_MIN 2
82#define I8XX_P1_MAX 33
83#define I8XX_P1_LVDS_MIN 1
84#define I8XX_P1_LVDS_MAX 6
85#define I8XX_P2_SLOW 4
86#define I8XX_P2_FAST 2
87#define I8XX_P2_LVDS_SLOW 14
88#define I8XX_P2_LVDS_FAST 14 /* No fast option */
89#define I8XX_P2_SLOW_LIMIT 165000
90
91#define I9XX_DOT_MIN 20000
92#define I9XX_DOT_MAX 400000
93#define I9XX_VCO_MIN 1400000
94#define I9XX_VCO_MAX 2800000
Shaohua Li21778322009-02-23 15:19:16 +080095#define IGD_VCO_MIN 1700000
96#define IGD_VCO_MAX 3500000
Kristian Høgsbergf3cade52009-02-13 20:56:50 -050097#define I9XX_N_MIN 1
98#define I9XX_N_MAX 6
Shaohua Li21778322009-02-23 15:19:16 +080099/* IGD's Ncounter is a ring counter */
100#define IGD_N_MIN 3
101#define IGD_N_MAX 6
Jesse Barnes79e53942008-11-07 14:24:08 -0800102#define I9XX_M_MIN 70
103#define I9XX_M_MAX 120
Shaohua Li21778322009-02-23 15:19:16 +0800104#define IGD_M_MIN 2
105#define IGD_M_MAX 256
Jesse Barnes79e53942008-11-07 14:24:08 -0800106#define I9XX_M1_MIN 10
Kristian Høgsbergf3cade52009-02-13 20:56:50 -0500107#define I9XX_M1_MAX 22
Jesse Barnes79e53942008-11-07 14:24:08 -0800108#define I9XX_M2_MIN 5
109#define I9XX_M2_MAX 9
Shaohua Li21778322009-02-23 15:19:16 +0800110/* IGD M1 is reserved, and must be 0 */
111#define IGD_M1_MIN 0
112#define IGD_M1_MAX 0
113#define IGD_M2_MIN 0
114#define IGD_M2_MAX 254
Jesse Barnes79e53942008-11-07 14:24:08 -0800115#define I9XX_P_SDVO_DAC_MIN 5
116#define I9XX_P_SDVO_DAC_MAX 80
117#define I9XX_P_LVDS_MIN 7
118#define I9XX_P_LVDS_MAX 98
Shaohua Li21778322009-02-23 15:19:16 +0800119#define IGD_P_LVDS_MIN 7
120#define IGD_P_LVDS_MAX 112
Jesse Barnes79e53942008-11-07 14:24:08 -0800121#define I9XX_P1_MIN 1
122#define I9XX_P1_MAX 8
123#define I9XX_P2_SDVO_DAC_SLOW 10
124#define I9XX_P2_SDVO_DAC_FAST 5
125#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000
126#define I9XX_P2_LVDS_SLOW 14
127#define I9XX_P2_LVDS_FAST 7
128#define I9XX_P2_LVDS_SLOW_LIMIT 112000
129
130#define INTEL_LIMIT_I8XX_DVO_DAC 0
131#define INTEL_LIMIT_I8XX_LVDS 1
132#define INTEL_LIMIT_I9XX_SDVO_DAC 2
133#define INTEL_LIMIT_I9XX_LVDS 3
Ma Ling044c7c42009-03-18 20:13:23 +0800134#define INTEL_LIMIT_G4X_SDVO 4
135#define INTEL_LIMIT_G4X_HDMI_DAC 5
136#define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6
137#define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7
Shaohua Li21778322009-02-23 15:19:16 +0800138#define INTEL_LIMIT_IGD_SDVO_DAC 8
139#define INTEL_LIMIT_IGD_LVDS 9
Ma Ling044c7c42009-03-18 20:13:23 +0800140
141/*The parameter is for SDVO on G4x platform*/
142#define G4X_DOT_SDVO_MIN 25000
143#define G4X_DOT_SDVO_MAX 270000
144#define G4X_VCO_MIN 1750000
145#define G4X_VCO_MAX 3500000
146#define G4X_N_SDVO_MIN 1
147#define G4X_N_SDVO_MAX 4
148#define G4X_M_SDVO_MIN 104
149#define G4X_M_SDVO_MAX 138
150#define G4X_M1_SDVO_MIN 17
151#define G4X_M1_SDVO_MAX 23
152#define G4X_M2_SDVO_MIN 5
153#define G4X_M2_SDVO_MAX 11
154#define G4X_P_SDVO_MIN 10
155#define G4X_P_SDVO_MAX 30
156#define G4X_P1_SDVO_MIN 1
157#define G4X_P1_SDVO_MAX 3
158#define G4X_P2_SDVO_SLOW 10
159#define G4X_P2_SDVO_FAST 10
160#define G4X_P2_SDVO_LIMIT 270000
161
162/*The parameter is for HDMI_DAC on G4x platform*/
163#define G4X_DOT_HDMI_DAC_MIN 22000
164#define G4X_DOT_HDMI_DAC_MAX 400000
165#define G4X_N_HDMI_DAC_MIN 1
166#define G4X_N_HDMI_DAC_MAX 4
167#define G4X_M_HDMI_DAC_MIN 104
168#define G4X_M_HDMI_DAC_MAX 138
169#define G4X_M1_HDMI_DAC_MIN 16
170#define G4X_M1_HDMI_DAC_MAX 23
171#define G4X_M2_HDMI_DAC_MIN 5
172#define G4X_M2_HDMI_DAC_MAX 11
173#define G4X_P_HDMI_DAC_MIN 5
174#define G4X_P_HDMI_DAC_MAX 80
175#define G4X_P1_HDMI_DAC_MIN 1
176#define G4X_P1_HDMI_DAC_MAX 8
177#define G4X_P2_HDMI_DAC_SLOW 10
178#define G4X_P2_HDMI_DAC_FAST 5
179#define G4X_P2_HDMI_DAC_LIMIT 165000
180
181/*The parameter is for SINGLE_CHANNEL_LVDS on G4x platform*/
182#define G4X_DOT_SINGLE_CHANNEL_LVDS_MIN 20000
183#define G4X_DOT_SINGLE_CHANNEL_LVDS_MAX 115000
184#define G4X_N_SINGLE_CHANNEL_LVDS_MIN 1
185#define G4X_N_SINGLE_CHANNEL_LVDS_MAX 3
186#define G4X_M_SINGLE_CHANNEL_LVDS_MIN 104
187#define G4X_M_SINGLE_CHANNEL_LVDS_MAX 138
188#define G4X_M1_SINGLE_CHANNEL_LVDS_MIN 17
189#define G4X_M1_SINGLE_CHANNEL_LVDS_MAX 23
190#define G4X_M2_SINGLE_CHANNEL_LVDS_MIN 5
191#define G4X_M2_SINGLE_CHANNEL_LVDS_MAX 11
192#define G4X_P_SINGLE_CHANNEL_LVDS_MIN 28
193#define G4X_P_SINGLE_CHANNEL_LVDS_MAX 112
194#define G4X_P1_SINGLE_CHANNEL_LVDS_MIN 2
195#define G4X_P1_SINGLE_CHANNEL_LVDS_MAX 8
196#define G4X_P2_SINGLE_CHANNEL_LVDS_SLOW 14
197#define G4X_P2_SINGLE_CHANNEL_LVDS_FAST 14
198#define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT 0
199
200/*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/
201#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN 80000
202#define G4X_DOT_DUAL_CHANNEL_LVDS_MAX 224000
203#define G4X_N_DUAL_CHANNEL_LVDS_MIN 1
204#define G4X_N_DUAL_CHANNEL_LVDS_MAX 3
205#define G4X_M_DUAL_CHANNEL_LVDS_MIN 104
206#define G4X_M_DUAL_CHANNEL_LVDS_MAX 138
207#define G4X_M1_DUAL_CHANNEL_LVDS_MIN 17
208#define G4X_M1_DUAL_CHANNEL_LVDS_MAX 23
209#define G4X_M2_DUAL_CHANNEL_LVDS_MIN 5
210#define G4X_M2_DUAL_CHANNEL_LVDS_MAX 11
211#define G4X_P_DUAL_CHANNEL_LVDS_MIN 14
212#define G4X_P_DUAL_CHANNEL_LVDS_MAX 42
213#define G4X_P1_DUAL_CHANNEL_LVDS_MIN 2
214#define G4X_P1_DUAL_CHANNEL_LVDS_MAX 6
215#define G4X_P2_DUAL_CHANNEL_LVDS_SLOW 7
216#define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7
217#define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0
218
Ma Lingd4906092009-03-18 20:13:27 +0800219static bool
220intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
221 int target, int refclk, intel_clock_t *best_clock);
222static bool
223intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
224 int target, int refclk, intel_clock_t *best_clock);
Jesse Barnes79e53942008-11-07 14:24:08 -0800225
226static const intel_limit_t intel_limits[] = {
227 { /* INTEL_LIMIT_I8XX_DVO_DAC */
228 .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
229 .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
230 .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
231 .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX },
232 .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX },
233 .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX },
234 .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX },
235 .p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX },
236 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
237 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
Ma Lingd4906092009-03-18 20:13:27 +0800238 .find_pll = intel_find_best_PLL,
Jesse Barnes79e53942008-11-07 14:24:08 -0800239 },
240 { /* INTEL_LIMIT_I8XX_LVDS */
241 .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
242 .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
243 .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
244 .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX },
245 .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX },
246 .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX },
247 .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX },
248 .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX },
249 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
250 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
Ma Lingd4906092009-03-18 20:13:27 +0800251 .find_pll = intel_find_best_PLL,
Jesse Barnes79e53942008-11-07 14:24:08 -0800252 },
253 { /* INTEL_LIMIT_I9XX_SDVO_DAC */
254 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
255 .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
256 .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
257 .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX },
258 .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX },
259 .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX },
260 .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX },
261 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
262 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
263 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
Ma Lingd4906092009-03-18 20:13:27 +0800264 .find_pll = intel_find_best_PLL,
Jesse Barnes79e53942008-11-07 14:24:08 -0800265 },
266 { /* INTEL_LIMIT_I9XX_LVDS */
267 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
268 .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
269 .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
270 .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX },
271 .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX },
272 .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX },
273 .p = { .min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX },
274 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
275 /* The single-channel range is 25-112Mhz, and dual-channel
276 * is 80-224Mhz. Prefer single channel as much as possible.
277 */
278 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
279 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
Ma Lingd4906092009-03-18 20:13:27 +0800280 .find_pll = intel_find_best_PLL,
Jesse Barnes79e53942008-11-07 14:24:08 -0800281 },
Ma Ling044c7c42009-03-18 20:13:23 +0800282 /* below parameter and function is for G4X Chipset Family*/
283 { /* INTEL_LIMIT_G4X_SDVO */
284 .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX },
285 .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX},
286 .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX },
287 .m = { .min = G4X_M_SDVO_MIN, .max = G4X_M_SDVO_MAX },
288 .m1 = { .min = G4X_M1_SDVO_MIN, .max = G4X_M1_SDVO_MAX },
289 .m2 = { .min = G4X_M2_SDVO_MIN, .max = G4X_M2_SDVO_MAX },
290 .p = { .min = G4X_P_SDVO_MIN, .max = G4X_P_SDVO_MAX },
291 .p1 = { .min = G4X_P1_SDVO_MIN, .max = G4X_P1_SDVO_MAX},
292 .p2 = { .dot_limit = G4X_P2_SDVO_LIMIT,
293 .p2_slow = G4X_P2_SDVO_SLOW,
294 .p2_fast = G4X_P2_SDVO_FAST
295 },
Ma Lingd4906092009-03-18 20:13:27 +0800296 .find_pll = intel_g4x_find_best_PLL,
Ma Ling044c7c42009-03-18 20:13:23 +0800297 },
298 { /* INTEL_LIMIT_G4X_HDMI_DAC */
299 .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX },
300 .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX},
301 .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX },
302 .m = { .min = G4X_M_HDMI_DAC_MIN, .max = G4X_M_HDMI_DAC_MAX },
303 .m1 = { .min = G4X_M1_HDMI_DAC_MIN, .max = G4X_M1_HDMI_DAC_MAX },
304 .m2 = { .min = G4X_M2_HDMI_DAC_MIN, .max = G4X_M2_HDMI_DAC_MAX },
305 .p = { .min = G4X_P_HDMI_DAC_MIN, .max = G4X_P_HDMI_DAC_MAX },
306 .p1 = { .min = G4X_P1_HDMI_DAC_MIN, .max = G4X_P1_HDMI_DAC_MAX},
307 .p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT,
308 .p2_slow = G4X_P2_HDMI_DAC_SLOW,
309 .p2_fast = G4X_P2_HDMI_DAC_FAST
310 },
Ma Lingd4906092009-03-18 20:13:27 +0800311 .find_pll = intel_g4x_find_best_PLL,
Ma Ling044c7c42009-03-18 20:13:23 +0800312 },
313 { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */
314 .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN,
315 .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX },
316 .vco = { .min = G4X_VCO_MIN,
317 .max = G4X_VCO_MAX },
318 .n = { .min = G4X_N_SINGLE_CHANNEL_LVDS_MIN,
319 .max = G4X_N_SINGLE_CHANNEL_LVDS_MAX },
320 .m = { .min = G4X_M_SINGLE_CHANNEL_LVDS_MIN,
321 .max = G4X_M_SINGLE_CHANNEL_LVDS_MAX },
322 .m1 = { .min = G4X_M1_SINGLE_CHANNEL_LVDS_MIN,
323 .max = G4X_M1_SINGLE_CHANNEL_LVDS_MAX },
324 .m2 = { .min = G4X_M2_SINGLE_CHANNEL_LVDS_MIN,
325 .max = G4X_M2_SINGLE_CHANNEL_LVDS_MAX },
326 .p = { .min = G4X_P_SINGLE_CHANNEL_LVDS_MIN,
327 .max = G4X_P_SINGLE_CHANNEL_LVDS_MAX },
328 .p1 = { .min = G4X_P1_SINGLE_CHANNEL_LVDS_MIN,
329 .max = G4X_P1_SINGLE_CHANNEL_LVDS_MAX },
330 .p2 = { .dot_limit = G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT,
331 .p2_slow = G4X_P2_SINGLE_CHANNEL_LVDS_SLOW,
332 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
333 },
Ma Lingd4906092009-03-18 20:13:27 +0800334 .find_pll = intel_g4x_find_best_PLL,
Ma Ling044c7c42009-03-18 20:13:23 +0800335 },
336 { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */
337 .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN,
338 .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX },
339 .vco = { .min = G4X_VCO_MIN,
340 .max = G4X_VCO_MAX },
341 .n = { .min = G4X_N_DUAL_CHANNEL_LVDS_MIN,
342 .max = G4X_N_DUAL_CHANNEL_LVDS_MAX },
343 .m = { .min = G4X_M_DUAL_CHANNEL_LVDS_MIN,
344 .max = G4X_M_DUAL_CHANNEL_LVDS_MAX },
345 .m1 = { .min = G4X_M1_DUAL_CHANNEL_LVDS_MIN,
346 .max = G4X_M1_DUAL_CHANNEL_LVDS_MAX },
347 .m2 = { .min = G4X_M2_DUAL_CHANNEL_LVDS_MIN,
348 .max = G4X_M2_DUAL_CHANNEL_LVDS_MAX },
349 .p = { .min = G4X_P_DUAL_CHANNEL_LVDS_MIN,
350 .max = G4X_P_DUAL_CHANNEL_LVDS_MAX },
351 .p1 = { .min = G4X_P1_DUAL_CHANNEL_LVDS_MIN,
352 .max = G4X_P1_DUAL_CHANNEL_LVDS_MAX },
353 .p2 = { .dot_limit = G4X_P2_DUAL_CHANNEL_LVDS_LIMIT,
354 .p2_slow = G4X_P2_DUAL_CHANNEL_LVDS_SLOW,
355 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
356 },
Ma Lingd4906092009-03-18 20:13:27 +0800357 .find_pll = intel_g4x_find_best_PLL,
Ma Ling044c7c42009-03-18 20:13:23 +0800358 },
Shaohua Li21778322009-02-23 15:19:16 +0800359 { /* INTEL_LIMIT_IGD_SDVO */
360 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
361 .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
362 .n = { .min = IGD_N_MIN, .max = IGD_N_MAX },
363 .m = { .min = IGD_M_MIN, .max = IGD_M_MAX },
364 .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX },
365 .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX },
366 .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX },
367 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
368 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
369 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
Shaohua Li61157072009-04-03 15:24:43 +0800370 .find_pll = intel_find_best_PLL,
Shaohua Li21778322009-02-23 15:19:16 +0800371 },
372 { /* INTEL_LIMIT_IGD_LVDS */
373 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
374 .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
375 .n = { .min = IGD_N_MIN, .max = IGD_N_MAX },
376 .m = { .min = IGD_M_MIN, .max = IGD_M_MAX },
377 .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX },
378 .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX },
379 .p = { .min = IGD_P_LVDS_MIN, .max = IGD_P_LVDS_MAX },
380 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
381 /* IGD only supports single-channel mode. */
382 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
383 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
Shaohua Li61157072009-04-03 15:24:43 +0800384 .find_pll = intel_find_best_PLL,
Shaohua Li21778322009-02-23 15:19:16 +0800385 },
386
Jesse Barnes79e53942008-11-07 14:24:08 -0800387};
388
Ma Ling044c7c42009-03-18 20:13:23 +0800389static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
390{
391 struct drm_device *dev = crtc->dev;
392 struct drm_i915_private *dev_priv = dev->dev_private;
393 const intel_limit_t *limit;
394
395 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
396 if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
397 LVDS_CLKB_POWER_UP)
398 /* LVDS with dual channel */
399 limit = &intel_limits
400 [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS];
401 else
402 /* LVDS with dual channel */
403 limit = &intel_limits
404 [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS];
405 } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) ||
406 intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
407 limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC];
408 } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
409 limit = &intel_limits[INTEL_LIMIT_G4X_SDVO];
410 } else /* The option is for other outputs */
411 limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
412
413 return limit;
414}
415
Jesse Barnes79e53942008-11-07 14:24:08 -0800416static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
417{
418 struct drm_device *dev = crtc->dev;
419 const intel_limit_t *limit;
420
Ma Ling044c7c42009-03-18 20:13:23 +0800421 if (IS_G4X(dev)) {
422 limit = intel_g4x_limit(crtc);
Shaohua Li21778322009-02-23 15:19:16 +0800423 } else if (IS_I9XX(dev) && !IS_IGD(dev)) {
Jesse Barnes79e53942008-11-07 14:24:08 -0800424 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
425 limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
426 else
427 limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
Shaohua Li21778322009-02-23 15:19:16 +0800428 } else if (IS_IGD(dev)) {
429 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
430 limit = &intel_limits[INTEL_LIMIT_IGD_LVDS];
431 else
432 limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC];
Jesse Barnes79e53942008-11-07 14:24:08 -0800433 } else {
434 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
435 limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
436 else
437 limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC];
438 }
439 return limit;
440}
441
Shaohua Li21778322009-02-23 15:19:16 +0800442/* m1 is reserved as 0 in IGD, n is a ring counter */
443static void igd_clock(int refclk, intel_clock_t *clock)
Jesse Barnes79e53942008-11-07 14:24:08 -0800444{
Shaohua Li21778322009-02-23 15:19:16 +0800445 clock->m = clock->m2 + 2;
446 clock->p = clock->p1 * clock->p2;
447 clock->vco = refclk * clock->m / clock->n;
448 clock->dot = clock->vco / clock->p;
449}
450
451static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
452{
453 if (IS_IGD(dev)) {
454 igd_clock(refclk, clock);
455 return;
456 }
Jesse Barnes79e53942008-11-07 14:24:08 -0800457 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
458 clock->p = clock->p1 * clock->p2;
459 clock->vco = refclk * clock->m / (clock->n + 2);
460 clock->dot = clock->vco / clock->p;
461}
462
Jesse Barnes79e53942008-11-07 14:24:08 -0800463/**
464 * Returns whether any output on the specified pipe is of the specified type
465 */
466bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
467{
468 struct drm_device *dev = crtc->dev;
469 struct drm_mode_config *mode_config = &dev->mode_config;
470 struct drm_connector *l_entry;
471
472 list_for_each_entry(l_entry, &mode_config->connector_list, head) {
473 if (l_entry->encoder &&
474 l_entry->encoder->crtc == crtc) {
475 struct intel_output *intel_output = to_intel_output(l_entry);
476 if (intel_output->type == type)
477 return true;
478 }
479 }
480 return false;
481}
482
Jesse Barnes7c04d1d2009-02-23 15:36:40 -0800483#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0)
Jesse Barnes79e53942008-11-07 14:24:08 -0800484/**
485 * Returns whether the given set of divisors are valid for a given refclk with
486 * the given connectors.
487 */
488
489static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
490{
491 const intel_limit_t *limit = intel_limit (crtc);
Shaohua Li21778322009-02-23 15:19:16 +0800492 struct drm_device *dev = crtc->dev;
Jesse Barnes79e53942008-11-07 14:24:08 -0800493
494 if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
495 INTELPllInvalid ("p1 out of range\n");
496 if (clock->p < limit->p.min || limit->p.max < clock->p)
497 INTELPllInvalid ("p out of range\n");
498 if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
499 INTELPllInvalid ("m2 out of range\n");
500 if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
501 INTELPllInvalid ("m1 out of range\n");
Shaohua Li21778322009-02-23 15:19:16 +0800502 if (clock->m1 <= clock->m2 && !IS_IGD(dev))
Jesse Barnes79e53942008-11-07 14:24:08 -0800503 INTELPllInvalid ("m1 <= m2\n");
504 if (clock->m < limit->m.min || limit->m.max < clock->m)
505 INTELPllInvalid ("m out of range\n");
506 if (clock->n < limit->n.min || limit->n.max < clock->n)
507 INTELPllInvalid ("n out of range\n");
508 if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
509 INTELPllInvalid ("vco out of range\n");
510 /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
511 * connector, etc., rather than just a single range.
512 */
513 if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
514 INTELPllInvalid ("dot out of range\n");
515
516 return true;
517}
518
Ma Lingd4906092009-03-18 20:13:27 +0800519static bool
520intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
521 int target, int refclk, intel_clock_t *best_clock)
522
Jesse Barnes79e53942008-11-07 14:24:08 -0800523{
524 struct drm_device *dev = crtc->dev;
525 struct drm_i915_private *dev_priv = dev->dev_private;
526 intel_clock_t clock;
Jesse Barnes79e53942008-11-07 14:24:08 -0800527 int err = target;
528
529 if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
530 (I915_READ(LVDS) & LVDS_PORT_EN) != 0) {
531 /*
532 * For LVDS, if the panel is on, just rely on its current
533 * settings for dual-channel. We haven't figured out how to
534 * reliably set up different single/dual channel state, if we
535 * even can.
536 */
537 if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
538 LVDS_CLKB_POWER_UP)
539 clock.p2 = limit->p2.p2_fast;
540 else
541 clock.p2 = limit->p2.p2_slow;
542 } else {
543 if (target < limit->p2.dot_limit)
544 clock.p2 = limit->p2.p2_slow;
545 else
546 clock.p2 = limit->p2.p2_fast;
547 }
548
549 memset (best_clock, 0, sizeof (*best_clock));
550
551 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
Shaohua Li21778322009-02-23 15:19:16 +0800552 for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
553 /* m1 is always 0 in IGD */
554 if (clock.m2 >= clock.m1 && !IS_IGD(dev))
555 break;
Jesse Barnes79e53942008-11-07 14:24:08 -0800556 for (clock.n = limit->n.min; clock.n <= limit->n.max;
557 clock.n++) {
558 for (clock.p1 = limit->p1.min;
559 clock.p1 <= limit->p1.max; clock.p1++) {
560 int this_err;
561
Shaohua Li21778322009-02-23 15:19:16 +0800562 intel_clock(dev, refclk, &clock);
Jesse Barnes79e53942008-11-07 14:24:08 -0800563
564 if (!intel_PLL_is_valid(crtc, &clock))
565 continue;
566
567 this_err = abs(clock.dot - target);
568 if (this_err < err) {
569 *best_clock = clock;
570 err = this_err;
571 }
572 }
573 }
574 }
575 }
576
577 return (err != target);
578}
579
Ma Lingd4906092009-03-18 20:13:27 +0800580static bool
581intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
582 int target, int refclk, intel_clock_t *best_clock)
583{
584 struct drm_device *dev = crtc->dev;
585 struct drm_i915_private *dev_priv = dev->dev_private;
586 intel_clock_t clock;
587 int max_n;
588 bool found;
589 /* approximately equals target * 0.00488 */
590 int err_most = (target >> 8) + (target >> 10);
591 found = false;
592
593 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
594 if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
595 LVDS_CLKB_POWER_UP)
596 clock.p2 = limit->p2.p2_fast;
597 else
598 clock.p2 = limit->p2.p2_slow;
599 } else {
600 if (target < limit->p2.dot_limit)
601 clock.p2 = limit->p2.p2_slow;
602 else
603 clock.p2 = limit->p2.p2_fast;
604 }
605
606 memset(best_clock, 0, sizeof(*best_clock));
607 max_n = limit->n.max;
608 /* based on hardware requriment prefer smaller n to precision */
609 for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
610 /* based on hardware requirment prefere larger m1,m2, p1 */
611 for (clock.m1 = limit->m1.max;
612 clock.m1 >= limit->m1.min; clock.m1--) {
613 for (clock.m2 = limit->m2.max;
614 clock.m2 >= limit->m2.min; clock.m2--) {
615 for (clock.p1 = limit->p1.max;
616 clock.p1 >= limit->p1.min; clock.p1--) {
617 int this_err;
618
Shaohua Li21778322009-02-23 15:19:16 +0800619 intel_clock(dev, refclk, &clock);
Ma Lingd4906092009-03-18 20:13:27 +0800620 if (!intel_PLL_is_valid(crtc, &clock))
621 continue;
622 this_err = abs(clock.dot - target) ;
623 if (this_err < err_most) {
624 *best_clock = clock;
625 err_most = this_err;
626 max_n = clock.n;
627 found = true;
628 }
629 }
630 }
631 }
632 }
633
634 return found;
635}
636
Jesse Barnes79e53942008-11-07 14:24:08 -0800637void
638intel_wait_for_vblank(struct drm_device *dev)
639{
640 /* Wait for 20ms, i.e. one cycle at 50hz. */
Arjan van de Ven580982d2009-03-23 13:36:25 -0700641 mdelay(20);
Jesse Barnes79e53942008-11-07 14:24:08 -0800642}
643
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000644static int
Kristian Høgsberg3c4fdcf2008-12-17 22:14:46 -0500645intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
646 struct drm_framebuffer *old_fb)
Jesse Barnes79e53942008-11-07 14:24:08 -0800647{
648 struct drm_device *dev = crtc->dev;
649 struct drm_i915_private *dev_priv = dev->dev_private;
650 struct drm_i915_master_private *master_priv;
651 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
652 struct intel_framebuffer *intel_fb;
653 struct drm_i915_gem_object *obj_priv;
654 struct drm_gem_object *obj;
655 int pipe = intel_crtc->pipe;
656 unsigned long Start, Offset;
657 int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
658 int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
659 int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
Jesse Barnesf5448472009-04-14 14:17:47 -0700660 int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF);
Jesse Barnes79e53942008-11-07 14:24:08 -0800661 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
Kristian Høgsberg3c4fdcf2008-12-17 22:14:46 -0500662 u32 dspcntr, alignment;
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000663 int ret;
Jesse Barnes79e53942008-11-07 14:24:08 -0800664
665 /* no fb bound */
666 if (!crtc->fb) {
667 DRM_DEBUG("No FB bound\n");
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000668 return 0;
669 }
670
671 switch (pipe) {
672 case 0:
673 case 1:
674 break;
675 default:
676 DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
677 return -EINVAL;
Jesse Barnes79e53942008-11-07 14:24:08 -0800678 }
679
680 intel_fb = to_intel_framebuffer(crtc->fb);
Jesse Barnes79e53942008-11-07 14:24:08 -0800681 obj = intel_fb->obj;
682 obj_priv = obj->driver_private;
683
Kristian Høgsberg3c4fdcf2008-12-17 22:14:46 -0500684 switch (obj_priv->tiling_mode) {
685 case I915_TILING_NONE:
686 alignment = 64 * 1024;
687 break;
688 case I915_TILING_X:
Chris Wilson2ebed172009-02-11 14:26:30 +0000689 /* pin() will align the object as required by fence */
690 alignment = 0;
Kristian Høgsberg3c4fdcf2008-12-17 22:14:46 -0500691 break;
692 case I915_TILING_Y:
693 /* FIXME: Is this true? */
694 DRM_ERROR("Y tiled not allowed for scan out buffers\n");
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000695 return -EINVAL;
Kristian Høgsberg3c4fdcf2008-12-17 22:14:46 -0500696 default:
697 BUG();
698 }
699
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000700 mutex_lock(&dev->struct_mutex);
701 ret = i915_gem_object_pin(intel_fb->obj, alignment);
702 if (ret != 0) {
703 mutex_unlock(&dev->struct_mutex);
704 return ret;
705 }
Kristian Høgsberg3c4fdcf2008-12-17 22:14:46 -0500706
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000707 ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
708 if (ret != 0) {
709 i915_gem_object_unpin(intel_fb->obj);
710 mutex_unlock(&dev->struct_mutex);
711 return ret;
712 }
Jesse Barnes79e53942008-11-07 14:24:08 -0800713
714 dspcntr = I915_READ(dspcntr_reg);
Jesse Barnes712531b2009-01-09 13:56:14 -0800715 /* Mask out pixel format bits in case we change it */
716 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
Jesse Barnes79e53942008-11-07 14:24:08 -0800717 switch (crtc->fb->bits_per_pixel) {
718 case 8:
719 dspcntr |= DISPPLANE_8BPP;
720 break;
721 case 16:
722 if (crtc->fb->depth == 15)
723 dspcntr |= DISPPLANE_15_16BPP;
724 else
725 dspcntr |= DISPPLANE_16BPP;
726 break;
727 case 24:
728 case 32:
729 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
730 break;
731 default:
732 DRM_ERROR("Unknown color depth\n");
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000733 i915_gem_object_unpin(intel_fb->obj);
734 mutex_unlock(&dev->struct_mutex);
735 return -EINVAL;
Jesse Barnes79e53942008-11-07 14:24:08 -0800736 }
Jesse Barnesf5448472009-04-14 14:17:47 -0700737 if (IS_I965G(dev)) {
738 if (obj_priv->tiling_mode != I915_TILING_NONE)
739 dspcntr |= DISPPLANE_TILED;
740 else
741 dspcntr &= ~DISPPLANE_TILED;
742 }
743
Jesse Barnes79e53942008-11-07 14:24:08 -0800744 I915_WRITE(dspcntr_reg, dspcntr);
745
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000746 Start = obj_priv->gtt_offset;
747 Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
748
Jesse Barnes79e53942008-11-07 14:24:08 -0800749 DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000750 I915_WRITE(dspstride, crtc->fb->pitch);
Jesse Barnes79e53942008-11-07 14:24:08 -0800751 if (IS_I965G(dev)) {
752 I915_WRITE(dspbase, Offset);
753 I915_READ(dspbase);
754 I915_WRITE(dspsurf, Start);
755 I915_READ(dspsurf);
Jesse Barnesf5448472009-04-14 14:17:47 -0700756 I915_WRITE(dsptileoff, (y << 16) | x);
Jesse Barnes79e53942008-11-07 14:24:08 -0800757 } else {
758 I915_WRITE(dspbase, Start + Offset);
759 I915_READ(dspbase);
760 }
761
Kristian Høgsberg3c4fdcf2008-12-17 22:14:46 -0500762 intel_wait_for_vblank(dev);
763
764 if (old_fb) {
765 intel_fb = to_intel_framebuffer(old_fb);
766 i915_gem_object_unpin(intel_fb->obj);
767 }
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000768 mutex_unlock(&dev->struct_mutex);
Jesse Barnes79e53942008-11-07 14:24:08 -0800769
770 if (!dev->primary->master)
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000771 return 0;
Jesse Barnes79e53942008-11-07 14:24:08 -0800772
773 master_priv = dev->primary->master->driver_priv;
774 if (!master_priv->sarea_priv)
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000775 return 0;
Jesse Barnes79e53942008-11-07 14:24:08 -0800776
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000777 if (pipe) {
Jesse Barnes79e53942008-11-07 14:24:08 -0800778 master_priv->sarea_priv->pipeB_x = x;
779 master_priv->sarea_priv->pipeB_y = y;
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000780 } else {
781 master_priv->sarea_priv->pipeA_x = x;
782 master_priv->sarea_priv->pipeA_y = y;
Jesse Barnes79e53942008-11-07 14:24:08 -0800783 }
Chris Wilson5c3b82e2009-02-11 13:25:09 +0000784
785 return 0;
Jesse Barnes79e53942008-11-07 14:24:08 -0800786}
787
788
789
790/**
791 * Sets the power management mode of the pipe and plane.
792 *
793 * This code should probably grow support for turning the cursor off and back
794 * on appropriately at the same time as we're turning the pipe off/on.
795 */
796static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
797{
798 struct drm_device *dev = crtc->dev;
799 struct drm_i915_master_private *master_priv;
800 struct drm_i915_private *dev_priv = dev->dev_private;
801 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
802 int pipe = intel_crtc->pipe;
803 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
804 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
805 int dspbase_reg = (pipe == 0) ? DSPAADDR : DSPBADDR;
806 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
807 u32 temp;
808 bool enabled;
809
810 /* XXX: When our outputs are all unaware of DPMS modes other than off
811 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
812 */
813 switch (mode) {
814 case DRM_MODE_DPMS_ON:
815 case DRM_MODE_DPMS_STANDBY:
816 case DRM_MODE_DPMS_SUSPEND:
817 /* Enable the DPLL */
818 temp = I915_READ(dpll_reg);
819 if ((temp & DPLL_VCO_ENABLE) == 0) {
820 I915_WRITE(dpll_reg, temp);
821 I915_READ(dpll_reg);
822 /* Wait for the clocks to stabilize. */
823 udelay(150);
824 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
825 I915_READ(dpll_reg);
826 /* Wait for the clocks to stabilize. */
827 udelay(150);
828 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
829 I915_READ(dpll_reg);
830 /* Wait for the clocks to stabilize. */
831 udelay(150);
832 }
833
834 /* Enable the pipe */
835 temp = I915_READ(pipeconf_reg);
836 if ((temp & PIPEACONF_ENABLE) == 0)
837 I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
838
839 /* Enable the plane */
840 temp = I915_READ(dspcntr_reg);
841 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
842 I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
843 /* Flush the plane changes */
844 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
845 }
846
847 intel_crtc_load_lut(crtc);
848
849 /* Give the overlay scaler a chance to enable if it's on this pipe */
850 //intel_crtc_dpms_video(crtc, true); TODO
851 break;
852 case DRM_MODE_DPMS_OFF:
853 /* Give the overlay scaler a chance to disable if it's on this pipe */
854 //intel_crtc_dpms_video(crtc, FALSE); TODO
855
856 /* Disable the VGA plane that we never use */
857 I915_WRITE(VGACNTRL, VGA_DISP_DISABLE);
858
859 /* Disable display plane */
860 temp = I915_READ(dspcntr_reg);
861 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
862 I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
863 /* Flush the plane changes */
864 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
865 I915_READ(dspbase_reg);
866 }
867
868 if (!IS_I9XX(dev)) {
869 /* Wait for vblank for the disable to take effect */
870 intel_wait_for_vblank(dev);
871 }
872
873 /* Next, disable display pipes */
874 temp = I915_READ(pipeconf_reg);
875 if ((temp & PIPEACONF_ENABLE) != 0) {
876 I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
877 I915_READ(pipeconf_reg);
878 }
879
880 /* Wait for vblank for the disable to take effect. */
881 intel_wait_for_vblank(dev);
882
883 temp = I915_READ(dpll_reg);
884 if ((temp & DPLL_VCO_ENABLE) != 0) {
885 I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
886 I915_READ(dpll_reg);
887 }
888
889 /* Wait for the clocks to turn off. */
890 udelay(150);
891 break;
892 }
893
894 if (!dev->primary->master)
895 return;
896
897 master_priv = dev->primary->master->driver_priv;
898 if (!master_priv->sarea_priv)
899 return;
900
901 enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
902
903 switch (pipe) {
904 case 0:
905 master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0;
906 master_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0;
907 break;
908 case 1:
909 master_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0;
910 master_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0;
911 break;
912 default:
913 DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
914 break;
915 }
916
917 intel_crtc->dpms_mode = mode;
918}
919
920static void intel_crtc_prepare (struct drm_crtc *crtc)
921{
922 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
923 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
924}
925
926static void intel_crtc_commit (struct drm_crtc *crtc)
927{
928 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
929 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
930}
931
932void intel_encoder_prepare (struct drm_encoder *encoder)
933{
934 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
935 /* lvds has its own version of prepare see intel_lvds_prepare */
936 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
937}
938
939void intel_encoder_commit (struct drm_encoder *encoder)
940{
941 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
942 /* lvds has its own version of commit see intel_lvds_commit */
943 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
944}
945
946static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
947 struct drm_display_mode *mode,
948 struct drm_display_mode *adjusted_mode)
949{
950 return true;
951}
952
953
954/** Returns the core display clock speed for i830 - i945 */
955static int intel_get_core_clock_speed(struct drm_device *dev)
956{
957
958 /* Core clock values taken from the published datasheets.
959 * The 830 may go up to 166 Mhz, which we should check.
960 */
961 if (IS_I945G(dev))
962 return 400000;
963 else if (IS_I915G(dev))
964 return 333000;
Shaohua Li21778322009-02-23 15:19:16 +0800965 else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
Jesse Barnes79e53942008-11-07 14:24:08 -0800966 return 200000;
967 else if (IS_I915GM(dev)) {
968 u16 gcfgc = 0;
969
970 pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
971
972 if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
973 return 133000;
974 else {
975 switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
976 case GC_DISPLAY_CLOCK_333_MHZ:
977 return 333000;
978 default:
979 case GC_DISPLAY_CLOCK_190_200_MHZ:
980 return 190000;
981 }
982 }
983 } else if (IS_I865G(dev))
984 return 266000;
985 else if (IS_I855(dev)) {
986 u16 hpllcc = 0;
987 /* Assume that the hardware is in the high speed state. This
988 * should be the default.
989 */
990 switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
991 case GC_CLOCK_133_200:
992 case GC_CLOCK_100_200:
993 return 200000;
994 case GC_CLOCK_166_250:
995 return 250000;
996 case GC_CLOCK_100_133:
997 return 133000;
998 }
999 } else /* 852, 830 */
1000 return 133000;
1001
1002 return 0; /* Silence gcc warning */
1003}
1004
1005
1006/**
1007 * Return the pipe currently connected to the panel fitter,
1008 * or -1 if the panel fitter is not present or not in use
1009 */
1010static int intel_panel_fitter_pipe (struct drm_device *dev)
1011{
1012 struct drm_i915_private *dev_priv = dev->dev_private;
1013 u32 pfit_control;
1014
1015 /* i830 doesn't have a panel fitter */
1016 if (IS_I830(dev))
1017 return -1;
1018
1019 pfit_control = I915_READ(PFIT_CONTROL);
1020
1021 /* See if the panel fitter is in use */
1022 if ((pfit_control & PFIT_ENABLE) == 0)
1023 return -1;
1024
1025 /* 965 can place panel fitter on either pipe */
1026 if (IS_I965G(dev))
1027 return (pfit_control >> 29) & 0x3;
1028
1029 /* older chips can only use pipe 1 */
1030 return 1;
1031}
1032
Chris Wilson5c3b82e2009-02-11 13:25:09 +00001033static int intel_crtc_mode_set(struct drm_crtc *crtc,
1034 struct drm_display_mode *mode,
1035 struct drm_display_mode *adjusted_mode,
1036 int x, int y,
1037 struct drm_framebuffer *old_fb)
Jesse Barnes79e53942008-11-07 14:24:08 -08001038{
1039 struct drm_device *dev = crtc->dev;
1040 struct drm_i915_private *dev_priv = dev->dev_private;
1041 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1042 int pipe = intel_crtc->pipe;
1043 int fp_reg = (pipe == 0) ? FPA0 : FPB0;
1044 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
1045 int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
1046 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
1047 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
1048 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
1049 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
1050 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
1051 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
1052 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
1053 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
1054 int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
1055 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
1056 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
Kristian Høgsberg43565a02009-02-13 20:56:52 -05001057 int refclk, num_outputs = 0;
Jesse Barnes79e53942008-11-07 14:24:08 -08001058 intel_clock_t clock;
1059 u32 dpll = 0, fp = 0, dspcntr, pipeconf;
1060 bool ok, is_sdvo = false, is_dvo = false;
1061 bool is_crt = false, is_lvds = false, is_tv = false;
1062 struct drm_mode_config *mode_config = &dev->mode_config;
1063 struct drm_connector *connector;
Ma Lingd4906092009-03-18 20:13:27 +08001064 const intel_limit_t *limit;
Chris Wilson5c3b82e2009-02-11 13:25:09 +00001065 int ret;
Jesse Barnes79e53942008-11-07 14:24:08 -08001066
1067 drm_vblank_pre_modeset(dev, pipe);
1068
1069 list_for_each_entry(connector, &mode_config->connector_list, head) {
1070 struct intel_output *intel_output = to_intel_output(connector);
1071
1072 if (!connector->encoder || connector->encoder->crtc != crtc)
1073 continue;
1074
1075 switch (intel_output->type) {
1076 case INTEL_OUTPUT_LVDS:
1077 is_lvds = true;
1078 break;
1079 case INTEL_OUTPUT_SDVO:
Eric Anholt7d573822009-01-02 13:33:00 -08001080 case INTEL_OUTPUT_HDMI:
Jesse Barnes79e53942008-11-07 14:24:08 -08001081 is_sdvo = true;
Jesse Barnese2f0ba92009-02-02 15:11:52 -08001082 if (intel_output->needs_tv_clock)
1083 is_tv = true;
Jesse Barnes79e53942008-11-07 14:24:08 -08001084 break;
1085 case INTEL_OUTPUT_DVO:
1086 is_dvo = true;
1087 break;
1088 case INTEL_OUTPUT_TVOUT:
1089 is_tv = true;
1090 break;
1091 case INTEL_OUTPUT_ANALOG:
1092 is_crt = true;
1093 break;
1094 }
Kristian Høgsberg43565a02009-02-13 20:56:52 -05001095
1096 num_outputs++;
Jesse Barnes79e53942008-11-07 14:24:08 -08001097 }
1098
Kristian Høgsberg43565a02009-02-13 20:56:52 -05001099 if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
1100 refclk = dev_priv->lvds_ssc_freq * 1000;
1101 DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000);
1102 } else if (IS_I9XX(dev)) {
Jesse Barnes79e53942008-11-07 14:24:08 -08001103 refclk = 96000;
1104 } else {
1105 refclk = 48000;
1106 }
1107
Ma Lingd4906092009-03-18 20:13:27 +08001108 /*
1109 * Returns a set of divisors for the desired target clock with the given
1110 * refclk, or FALSE. The returned values represent the clock equation:
1111 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
1112 */
1113 limit = intel_limit(crtc);
1114 ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock);
Jesse Barnes79e53942008-11-07 14:24:08 -08001115 if (!ok) {
1116 DRM_ERROR("Couldn't find PLL settings for mode!\n");
Chris Wilson5c3b82e2009-02-11 13:25:09 +00001117 return -EINVAL;
Jesse Barnes79e53942008-11-07 14:24:08 -08001118 }
1119
Zhenyu Wang7026d4a2009-03-24 14:02:43 +08001120 /* SDVO TV has fixed PLL values depend on its clock range,
1121 this mirrors vbios setting. */
1122 if (is_sdvo && is_tv) {
1123 if (adjusted_mode->clock >= 100000
1124 && adjusted_mode->clock < 140500) {
1125 clock.p1 = 2;
1126 clock.p2 = 10;
1127 clock.n = 3;
1128 clock.m1 = 16;
1129 clock.m2 = 8;
1130 } else if (adjusted_mode->clock >= 140500
1131 && adjusted_mode->clock <= 200000) {
1132 clock.p1 = 1;
1133 clock.p2 = 10;
1134 clock.n = 6;
1135 clock.m1 = 12;
1136 clock.m2 = 8;
1137 }
1138 }
1139
Shaohua Li21778322009-02-23 15:19:16 +08001140 if (IS_IGD(dev))
1141 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
1142 else
1143 fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
Jesse Barnes79e53942008-11-07 14:24:08 -08001144
1145 dpll = DPLL_VGA_MODE_DIS;
1146 if (IS_I9XX(dev)) {
1147 if (is_lvds)
1148 dpll |= DPLLB_MODE_LVDS;
1149 else
1150 dpll |= DPLLB_MODE_DAC_SERIAL;
1151 if (is_sdvo) {
1152 dpll |= DPLL_DVO_HIGH_SPEED;
1153 if (IS_I945G(dev) || IS_I945GM(dev)) {
1154 int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
1155 dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
1156 }
1157 }
1158
1159 /* compute bitmask from p1 value */
Shaohua Li21778322009-02-23 15:19:16 +08001160 if (IS_IGD(dev))
1161 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD;
1162 else
1163 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
Jesse Barnes79e53942008-11-07 14:24:08 -08001164 switch (clock.p2) {
1165 case 5:
1166 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
1167 break;
1168 case 7:
1169 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
1170 break;
1171 case 10:
1172 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
1173 break;
1174 case 14:
1175 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
1176 break;
1177 }
1178 if (IS_I965G(dev))
1179 dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
1180 } else {
1181 if (is_lvds) {
1182 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
1183 } else {
1184 if (clock.p1 == 2)
1185 dpll |= PLL_P1_DIVIDE_BY_TWO;
1186 else
1187 dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
1188 if (clock.p2 == 4)
1189 dpll |= PLL_P2_DIVIDE_BY_4;
1190 }
1191 }
1192
Kristian Høgsberg43565a02009-02-13 20:56:52 -05001193 if (is_sdvo && is_tv)
1194 dpll |= PLL_REF_INPUT_TVCLKINBC;
1195 else if (is_tv)
Jesse Barnes79e53942008-11-07 14:24:08 -08001196 /* XXX: just matching BIOS for now */
Kristian Høgsberg43565a02009-02-13 20:56:52 -05001197 /* dpll |= PLL_REF_INPUT_TVCLKINBC; */
Jesse Barnes79e53942008-11-07 14:24:08 -08001198 dpll |= 3;
Kristian Høgsberg43565a02009-02-13 20:56:52 -05001199 else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
1200 dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
Jesse Barnes79e53942008-11-07 14:24:08 -08001201 else
1202 dpll |= PLL_REF_INPUT_DREFCLK;
1203
1204 /* setup pipeconf */
1205 pipeconf = I915_READ(pipeconf_reg);
1206
1207 /* Set up the display plane register */
1208 dspcntr = DISPPLANE_GAMMA_ENABLE;
1209
1210 if (pipe == 0)
1211 dspcntr |= DISPPLANE_SEL_PIPE_A;
1212 else
1213 dspcntr |= DISPPLANE_SEL_PIPE_B;
1214
1215 if (pipe == 0 && !IS_I965G(dev)) {
1216 /* Enable pixel doubling when the dot clock is > 90% of the (display)
1217 * core speed.
1218 *
1219 * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
1220 * pipe == 0 check?
1221 */
1222 if (mode->clock > intel_get_core_clock_speed(dev) * 9 / 10)
1223 pipeconf |= PIPEACONF_DOUBLE_WIDE;
1224 else
1225 pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
1226 }
1227
1228 dspcntr |= DISPLAY_PLANE_ENABLE;
1229 pipeconf |= PIPEACONF_ENABLE;
1230 dpll |= DPLL_VCO_ENABLE;
1231
1232
1233 /* Disable the panel fitter if it was on our pipe */
1234 if (intel_panel_fitter_pipe(dev) == pipe)
1235 I915_WRITE(PFIT_CONTROL, 0);
1236
1237 DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
1238 drm_mode_debug_printmodeline(mode);
1239
1240
1241 if (dpll & DPLL_VCO_ENABLE) {
1242 I915_WRITE(fp_reg, fp);
1243 I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
1244 I915_READ(dpll_reg);
1245 udelay(150);
1246 }
1247
1248 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
1249 * This is an exception to the general rule that mode_set doesn't turn
1250 * things on.
1251 */
1252 if (is_lvds) {
1253 u32 lvds = I915_READ(LVDS);
1254
1255 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
1256 /* Set the B0-B3 data pairs corresponding to whether we're going to
1257 * set the DPLLs for dual-channel mode or not.
1258 */
1259 if (clock.p2 == 7)
1260 lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
1261 else
1262 lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
1263
1264 /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
1265 * appropriately here, but we need to look more thoroughly into how
1266 * panels behave in the two modes.
1267 */
1268
1269 I915_WRITE(LVDS, lvds);
1270 I915_READ(LVDS);
1271 }
1272
1273 I915_WRITE(fp_reg, fp);
1274 I915_WRITE(dpll_reg, dpll);
1275 I915_READ(dpll_reg);
1276 /* Wait for the clocks to stabilize. */
1277 udelay(150);
1278
1279 if (IS_I965G(dev)) {
1280 int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
1281 I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
1282 ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
1283 } else {
1284 /* write it again -- the BIOS does, after all */
1285 I915_WRITE(dpll_reg, dpll);
1286 }
1287 I915_READ(dpll_reg);
1288 /* Wait for the clocks to stabilize. */
1289 udelay(150);
1290
1291 I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
1292 ((adjusted_mode->crtc_htotal - 1) << 16));
1293 I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
1294 ((adjusted_mode->crtc_hblank_end - 1) << 16));
1295 I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
1296 ((adjusted_mode->crtc_hsync_end - 1) << 16));
1297 I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
1298 ((adjusted_mode->crtc_vtotal - 1) << 16));
1299 I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
1300 ((adjusted_mode->crtc_vblank_end - 1) << 16));
1301 I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
1302 ((adjusted_mode->crtc_vsync_end - 1) << 16));
1303 /* pipesrc and dspsize control the size that is scaled from, which should
1304 * always be the user's requested size.
1305 */
1306 I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
1307 I915_WRITE(dsppos_reg, 0);
1308 I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
1309 I915_WRITE(pipeconf_reg, pipeconf);
1310 I915_READ(pipeconf_reg);
1311
1312 intel_wait_for_vblank(dev);
1313
1314 I915_WRITE(dspcntr_reg, dspcntr);
1315
1316 /* Flush the plane changes */
Chris Wilson5c3b82e2009-02-11 13:25:09 +00001317 ret = intel_pipe_set_base(crtc, x, y, old_fb);
1318 if (ret != 0)
1319 return ret;
Jesse Barnes79e53942008-11-07 14:24:08 -08001320
1321 drm_vblank_post_modeset(dev, pipe);
Chris Wilson5c3b82e2009-02-11 13:25:09 +00001322
1323 return 0;
Jesse Barnes79e53942008-11-07 14:24:08 -08001324}
1325
1326/** Loads the palette/gamma unit for the CRTC with the prepared values */
1327void intel_crtc_load_lut(struct drm_crtc *crtc)
1328{
1329 struct drm_device *dev = crtc->dev;
1330 struct drm_i915_private *dev_priv = dev->dev_private;
1331 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1332 int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B;
1333 int i;
1334
1335 /* The clocks have to be on to load the palette. */
1336 if (!crtc->enabled)
1337 return;
1338
1339 for (i = 0; i < 256; i++) {
1340 I915_WRITE(palreg + 4 * i,
1341 (intel_crtc->lut_r[i] << 16) |
1342 (intel_crtc->lut_g[i] << 8) |
1343 intel_crtc->lut_b[i]);
1344 }
1345}
1346
1347static int intel_crtc_cursor_set(struct drm_crtc *crtc,
1348 struct drm_file *file_priv,
1349 uint32_t handle,
1350 uint32_t width, uint32_t height)
1351{
1352 struct drm_device *dev = crtc->dev;
1353 struct drm_i915_private *dev_priv = dev->dev_private;
1354 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1355 struct drm_gem_object *bo;
1356 struct drm_i915_gem_object *obj_priv;
1357 int pipe = intel_crtc->pipe;
1358 uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
1359 uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
Jesse Barnes14b60392009-05-20 16:47:08 -04001360 uint32_t temp = I915_READ(control);
Jesse Barnes79e53942008-11-07 14:24:08 -08001361 size_t addr;
Kristian Høgsberg3f8bc372008-12-17 22:14:59 -05001362 int ret;
Jesse Barnes79e53942008-11-07 14:24:08 -08001363
1364 DRM_DEBUG("\n");
1365
1366 /* if we want to turn off the cursor ignore width and height */
1367 if (!handle) {
1368 DRM_DEBUG("cursor off\n");
Jesse Barnes14b60392009-05-20 16:47:08 -04001369 if (IS_MOBILE(dev) || IS_I9XX(dev)) {
1370 temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
1371 temp |= CURSOR_MODE_DISABLE;
1372 } else {
1373 temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
1374 }
Kristian Høgsberg3f8bc372008-12-17 22:14:59 -05001375 addr = 0;
1376 bo = NULL;
Pierre Willenbrock50044172009-02-23 10:12:15 +10001377 mutex_lock(&dev->struct_mutex);
Kristian Høgsberg3f8bc372008-12-17 22:14:59 -05001378 goto finish;
Jesse Barnes79e53942008-11-07 14:24:08 -08001379 }
1380
1381 /* Currently we only support 64x64 cursors */
1382 if (width != 64 || height != 64) {
1383 DRM_ERROR("we currently only support 64x64 cursors\n");
1384 return -EINVAL;
1385 }
1386
1387 bo = drm_gem_object_lookup(dev, file_priv, handle);
1388 if (!bo)
1389 return -ENOENT;
1390
1391 obj_priv = bo->driver_private;
1392
1393 if (bo->size < width * height * 4) {
1394 DRM_ERROR("buffer is to small\n");
Dave Airlie34b8686e2009-01-15 14:03:07 +10001395 ret = -ENOMEM;
1396 goto fail;
Jesse Barnes79e53942008-11-07 14:24:08 -08001397 }
1398
Dave Airlie71acb5e2008-12-30 20:31:46 +10001399 /* we only need to pin inside GTT if cursor is non-phy */
Kristian Høgsberg7f9872e2009-02-13 20:56:49 -05001400 mutex_lock(&dev->struct_mutex);
Dave Airlie71acb5e2008-12-30 20:31:46 +10001401 if (!dev_priv->cursor_needs_physical) {
1402 ret = i915_gem_object_pin(bo, PAGE_SIZE);
1403 if (ret) {
1404 DRM_ERROR("failed to pin cursor bo\n");
Kristian Høgsberg7f9872e2009-02-13 20:56:49 -05001405 goto fail_locked;
Dave Airlie71acb5e2008-12-30 20:31:46 +10001406 }
Jesse Barnes79e53942008-11-07 14:24:08 -08001407 addr = obj_priv->gtt_offset;
Dave Airlie71acb5e2008-12-30 20:31:46 +10001408 } else {
1409 ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
1410 if (ret) {
1411 DRM_ERROR("failed to attach phys object\n");
Kristian Høgsberg7f9872e2009-02-13 20:56:49 -05001412 goto fail_locked;
Dave Airlie71acb5e2008-12-30 20:31:46 +10001413 }
1414 addr = obj_priv->phys_obj->handle->busaddr;
Kristian Høgsberg3f8bc372008-12-17 22:14:59 -05001415 }
1416
Jesse Barnes14b60392009-05-20 16:47:08 -04001417 if (!IS_I9XX(dev))
1418 I915_WRITE(CURSIZE, (height << 12) | width);
1419
1420 /* Hooray for CUR*CNTR differences */
1421 if (IS_MOBILE(dev) || IS_I9XX(dev)) {
1422 temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
1423 temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
1424 temp |= (pipe << 28); /* Connect to correct pipe */
1425 } else {
1426 temp &= ~(CURSOR_FORMAT_MASK);
1427 temp |= CURSOR_ENABLE;
1428 temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
1429 }
Jesse Barnes79e53942008-11-07 14:24:08 -08001430
Kristian Høgsberg3f8bc372008-12-17 22:14:59 -05001431 finish:
Jesse Barnes79e53942008-11-07 14:24:08 -08001432 I915_WRITE(control, temp);
1433 I915_WRITE(base, addr);
1434
Kristian Høgsberg3f8bc372008-12-17 22:14:59 -05001435 if (intel_crtc->cursor_bo) {
Dave Airlie71acb5e2008-12-30 20:31:46 +10001436 if (dev_priv->cursor_needs_physical) {
1437 if (intel_crtc->cursor_bo != bo)
1438 i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
1439 } else
1440 i915_gem_object_unpin(intel_crtc->cursor_bo);
Kristian Høgsberg3f8bc372008-12-17 22:14:59 -05001441 drm_gem_object_unreference(intel_crtc->cursor_bo);
1442 }
Kristian Høgsberg7f9872e2009-02-13 20:56:49 -05001443 mutex_unlock(&dev->struct_mutex);
Kristian Høgsberg3f8bc372008-12-17 22:14:59 -05001444
1445 intel_crtc->cursor_addr = addr;
1446 intel_crtc->cursor_bo = bo;
1447
Jesse Barnes79e53942008-11-07 14:24:08 -08001448 return 0;
Dave Airlie34b8686e2009-01-15 14:03:07 +10001449fail:
1450 mutex_lock(&dev->struct_mutex);
Kristian Høgsberg7f9872e2009-02-13 20:56:49 -05001451fail_locked:
Dave Airlie34b8686e2009-01-15 14:03:07 +10001452 drm_gem_object_unreference(bo);
1453 mutex_unlock(&dev->struct_mutex);
1454 return ret;
Jesse Barnes79e53942008-11-07 14:24:08 -08001455}
1456
1457static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
1458{
1459 struct drm_device *dev = crtc->dev;
1460 struct drm_i915_private *dev_priv = dev->dev_private;
1461 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1462 int pipe = intel_crtc->pipe;
1463 uint32_t temp = 0;
1464 uint32_t adder;
1465
1466 if (x < 0) {
1467 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
1468 x = -x;
1469 }
1470 if (y < 0) {
1471 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
1472 y = -y;
1473 }
1474
1475 temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
1476 temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1477
1478 adder = intel_crtc->cursor_addr;
1479 I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
1480 I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
1481
1482 return 0;
1483}
1484
1485/** Sets the color ramps on behalf of RandR */
1486void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
1487 u16 blue, int regno)
1488{
1489 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1490
1491 intel_crtc->lut_r[regno] = red >> 8;
1492 intel_crtc->lut_g[regno] = green >> 8;
1493 intel_crtc->lut_b[regno] = blue >> 8;
1494}
1495
1496static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1497 u16 *blue, uint32_t size)
1498{
1499 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1500 int i;
1501
1502 if (size != 256)
1503 return;
1504
1505 for (i = 0; i < 256; i++) {
1506 intel_crtc->lut_r[i] = red[i] >> 8;
1507 intel_crtc->lut_g[i] = green[i] >> 8;
1508 intel_crtc->lut_b[i] = blue[i] >> 8;
1509 }
1510
1511 intel_crtc_load_lut(crtc);
1512}
1513
1514/**
1515 * Get a pipe with a simple mode set on it for doing load-based monitor
1516 * detection.
1517 *
1518 * It will be up to the load-detect code to adjust the pipe as appropriate for
1519 * its requirements. The pipe will be connected to no other outputs.
1520 *
1521 * Currently this code will only succeed if there is a pipe with no outputs
1522 * configured for it. In the future, it could choose to temporarily disable
1523 * some outputs to free up a pipe for its use.
1524 *
1525 * \return crtc, or NULL if no pipes are available.
1526 */
1527
1528/* VESA 640x480x72Hz mode to set on the pipe */
1529static struct drm_display_mode load_detect_mode = {
1530 DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
1531 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
1532};
1533
1534struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
1535 struct drm_display_mode *mode,
1536 int *dpms_mode)
1537{
1538 struct intel_crtc *intel_crtc;
1539 struct drm_crtc *possible_crtc;
1540 struct drm_crtc *supported_crtc =NULL;
1541 struct drm_encoder *encoder = &intel_output->enc;
1542 struct drm_crtc *crtc = NULL;
1543 struct drm_device *dev = encoder->dev;
1544 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
1545 struct drm_crtc_helper_funcs *crtc_funcs;
1546 int i = -1;
1547
1548 /*
1549 * Algorithm gets a little messy:
1550 * - if the connector already has an assigned crtc, use it (but make
1551 * sure it's on first)
1552 * - try to find the first unused crtc that can drive this connector,
1553 * and use that if we find one
1554 * - if there are no unused crtcs available, try to use the first
1555 * one we found that supports the connector
1556 */
1557
1558 /* See if we already have a CRTC for this connector */
1559 if (encoder->crtc) {
1560 crtc = encoder->crtc;
1561 /* Make sure the crtc and connector are running */
1562 intel_crtc = to_intel_crtc(crtc);
1563 *dpms_mode = intel_crtc->dpms_mode;
1564 if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
1565 crtc_funcs = crtc->helper_private;
1566 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1567 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
1568 }
1569 return crtc;
1570 }
1571
1572 /* Find an unused one (if possible) */
1573 list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) {
1574 i++;
1575 if (!(encoder->possible_crtcs & (1 << i)))
1576 continue;
1577 if (!possible_crtc->enabled) {
1578 crtc = possible_crtc;
1579 break;
1580 }
1581 if (!supported_crtc)
1582 supported_crtc = possible_crtc;
1583 }
1584
1585 /*
1586 * If we didn't find an unused CRTC, don't use any.
1587 */
1588 if (!crtc) {
1589 return NULL;
1590 }
1591
1592 encoder->crtc = crtc;
1593 intel_output->load_detect_temp = true;
1594
1595 intel_crtc = to_intel_crtc(crtc);
1596 *dpms_mode = intel_crtc->dpms_mode;
1597
1598 if (!crtc->enabled) {
1599 if (!mode)
1600 mode = &load_detect_mode;
Kristian Høgsberg3c4fdcf2008-12-17 22:14:46 -05001601 drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb);
Jesse Barnes79e53942008-11-07 14:24:08 -08001602 } else {
1603 if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
1604 crtc_funcs = crtc->helper_private;
1605 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1606 }
1607
1608 /* Add this connector to the crtc */
1609 encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode);
1610 encoder_funcs->commit(encoder);
1611 }
1612 /* let the connector get through one full cycle before testing */
1613 intel_wait_for_vblank(dev);
1614
1615 return crtc;
1616}
1617
1618void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
1619{
1620 struct drm_encoder *encoder = &intel_output->enc;
1621 struct drm_device *dev = encoder->dev;
1622 struct drm_crtc *crtc = encoder->crtc;
1623 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
1624 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1625
1626 if (intel_output->load_detect_temp) {
1627 encoder->crtc = NULL;
1628 intel_output->load_detect_temp = false;
1629 crtc->enabled = drm_helper_crtc_in_use(crtc);
1630 drm_helper_disable_unused_functions(dev);
1631 }
1632
1633 /* Switch crtc and output back off if necessary */
1634 if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
1635 if (encoder->crtc == crtc)
1636 encoder_funcs->dpms(encoder, dpms_mode);
1637 crtc_funcs->dpms(crtc, dpms_mode);
1638 }
1639}
1640
1641/* Returns the clock of the currently programmed mode of the given pipe. */
1642static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
1643{
1644 struct drm_i915_private *dev_priv = dev->dev_private;
1645 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1646 int pipe = intel_crtc->pipe;
1647 u32 dpll = I915_READ((pipe == 0) ? DPLL_A : DPLL_B);
1648 u32 fp;
1649 intel_clock_t clock;
1650
1651 if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
1652 fp = I915_READ((pipe == 0) ? FPA0 : FPB0);
1653 else
1654 fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
1655
1656 clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
Shaohua Li21778322009-02-23 15:19:16 +08001657 if (IS_IGD(dev)) {
1658 clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
1659 clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT;
1660 } else {
1661 clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
1662 clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
1663 }
1664
Jesse Barnes79e53942008-11-07 14:24:08 -08001665 if (IS_I9XX(dev)) {
Shaohua Li21778322009-02-23 15:19:16 +08001666 if (IS_IGD(dev))
1667 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >>
1668 DPLL_FPA01_P1_POST_DIV_SHIFT_IGD);
1669 else
1670 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
Jesse Barnes79e53942008-11-07 14:24:08 -08001671 DPLL_FPA01_P1_POST_DIV_SHIFT);
1672
1673 switch (dpll & DPLL_MODE_MASK) {
1674 case DPLLB_MODE_DAC_SERIAL:
1675 clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ?
1676 5 : 10;
1677 break;
1678 case DPLLB_MODE_LVDS:
1679 clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ?
1680 7 : 14;
1681 break;
1682 default:
1683 DRM_DEBUG("Unknown DPLL mode %08x in programmed "
1684 "mode\n", (int)(dpll & DPLL_MODE_MASK));
1685 return 0;
1686 }
1687
1688 /* XXX: Handle the 100Mhz refclk */
Shaohua Li21778322009-02-23 15:19:16 +08001689 intel_clock(dev, 96000, &clock);
Jesse Barnes79e53942008-11-07 14:24:08 -08001690 } else {
1691 bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
1692
1693 if (is_lvds) {
1694 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
1695 DPLL_FPA01_P1_POST_DIV_SHIFT);
1696 clock.p2 = 14;
1697
1698 if ((dpll & PLL_REF_INPUT_MASK) ==
1699 PLLB_REF_INPUT_SPREADSPECTRUMIN) {
1700 /* XXX: might not be 66MHz */
Shaohua Li21778322009-02-23 15:19:16 +08001701 intel_clock(dev, 66000, &clock);
Jesse Barnes79e53942008-11-07 14:24:08 -08001702 } else
Shaohua Li21778322009-02-23 15:19:16 +08001703 intel_clock(dev, 48000, &clock);
Jesse Barnes79e53942008-11-07 14:24:08 -08001704 } else {
1705 if (dpll & PLL_P1_DIVIDE_BY_TWO)
1706 clock.p1 = 2;
1707 else {
1708 clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
1709 DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
1710 }
1711 if (dpll & PLL_P2_DIVIDE_BY_4)
1712 clock.p2 = 4;
1713 else
1714 clock.p2 = 2;
1715
Shaohua Li21778322009-02-23 15:19:16 +08001716 intel_clock(dev, 48000, &clock);
Jesse Barnes79e53942008-11-07 14:24:08 -08001717 }
1718 }
1719
1720 /* XXX: It would be nice to validate the clocks, but we can't reuse
1721 * i830PllIsValid() because it relies on the xf86_config connector
1722 * configuration being accurate, which it isn't necessarily.
1723 */
1724
1725 return clock.dot;
1726}
1727
1728/** Returns the currently programmed mode of the given pipe. */
1729struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
1730 struct drm_crtc *crtc)
1731{
1732 struct drm_i915_private *dev_priv = dev->dev_private;
1733 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1734 int pipe = intel_crtc->pipe;
1735 struct drm_display_mode *mode;
1736 int htot = I915_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
1737 int hsync = I915_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
1738 int vtot = I915_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
1739 int vsync = I915_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
1740
1741 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
1742 if (!mode)
1743 return NULL;
1744
1745 mode->clock = intel_crtc_clock_get(dev, crtc);
1746 mode->hdisplay = (htot & 0xffff) + 1;
1747 mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
1748 mode->hsync_start = (hsync & 0xffff) + 1;
1749 mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
1750 mode->vdisplay = (vtot & 0xffff) + 1;
1751 mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
1752 mode->vsync_start = (vsync & 0xffff) + 1;
1753 mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
1754
1755 drm_mode_set_name(mode);
1756 drm_mode_set_crtcinfo(mode, 0);
1757
1758 return mode;
1759}
1760
1761static void intel_crtc_destroy(struct drm_crtc *crtc)
1762{
1763 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1764
1765 drm_crtc_cleanup(crtc);
1766 kfree(intel_crtc);
1767}
1768
1769static const struct drm_crtc_helper_funcs intel_helper_funcs = {
1770 .dpms = intel_crtc_dpms,
1771 .mode_fixup = intel_crtc_mode_fixup,
1772 .mode_set = intel_crtc_mode_set,
1773 .mode_set_base = intel_pipe_set_base,
1774 .prepare = intel_crtc_prepare,
1775 .commit = intel_crtc_commit,
1776};
1777
1778static const struct drm_crtc_funcs intel_crtc_funcs = {
1779 .cursor_set = intel_crtc_cursor_set,
1780 .cursor_move = intel_crtc_cursor_move,
1781 .gamma_set = intel_crtc_gamma_set,
1782 .set_config = drm_crtc_helper_set_config,
1783 .destroy = intel_crtc_destroy,
1784};
1785
1786
Hannes Ederb358d0a2008-12-18 21:18:47 +01001787static void intel_crtc_init(struct drm_device *dev, int pipe)
Jesse Barnes79e53942008-11-07 14:24:08 -08001788{
1789 struct intel_crtc *intel_crtc;
1790 int i;
1791
1792 intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
1793 if (intel_crtc == NULL)
1794 return;
1795
1796 drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs);
1797
1798 drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256);
1799 intel_crtc->pipe = pipe;
1800 for (i = 0; i < 256; i++) {
1801 intel_crtc->lut_r[i] = i;
1802 intel_crtc->lut_g[i] = i;
1803 intel_crtc->lut_b[i] = i;
1804 }
1805
1806 intel_crtc->cursor_addr = 0;
1807 intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
1808 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
1809
1810 intel_crtc->mode_set.crtc = &intel_crtc->base;
1811 intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1);
1812 intel_crtc->mode_set.num_connectors = 0;
1813
1814 if (i915_fbpercrtc) {
1815
1816
1817
1818 }
1819}
1820
Carl Worth08d7b3d2009-04-29 14:43:54 -07001821int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
1822 struct drm_file *file_priv)
1823{
1824 drm_i915_private_t *dev_priv = dev->dev_private;
1825 struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
1826 struct drm_crtc *crtc = NULL;
1827 int pipe = -1;
1828
1829 if (!dev_priv) {
1830 DRM_ERROR("called with no initialization\n");
1831 return -EINVAL;
1832 }
1833
1834 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1835 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1836 if (crtc->base.id == pipe_from_crtc_id->crtc_id) {
1837 pipe = intel_crtc->pipe;
1838 break;
1839 }
1840 }
1841
1842 if (pipe == -1) {
1843 DRM_ERROR("no such CRTC id\n");
1844 return -EINVAL;
1845 }
1846
1847 pipe_from_crtc_id->pipe = pipe;
1848
1849 return 0;
1850}
1851
Jesse Barnes79e53942008-11-07 14:24:08 -08001852struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
1853{
1854 struct drm_crtc *crtc = NULL;
1855
1856 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1857 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1858 if (intel_crtc->pipe == pipe)
1859 break;
1860 }
1861 return crtc;
1862}
1863
Hannes Ederb358d0a2008-12-18 21:18:47 +01001864static int intel_connector_clones(struct drm_device *dev, int type_mask)
Jesse Barnes79e53942008-11-07 14:24:08 -08001865{
1866 int index_mask = 0;
1867 struct drm_connector *connector;
1868 int entry = 0;
1869
1870 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1871 struct intel_output *intel_output = to_intel_output(connector);
1872 if (type_mask & (1 << intel_output->type))
1873 index_mask |= (1 << entry);
1874 entry++;
1875 }
1876 return index_mask;
1877}
1878
1879
1880static void intel_setup_outputs(struct drm_device *dev)
1881{
Eric Anholt725e30a2009-01-22 13:01:02 -08001882 struct drm_i915_private *dev_priv = dev->dev_private;
Jesse Barnes79e53942008-11-07 14:24:08 -08001883 struct drm_connector *connector;
1884
1885 intel_crt_init(dev);
1886
1887 /* Set up integrated LVDS */
1888 if (IS_MOBILE(dev) && !IS_I830(dev))
1889 intel_lvds_init(dev);
1890
1891 if (IS_I9XX(dev)) {
Eric Anholt7d573822009-01-02 13:33:00 -08001892 int found;
Kristian Høgsberg13520b02009-03-13 15:42:14 -04001893 u32 reg;
Eric Anholt7d573822009-01-02 13:33:00 -08001894
Eric Anholt725e30a2009-01-22 13:01:02 -08001895 if (I915_READ(SDVOB) & SDVO_DETECTED) {
1896 found = intel_sdvo_init(dev, SDVOB);
1897 if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
1898 intel_hdmi_init(dev, SDVOB);
1899 }
Kristian Høgsberg13520b02009-03-13 15:42:14 -04001900
1901 /* Before G4X SDVOC doesn't have its own detect register */
1902 if (IS_G4X(dev))
1903 reg = SDVOC;
1904 else
1905 reg = SDVOB;
1906
1907 if (I915_READ(reg) & SDVO_DETECTED) {
Eric Anholt725e30a2009-01-22 13:01:02 -08001908 found = intel_sdvo_init(dev, SDVOC);
1909 if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
1910 intel_hdmi_init(dev, SDVOC);
1911 }
Jesse Barnes79e53942008-11-07 14:24:08 -08001912 } else
1913 intel_dvo_init(dev);
1914
Eric Anholt1fc45d82009-01-02 15:57:35 -08001915 if (IS_I9XX(dev) && IS_MOBILE(dev))
Jesse Barnes79e53942008-11-07 14:24:08 -08001916 intel_tv_init(dev);
1917
1918 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1919 struct intel_output *intel_output = to_intel_output(connector);
1920 struct drm_encoder *encoder = &intel_output->enc;
1921 int crtc_mask = 0, clone_mask = 0;
1922
1923 /* valid crtcs */
1924 switch(intel_output->type) {
Eric Anholt7d573822009-01-02 13:33:00 -08001925 case INTEL_OUTPUT_HDMI:
1926 crtc_mask = ((1 << 0)|
1927 (1 << 1));
1928 clone_mask = ((1 << INTEL_OUTPUT_HDMI));
1929 break;
Jesse Barnes79e53942008-11-07 14:24:08 -08001930 case INTEL_OUTPUT_DVO:
1931 case INTEL_OUTPUT_SDVO:
1932 crtc_mask = ((1 << 0)|
1933 (1 << 1));
1934 clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
1935 (1 << INTEL_OUTPUT_DVO) |
1936 (1 << INTEL_OUTPUT_SDVO));
1937 break;
1938 case INTEL_OUTPUT_ANALOG:
1939 crtc_mask = ((1 << 0)|
1940 (1 << 1));
1941 clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
1942 (1 << INTEL_OUTPUT_DVO) |
1943 (1 << INTEL_OUTPUT_SDVO));
1944 break;
1945 case INTEL_OUTPUT_LVDS:
1946 crtc_mask = (1 << 1);
1947 clone_mask = (1 << INTEL_OUTPUT_LVDS);
1948 break;
1949 case INTEL_OUTPUT_TVOUT:
1950 crtc_mask = ((1 << 0) |
1951 (1 << 1));
1952 clone_mask = (1 << INTEL_OUTPUT_TVOUT);
1953 break;
1954 }
1955 encoder->possible_crtcs = crtc_mask;
1956 encoder->possible_clones = intel_connector_clones(dev, clone_mask);
1957 }
1958}
1959
1960static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
1961{
1962 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1963 struct drm_device *dev = fb->dev;
1964
1965 if (fb->fbdev)
1966 intelfb_remove(dev, fb);
1967
1968 drm_framebuffer_cleanup(fb);
1969 mutex_lock(&dev->struct_mutex);
1970 drm_gem_object_unreference(intel_fb->obj);
1971 mutex_unlock(&dev->struct_mutex);
1972
1973 kfree(intel_fb);
1974}
1975
1976static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
1977 struct drm_file *file_priv,
1978 unsigned int *handle)
1979{
1980 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1981 struct drm_gem_object *object = intel_fb->obj;
1982
1983 return drm_gem_handle_create(file_priv, object, handle);
1984}
1985
1986static const struct drm_framebuffer_funcs intel_fb_funcs = {
1987 .destroy = intel_user_framebuffer_destroy,
1988 .create_handle = intel_user_framebuffer_create_handle,
1989};
1990
1991int intel_framebuffer_create(struct drm_device *dev,
1992 struct drm_mode_fb_cmd *mode_cmd,
1993 struct drm_framebuffer **fb,
1994 struct drm_gem_object *obj)
1995{
1996 struct intel_framebuffer *intel_fb;
1997 int ret;
1998
1999 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
2000 if (!intel_fb)
2001 return -ENOMEM;
2002
2003 ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
2004 if (ret) {
2005 DRM_ERROR("framebuffer init failed %d\n", ret);
2006 return ret;
2007 }
2008
2009 drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
2010
2011 intel_fb->obj = obj;
2012
2013 *fb = &intel_fb->base;
2014
2015 return 0;
2016}
2017
2018
2019static struct drm_framebuffer *
2020intel_user_framebuffer_create(struct drm_device *dev,
2021 struct drm_file *filp,
2022 struct drm_mode_fb_cmd *mode_cmd)
2023{
2024 struct drm_gem_object *obj;
2025 struct drm_framebuffer *fb;
2026 int ret;
2027
2028 obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle);
2029 if (!obj)
2030 return NULL;
2031
2032 ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj);
2033 if (ret) {
Jesse Barnes496818f2009-02-11 13:28:14 -08002034 mutex_lock(&dev->struct_mutex);
Jesse Barnes79e53942008-11-07 14:24:08 -08002035 drm_gem_object_unreference(obj);
Jesse Barnes496818f2009-02-11 13:28:14 -08002036 mutex_unlock(&dev->struct_mutex);
Jesse Barnes79e53942008-11-07 14:24:08 -08002037 return NULL;
2038 }
2039
2040 return fb;
2041}
2042
Jesse Barnes79e53942008-11-07 14:24:08 -08002043static const struct drm_mode_config_funcs intel_mode_funcs = {
Jesse Barnes79e53942008-11-07 14:24:08 -08002044 .fb_create = intel_user_framebuffer_create,
2045 .fb_changed = intelfb_probe,
2046};
2047
2048void intel_modeset_init(struct drm_device *dev)
2049{
2050 int num_pipe;
2051 int i;
2052
2053 drm_mode_config_init(dev);
2054
2055 dev->mode_config.min_width = 0;
2056 dev->mode_config.min_height = 0;
2057
2058 dev->mode_config.funcs = (void *)&intel_mode_funcs;
2059
2060 if (IS_I965G(dev)) {
2061 dev->mode_config.max_width = 8192;
2062 dev->mode_config.max_height = 8192;
2063 } else {
2064 dev->mode_config.max_width = 2048;
2065 dev->mode_config.max_height = 2048;
2066 }
2067
2068 /* set memory base */
2069 if (IS_I9XX(dev))
2070 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 2);
2071 else
2072 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0);
2073
2074 if (IS_MOBILE(dev) || IS_I9XX(dev))
2075 num_pipe = 2;
2076 else
2077 num_pipe = 1;
2078 DRM_DEBUG("%d display pipe%s available.\n",
2079 num_pipe, num_pipe > 1 ? "s" : "");
2080
2081 for (i = 0; i < num_pipe; i++) {
2082 intel_crtc_init(dev, i);
2083 }
2084
2085 intel_setup_outputs(dev);
2086}
2087
2088void intel_modeset_cleanup(struct drm_device *dev)
2089{
2090 drm_mode_config_cleanup(dev);
2091}
2092
2093
2094/* current intel driver doesn't take advantage of encoders
2095 always give back the encoder for the connector
2096*/
2097struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
2098{
2099 struct intel_output *intel_output = to_intel_output(connector);
2100
2101 return &intel_output->enc;
2102}