diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
32 files changed, 2393 insertions, 1834 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 9929f84ec3e1..95639017bdbe 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -33,3 +33,5 @@ i915-$(CONFIG_ACPI) += i915_opregion.o | |||
33 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 33 | i915-$(CONFIG_COMPAT) += i915_ioc32.o |
34 | 34 | ||
35 | obj-$(CONFIG_DRM_I915) += i915.o | 35 | obj-$(CONFIG_DRM_I915) += i915.o |
36 | |||
37 | CFLAGS_i915_trace_points.o := -I$(src) | ||
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 288fc50627e2..0d6ff640e1c6 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
@@ -70,16 +70,6 @@ struct intel_dvo_dev_ops { | |||
70 | void (*dpms)(struct intel_dvo_device *dvo, int mode); | 70 | void (*dpms)(struct intel_dvo_device *dvo, int mode); |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Saves the output's state for restoration on VT switch. | ||
74 | */ | ||
75 | void (*save)(struct intel_dvo_device *dvo); | ||
76 | |||
77 | /* | ||
78 | * Restore's the output's state at VT switch. | ||
79 | */ | ||
80 | void (*restore)(struct intel_dvo_device *dvo); | ||
81 | |||
82 | /* | ||
83 | * Callback for testing a video mode for a given output. | 73 | * Callback for testing a video mode for a given output. |
84 | * | 74 | * |
85 | * This function should only check for cases where a mode can't | 75 | * This function should only check for cases where a mode can't |
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index 1184c14ba87d..14d59804acd7 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c | |||
@@ -159,16 +159,7 @@ | |||
159 | #define CH7017_BANG_LIMIT_CONTROL 0x7f | 159 | #define CH7017_BANG_LIMIT_CONTROL 0x7f |
160 | 160 | ||
161 | struct ch7017_priv { | 161 | struct ch7017_priv { |
162 | uint8_t save_hapi; | 162 | uint8_t dummy; |
163 | uint8_t save_vali; | ||
164 | uint8_t save_valo; | ||
165 | uint8_t save_ailo; | ||
166 | uint8_t save_lvds_pll_vco; | ||
167 | uint8_t save_feedback_div; | ||
168 | uint8_t save_lvds_control_2; | ||
169 | uint8_t save_outputs_enable; | ||
170 | uint8_t save_lvds_power_down; | ||
171 | uint8_t save_power_management; | ||
172 | }; | 163 | }; |
173 | 164 | ||
174 | static void ch7017_dump_regs(struct intel_dvo_device *dvo); | 165 | static void ch7017_dump_regs(struct intel_dvo_device *dvo); |
@@ -401,39 +392,6 @@ do { \ | |||
401 | DUMP(CH7017_LVDS_POWER_DOWN); | 392 | DUMP(CH7017_LVDS_POWER_DOWN); |
402 | } | 393 | } |
403 | 394 | ||
404 | static void ch7017_save(struct intel_dvo_device *dvo) | ||
405 | { | ||
406 | struct ch7017_priv *priv = dvo->dev_priv; | ||
407 | |||
408 | ch7017_read(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, &priv->save_hapi); | ||
409 | ch7017_read(dvo, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, &priv->save_valo); | ||
410 | ch7017_read(dvo, CH7017_ACTIVE_INPUT_LINE_OUTPUT, &priv->save_ailo); | ||
411 | ch7017_read(dvo, CH7017_LVDS_PLL_VCO_CONTROL, &priv->save_lvds_pll_vco); | ||
412 | ch7017_read(dvo, CH7017_LVDS_PLL_FEEDBACK_DIV, &priv->save_feedback_div); | ||
413 | ch7017_read(dvo, CH7017_LVDS_CONTROL_2, &priv->save_lvds_control_2); | ||
414 | ch7017_read(dvo, CH7017_OUTPUTS_ENABLE, &priv->save_outputs_enable); | ||
415 | ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &priv->save_lvds_power_down); | ||
416 | ch7017_read(dvo, CH7017_POWER_MANAGEMENT, &priv->save_power_management); | ||
417 | } | ||
418 | |||
419 | static void ch7017_restore(struct intel_dvo_device *dvo) | ||
420 | { | ||
421 | struct ch7017_priv *priv = dvo->dev_priv; | ||
422 | |||
423 | /* Power down before changing mode */ | ||
424 | ch7017_dpms(dvo, DRM_MODE_DPMS_OFF); | ||
425 | |||
426 | ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, priv->save_hapi); | ||
427 | ch7017_write(dvo, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, priv->save_valo); | ||
428 | ch7017_write(dvo, CH7017_ACTIVE_INPUT_LINE_OUTPUT, priv->save_ailo); | ||
429 | ch7017_write(dvo, CH7017_LVDS_PLL_VCO_CONTROL, priv->save_lvds_pll_vco); | ||
430 | ch7017_write(dvo, CH7017_LVDS_PLL_FEEDBACK_DIV, priv->save_feedback_div); | ||
431 | ch7017_write(dvo, CH7017_LVDS_CONTROL_2, priv->save_lvds_control_2); | ||
432 | ch7017_write(dvo, CH7017_OUTPUTS_ENABLE, priv->save_outputs_enable); | ||
433 | ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, priv->save_lvds_power_down); | ||
434 | ch7017_write(dvo, CH7017_POWER_MANAGEMENT, priv->save_power_management); | ||
435 | } | ||
436 | |||
437 | static void ch7017_destroy(struct intel_dvo_device *dvo) | 395 | static void ch7017_destroy(struct intel_dvo_device *dvo) |
438 | { | 396 | { |
439 | struct ch7017_priv *priv = dvo->dev_priv; | 397 | struct ch7017_priv *priv = dvo->dev_priv; |
@@ -451,7 +409,5 @@ struct intel_dvo_dev_ops ch7017_ops = { | |||
451 | .mode_set = ch7017_mode_set, | 409 | .mode_set = ch7017_mode_set, |
452 | .dpms = ch7017_dpms, | 410 | .dpms = ch7017_dpms, |
453 | .dump_regs = ch7017_dump_regs, | 411 | .dump_regs = ch7017_dump_regs, |
454 | .save = ch7017_save, | ||
455 | .restore = ch7017_restore, | ||
456 | .destroy = ch7017_destroy, | 412 | .destroy = ch7017_destroy, |
457 | }; | 413 | }; |
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index d56ff5cc22b2..6f1944b24441 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c | |||
@@ -92,21 +92,10 @@ static struct ch7xxx_id_struct { | |||
92 | { CH7301_VID, "CH7301" }, | 92 | { CH7301_VID, "CH7301" }, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | struct ch7xxx_reg_state { | ||
96 | uint8_t regs[CH7xxx_NUM_REGS]; | ||
97 | }; | ||
98 | |||
99 | struct ch7xxx_priv { | 95 | struct ch7xxx_priv { |
100 | bool quiet; | 96 | bool quiet; |
101 | |||
102 | struct ch7xxx_reg_state save_reg; | ||
103 | struct ch7xxx_reg_state mode_reg; | ||
104 | uint8_t save_TCTL, save_TPCP, save_TPD, save_TPVT; | ||
105 | uint8_t save_TLPF, save_TCT, save_PM, save_IDF; | ||
106 | }; | 97 | }; |
107 | 98 | ||
108 | static void ch7xxx_save(struct intel_dvo_device *dvo); | ||
109 | |||
110 | static char *ch7xxx_get_id(uint8_t vid) | 99 | static char *ch7xxx_get_id(uint8_t vid) |
111 | { | 100 | { |
112 | int i; | 101 | int i; |
@@ -312,42 +301,17 @@ static void ch7xxx_dpms(struct intel_dvo_device *dvo, int mode) | |||
312 | 301 | ||
313 | static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) | 302 | static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) |
314 | { | 303 | { |
315 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; | ||
316 | int i; | 304 | int i; |
317 | 305 | ||
318 | for (i = 0; i < CH7xxx_NUM_REGS; i++) { | 306 | for (i = 0; i < CH7xxx_NUM_REGS; i++) { |
307 | uint8_t val; | ||
319 | if ((i % 8) == 0 ) | 308 | if ((i % 8) == 0 ) |
320 | DRM_LOG_KMS("\n %02X: ", i); | 309 | DRM_LOG_KMS("\n %02X: ", i); |
321 | DRM_LOG_KMS("%02X ", ch7xxx->mode_reg.regs[i]); | 310 | ch7xxx_readb(dvo, i, &val); |
311 | DRM_LOG_KMS("%02X ", val); | ||
322 | } | 312 | } |
323 | } | 313 | } |
324 | 314 | ||
325 | static void ch7xxx_save(struct intel_dvo_device *dvo) | ||
326 | { | ||
327 | struct ch7xxx_priv *ch7xxx= dvo->dev_priv; | ||
328 | |||
329 | ch7xxx_readb(dvo, CH7xxx_TCTL, &ch7xxx->save_TCTL); | ||
330 | ch7xxx_readb(dvo, CH7xxx_TPCP, &ch7xxx->save_TPCP); | ||
331 | ch7xxx_readb(dvo, CH7xxx_TPD, &ch7xxx->save_TPD); | ||
332 | ch7xxx_readb(dvo, CH7xxx_TPVT, &ch7xxx->save_TPVT); | ||
333 | ch7xxx_readb(dvo, CH7xxx_TLPF, &ch7xxx->save_TLPF); | ||
334 | ch7xxx_readb(dvo, CH7xxx_PM, &ch7xxx->save_PM); | ||
335 | ch7xxx_readb(dvo, CH7xxx_IDF, &ch7xxx->save_IDF); | ||
336 | } | ||
337 | |||
338 | static void ch7xxx_restore(struct intel_dvo_device *dvo) | ||
339 | { | ||
340 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; | ||
341 | |||
342 | ch7xxx_writeb(dvo, CH7xxx_TCTL, ch7xxx->save_TCTL); | ||
343 | ch7xxx_writeb(dvo, CH7xxx_TPCP, ch7xxx->save_TPCP); | ||
344 | ch7xxx_writeb(dvo, CH7xxx_TPD, ch7xxx->save_TPD); | ||
345 | ch7xxx_writeb(dvo, CH7xxx_TPVT, ch7xxx->save_TPVT); | ||
346 | ch7xxx_writeb(dvo, CH7xxx_TLPF, ch7xxx->save_TLPF); | ||
347 | ch7xxx_writeb(dvo, CH7xxx_IDF, ch7xxx->save_IDF); | ||
348 | ch7xxx_writeb(dvo, CH7xxx_PM, ch7xxx->save_PM); | ||
349 | } | ||
350 | |||
351 | static void ch7xxx_destroy(struct intel_dvo_device *dvo) | 315 | static void ch7xxx_destroy(struct intel_dvo_device *dvo) |
352 | { | 316 | { |
353 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; | 317 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; |
@@ -365,7 +329,5 @@ struct intel_dvo_dev_ops ch7xxx_ops = { | |||
365 | .mode_set = ch7xxx_mode_set, | 329 | .mode_set = ch7xxx_mode_set, |
366 | .dpms = ch7xxx_dpms, | 330 | .dpms = ch7xxx_dpms, |
367 | .dump_regs = ch7xxx_dump_regs, | 331 | .dump_regs = ch7xxx_dump_regs, |
368 | .save = ch7xxx_save, | ||
369 | .restore = ch7xxx_restore, | ||
370 | .destroy = ch7xxx_destroy, | 332 | .destroy = ch7xxx_destroy, |
371 | }; | 333 | }; |
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c index 24169e528f0f..a2ec3f487202 100644 --- a/drivers/gpu/drm/i915/dvo_ivch.c +++ b/drivers/gpu/drm/i915/dvo_ivch.c | |||
@@ -153,9 +153,6 @@ struct ivch_priv { | |||
153 | bool quiet; | 153 | bool quiet; |
154 | 154 | ||
155 | uint16_t width, height; | 155 | uint16_t width, height; |
156 | |||
157 | uint16_t save_VR01; | ||
158 | uint16_t save_VR40; | ||
159 | }; | 156 | }; |
160 | 157 | ||
161 | 158 | ||
@@ -405,22 +402,6 @@ static void ivch_dump_regs(struct intel_dvo_device *dvo) | |||
405 | DRM_LOG_KMS("VR8F: 0x%04x\n", val); | 402 | DRM_LOG_KMS("VR8F: 0x%04x\n", val); |
406 | } | 403 | } |
407 | 404 | ||
408 | static void ivch_save(struct intel_dvo_device *dvo) | ||
409 | { | ||
410 | struct ivch_priv *priv = dvo->dev_priv; | ||
411 | |||
412 | ivch_read(dvo, VR01, &priv->save_VR01); | ||
413 | ivch_read(dvo, VR40, &priv->save_VR40); | ||
414 | } | ||
415 | |||
416 | static void ivch_restore(struct intel_dvo_device *dvo) | ||
417 | { | ||
418 | struct ivch_priv *priv = dvo->dev_priv; | ||
419 | |||
420 | ivch_write(dvo, VR01, priv->save_VR01); | ||
421 | ivch_write(dvo, VR40, priv->save_VR40); | ||
422 | } | ||
423 | |||
424 | static void ivch_destroy(struct intel_dvo_device *dvo) | 405 | static void ivch_destroy(struct intel_dvo_device *dvo) |
425 | { | 406 | { |
426 | struct ivch_priv *priv = dvo->dev_priv; | 407 | struct ivch_priv *priv = dvo->dev_priv; |
@@ -434,8 +415,6 @@ static void ivch_destroy(struct intel_dvo_device *dvo) | |||
434 | struct intel_dvo_dev_ops ivch_ops= { | 415 | struct intel_dvo_dev_ops ivch_ops= { |
435 | .init = ivch_init, | 416 | .init = ivch_init, |
436 | .dpms = ivch_dpms, | 417 | .dpms = ivch_dpms, |
437 | .save = ivch_save, | ||
438 | .restore = ivch_restore, | ||
439 | .mode_valid = ivch_mode_valid, | 418 | .mode_valid = ivch_mode_valid, |
440 | .mode_set = ivch_mode_set, | 419 | .mode_set = ivch_mode_set, |
441 | .detect = ivch_detect, | 420 | .detect = ivch_detect, |
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c index 0001c13f0a80..9b8e6765cf26 100644 --- a/drivers/gpu/drm/i915/dvo_sil164.c +++ b/drivers/gpu/drm/i915/dvo_sil164.c | |||
@@ -58,17 +58,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
58 | 58 | ||
59 | #define SIL164_REGC 0x0c | 59 | #define SIL164_REGC 0x0c |
60 | 60 | ||
61 | struct sil164_save_rec { | ||
62 | uint8_t reg8; | ||
63 | uint8_t reg9; | ||
64 | uint8_t regc; | ||
65 | }; | ||
66 | |||
67 | struct sil164_priv { | 61 | struct sil164_priv { |
68 | //I2CDevRec d; | 62 | //I2CDevRec d; |
69 | bool quiet; | 63 | bool quiet; |
70 | struct sil164_save_rec save_regs; | ||
71 | struct sil164_save_rec mode_regs; | ||
72 | }; | 64 | }; |
73 | 65 | ||
74 | #define SILPTR(d) ((SIL164Ptr)(d->DriverPrivate.ptr)) | 66 | #define SILPTR(d) ((SIL164Ptr)(d->DriverPrivate.ptr)) |
@@ -252,34 +244,6 @@ static void sil164_dump_regs(struct intel_dvo_device *dvo) | |||
252 | DRM_LOG_KMS("SIL164_REGC: 0x%02x\n", val); | 244 | DRM_LOG_KMS("SIL164_REGC: 0x%02x\n", val); |
253 | } | 245 | } |
254 | 246 | ||
255 | static void sil164_save(struct intel_dvo_device *dvo) | ||
256 | { | ||
257 | struct sil164_priv *sil= dvo->dev_priv; | ||
258 | |||
259 | if (!sil164_readb(dvo, SIL164_REG8, &sil->save_regs.reg8)) | ||
260 | return; | ||
261 | |||
262 | if (!sil164_readb(dvo, SIL164_REG9, &sil->save_regs.reg9)) | ||
263 | return; | ||
264 | |||
265 | if (!sil164_readb(dvo, SIL164_REGC, &sil->save_regs.regc)) | ||
266 | return; | ||
267 | |||
268 | return; | ||
269 | } | ||
270 | |||
271 | static void sil164_restore(struct intel_dvo_device *dvo) | ||
272 | { | ||
273 | struct sil164_priv *sil = dvo->dev_priv; | ||
274 | |||
275 | /* Restore it powered down initially */ | ||
276 | sil164_writeb(dvo, SIL164_REG8, sil->save_regs.reg8 & ~0x1); | ||
277 | |||
278 | sil164_writeb(dvo, SIL164_REG9, sil->save_regs.reg9); | ||
279 | sil164_writeb(dvo, SIL164_REGC, sil->save_regs.regc); | ||
280 | sil164_writeb(dvo, SIL164_REG8, sil->save_regs.reg8); | ||
281 | } | ||
282 | |||
283 | static void sil164_destroy(struct intel_dvo_device *dvo) | 247 | static void sil164_destroy(struct intel_dvo_device *dvo) |
284 | { | 248 | { |
285 | struct sil164_priv *sil = dvo->dev_priv; | 249 | struct sil164_priv *sil = dvo->dev_priv; |
@@ -297,7 +261,5 @@ struct intel_dvo_dev_ops sil164_ops = { | |||
297 | .mode_set = sil164_mode_set, | 261 | .mode_set = sil164_mode_set, |
298 | .dpms = sil164_dpms, | 262 | .dpms = sil164_dpms, |
299 | .dump_regs = sil164_dump_regs, | 263 | .dump_regs = sil164_dump_regs, |
300 | .save = sil164_save, | ||
301 | .restore = sil164_restore, | ||
302 | .destroy = sil164_destroy, | 264 | .destroy = sil164_destroy, |
303 | }; | 265 | }; |
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c index c7c391bc116a..66c697bc9b22 100644 --- a/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/dvo_tfp410.c | |||
@@ -86,16 +86,8 @@ | |||
86 | #define TFP410_V_RES_LO 0x3C | 86 | #define TFP410_V_RES_LO 0x3C |
87 | #define TFP410_V_RES_HI 0x3D | 87 | #define TFP410_V_RES_HI 0x3D |
88 | 88 | ||
89 | struct tfp410_save_rec { | ||
90 | uint8_t ctl1; | ||
91 | uint8_t ctl2; | ||
92 | }; | ||
93 | |||
94 | struct tfp410_priv { | 89 | struct tfp410_priv { |
95 | bool quiet; | 90 | bool quiet; |
96 | |||
97 | struct tfp410_save_rec saved_reg; | ||
98 | struct tfp410_save_rec mode_reg; | ||
99 | }; | 91 | }; |
100 | 92 | ||
101 | static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | 93 | static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) |
@@ -293,28 +285,6 @@ static void tfp410_dump_regs(struct intel_dvo_device *dvo) | |||
293 | DRM_LOG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val); | 285 | DRM_LOG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val); |
294 | } | 286 | } |
295 | 287 | ||
296 | static void tfp410_save(struct intel_dvo_device *dvo) | ||
297 | { | ||
298 | struct tfp410_priv *tfp = dvo->dev_priv; | ||
299 | |||
300 | if (!tfp410_readb(dvo, TFP410_CTL_1, &tfp->saved_reg.ctl1)) | ||
301 | return; | ||
302 | |||
303 | if (!tfp410_readb(dvo, TFP410_CTL_2, &tfp->saved_reg.ctl2)) | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | static void tfp410_restore(struct intel_dvo_device *dvo) | ||
308 | { | ||
309 | struct tfp410_priv *tfp = dvo->dev_priv; | ||
310 | |||
311 | /* Restore it powered down initially */ | ||
312 | tfp410_writeb(dvo, TFP410_CTL_1, tfp->saved_reg.ctl1 & ~0x1); | ||
313 | |||
314 | tfp410_writeb(dvo, TFP410_CTL_2, tfp->saved_reg.ctl2); | ||
315 | tfp410_writeb(dvo, TFP410_CTL_1, tfp->saved_reg.ctl1); | ||
316 | } | ||
317 | |||
318 | static void tfp410_destroy(struct intel_dvo_device *dvo) | 288 | static void tfp410_destroy(struct intel_dvo_device *dvo) |
319 | { | 289 | { |
320 | struct tfp410_priv *tfp = dvo->dev_priv; | 290 | struct tfp410_priv *tfp = dvo->dev_priv; |
@@ -332,7 +302,5 @@ struct intel_dvo_dev_ops tfp410_ops = { | |||
332 | .mode_set = tfp410_mode_set, | 302 | .mode_set = tfp410_mode_set, |
333 | .dpms = tfp410_dpms, | 303 | .dpms = tfp410_dpms, |
334 | .dump_regs = tfp410_dump_regs, | 304 | .dump_regs = tfp410_dump_regs, |
335 | .save = tfp410_save, | ||
336 | .restore = tfp410_restore, | ||
337 | .destroy = tfp410_destroy, | 305 | .destroy = tfp410_destroy, |
338 | }; | 306 | }; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a0b8447b06e7..322070c0c631 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -96,19 +96,18 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
96 | spin_lock(lock); | 96 | spin_lock(lock); |
97 | list_for_each_entry(obj_priv, head, list) | 97 | list_for_each_entry(obj_priv, head, list) |
98 | { | 98 | { |
99 | struct drm_gem_object *obj = obj_priv->obj; | ||
100 | |||
101 | seq_printf(m, " %p: %s %8zd %08x %08x %d%s%s", | 99 | seq_printf(m, " %p: %s %8zd %08x %08x %d%s%s", |
102 | obj, | 100 | &obj_priv->base, |
103 | get_pin_flag(obj_priv), | 101 | get_pin_flag(obj_priv), |
104 | obj->size, | 102 | obj_priv->base.size, |
105 | obj->read_domains, obj->write_domain, | 103 | obj_priv->base.read_domains, |
104 | obj_priv->base.write_domain, | ||
106 | obj_priv->last_rendering_seqno, | 105 | obj_priv->last_rendering_seqno, |
107 | obj_priv->dirty ? " dirty" : "", | 106 | obj_priv->dirty ? " dirty" : "", |
108 | obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | 107 | obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : ""); |
109 | 108 | ||
110 | if (obj->name) | 109 | if (obj_priv->base.name) |
111 | seq_printf(m, " (name: %d)", obj->name); | 110 | seq_printf(m, " (name: %d)", obj_priv->base.name); |
112 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 111 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
113 | seq_printf(m, " (fence: %d)", obj_priv->fence_reg); | 112 | seq_printf(m, " (fence: %d)", obj_priv->fence_reg); |
114 | if (obj_priv->gtt_space != NULL) | 113 | if (obj_priv->gtt_space != NULL) |
@@ -289,7 +288,7 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) | |||
289 | spin_lock(&dev_priv->mm.active_list_lock); | 288 | spin_lock(&dev_priv->mm.active_list_lock); |
290 | 289 | ||
291 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | 290 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { |
292 | obj = obj_priv->obj; | 291 | obj = &obj_priv->base; |
293 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { | 292 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { |
294 | ret = i915_gem_object_get_pages(obj, 0); | 293 | ret = i915_gem_object_get_pages(obj, 0); |
295 | if (ret) { | 294 | if (ret) { |
@@ -567,23 +566,14 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
567 | { | 566 | { |
568 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 567 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
569 | struct drm_device *dev = node->minor->dev; | 568 | struct drm_device *dev = node->minor->dev; |
570 | struct drm_crtc *crtc; | ||
571 | drm_i915_private_t *dev_priv = dev->dev_private; | 569 | drm_i915_private_t *dev_priv = dev->dev_private; |
572 | bool fbc_enabled = false; | ||
573 | 570 | ||
574 | if (!dev_priv->display.fbc_enabled) { | 571 | if (!I915_HAS_FBC(dev)) { |
575 | seq_printf(m, "FBC unsupported on this chipset\n"); | 572 | seq_printf(m, "FBC unsupported on this chipset\n"); |
576 | return 0; | 573 | return 0; |
577 | } | 574 | } |
578 | 575 | ||
579 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 576 | if (intel_fbc_enabled(dev)) { |
580 | if (!crtc->enabled) | ||
581 | continue; | ||
582 | if (dev_priv->display.fbc_enabled(crtc)) | ||
583 | fbc_enabled = true; | ||
584 | } | ||
585 | |||
586 | if (fbc_enabled) { | ||
587 | seq_printf(m, "FBC enabled\n"); | 577 | seq_printf(m, "FBC enabled\n"); |
588 | } else { | 578 | } else { |
589 | seq_printf(m, "FBC disabled: "); | 579 | seq_printf(m, "FBC disabled: "); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2dc93939507d..2a6b5de5ae5d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1357,19 +1357,30 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1357 | 1357 | ||
1358 | dev_priv->cfb_size = size; | 1358 | dev_priv->cfb_size = size; |
1359 | 1359 | ||
1360 | intel_disable_fbc(dev); | ||
1361 | dev_priv->compressed_fb = compressed_fb; | ||
1362 | |||
1360 | if (IS_GM45(dev)) { | 1363 | if (IS_GM45(dev)) { |
1361 | g4x_disable_fbc(dev); | ||
1362 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); | 1364 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); |
1363 | } else { | 1365 | } else { |
1364 | i8xx_disable_fbc(dev); | ||
1365 | I915_WRITE(FBC_CFB_BASE, cfb_base); | 1366 | I915_WRITE(FBC_CFB_BASE, cfb_base); |
1366 | I915_WRITE(FBC_LL_BASE, ll_base); | 1367 | I915_WRITE(FBC_LL_BASE, ll_base); |
1368 | dev_priv->compressed_llb = compressed_llb; | ||
1367 | } | 1369 | } |
1368 | 1370 | ||
1369 | DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, | 1371 | DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, |
1370 | ll_base, size >> 20); | 1372 | ll_base, size >> 20); |
1371 | } | 1373 | } |
1372 | 1374 | ||
1375 | static void i915_cleanup_compression(struct drm_device *dev) | ||
1376 | { | ||
1377 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1378 | |||
1379 | drm_mm_put_block(dev_priv->compressed_fb); | ||
1380 | if (!IS_GM45(dev)) | ||
1381 | drm_mm_put_block(dev_priv->compressed_llb); | ||
1382 | } | ||
1383 | |||
1373 | /* true = enable decode, false = disable decoder */ | 1384 | /* true = enable decode, false = disable decoder */ |
1374 | static unsigned int i915_vga_set_decode(void *cookie, bool state) | 1385 | static unsigned int i915_vga_set_decode(void *cookie, bool state) |
1375 | { | 1386 | { |
@@ -1492,8 +1503,8 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1492 | 1503 | ||
1493 | I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); | 1504 | I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); |
1494 | 1505 | ||
1495 | drm_helper_initial_config(dev); | 1506 | intel_fbdev_init(dev); |
1496 | 1507 | drm_kms_helper_poll_init(dev); | |
1497 | return 0; | 1508 | return 0; |
1498 | 1509 | ||
1499 | destroy_ringbuffer: | 1510 | destroy_ringbuffer: |
@@ -1579,7 +1590,7 @@ static void i915_get_mem_freq(struct drm_device *dev) | |||
1579 | */ | 1590 | */ |
1580 | int i915_driver_load(struct drm_device *dev, unsigned long flags) | 1591 | int i915_driver_load(struct drm_device *dev, unsigned long flags) |
1581 | { | 1592 | { |
1582 | struct drm_i915_private *dev_priv = dev->dev_private; | 1593 | struct drm_i915_private *dev_priv; |
1583 | resource_size_t base, size; | 1594 | resource_size_t base, size; |
1584 | int ret = 0, mmio_bar; | 1595 | int ret = 0, mmio_bar; |
1585 | uint32_t agp_size, prealloc_size, prealloc_start; | 1596 | uint32_t agp_size, prealloc_size, prealloc_start; |
@@ -1711,6 +1722,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1711 | /* Start out suspended */ | 1722 | /* Start out suspended */ |
1712 | dev_priv->mm.suspended = 1; | 1723 | dev_priv->mm.suspended = 1; |
1713 | 1724 | ||
1725 | intel_detect_pch(dev); | ||
1726 | |||
1714 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1727 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1715 | ret = i915_load_modeset_init(dev, prealloc_start, | 1728 | ret = i915_load_modeset_init(dev, prealloc_start, |
1716 | prealloc_size, agp_size); | 1729 | prealloc_size, agp_size); |
@@ -1757,6 +1770,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
1757 | } | 1770 | } |
1758 | 1771 | ||
1759 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1772 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1773 | intel_modeset_cleanup(dev); | ||
1774 | |||
1760 | /* | 1775 | /* |
1761 | * free the memory space allocated for the child device | 1776 | * free the memory space allocated for the child device |
1762 | * config parsed from VBT | 1777 | * config parsed from VBT |
@@ -1780,13 +1795,13 @@ int i915_driver_unload(struct drm_device *dev) | |||
1780 | intel_opregion_free(dev, 0); | 1795 | intel_opregion_free(dev, 0); |
1781 | 1796 | ||
1782 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1797 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1783 | intel_modeset_cleanup(dev); | ||
1784 | |||
1785 | i915_gem_free_all_phys_object(dev); | 1798 | i915_gem_free_all_phys_object(dev); |
1786 | 1799 | ||
1787 | mutex_lock(&dev->struct_mutex); | 1800 | mutex_lock(&dev->struct_mutex); |
1788 | i915_gem_cleanup_ringbuffer(dev); | 1801 | i915_gem_cleanup_ringbuffer(dev); |
1789 | mutex_unlock(&dev->struct_mutex); | 1802 | mutex_unlock(&dev->struct_mutex); |
1803 | if (I915_HAS_FBC(dev) && i915_powersave) | ||
1804 | i915_cleanup_compression(dev); | ||
1790 | drm_mm_takedown(&dev_priv->vram); | 1805 | drm_mm_takedown(&dev_priv->vram); |
1791 | i915_gem_lastclose(dev); | 1806 | i915_gem_lastclose(dev); |
1792 | 1807 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0af3dcc85ce9..5c51e45ab68d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -69,7 +69,8 @@ const static struct intel_device_info intel_845g_info = { | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | const static struct intel_device_info intel_i85x_info = { | 71 | const static struct intel_device_info intel_i85x_info = { |
72 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, | 72 | .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, |
73 | .cursor_needs_physical = 1, | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | const static struct intel_device_info intel_i865g_info = { | 76 | const static struct intel_device_info intel_i865g_info = { |
@@ -151,7 +152,7 @@ const static struct pci_device_id pciidlist[] = { | |||
151 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), | 152 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), |
152 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), | 153 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), |
153 | INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), | 154 | INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), |
154 | INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info), | 155 | INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), |
155 | INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), | 156 | INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), |
156 | INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), | 157 | INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), |
157 | INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), | 158 | INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), |
@@ -187,6 +188,35 @@ const static struct pci_device_id pciidlist[] = { | |||
187 | MODULE_DEVICE_TABLE(pci, pciidlist); | 188 | MODULE_DEVICE_TABLE(pci, pciidlist); |
188 | #endif | 189 | #endif |
189 | 190 | ||
191 | #define INTEL_PCH_DEVICE_ID_MASK 0xff00 | ||
192 | #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 | ||
193 | |||
194 | void intel_detect_pch (struct drm_device *dev) | ||
195 | { | ||
196 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
197 | struct pci_dev *pch; | ||
198 | |||
199 | /* | ||
200 | * The reason to probe ISA bridge instead of Dev31:Fun0 is to | ||
201 | * make graphics device passthrough work easy for VMM, that only | ||
202 | * need to expose ISA bridge to let driver know the real hardware | ||
203 | * underneath. This is a requirement from virtualization team. | ||
204 | */ | ||
205 | pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); | ||
206 | if (pch) { | ||
207 | if (pch->vendor == PCI_VENDOR_ID_INTEL) { | ||
208 | int id; | ||
209 | id = pch->device & INTEL_PCH_DEVICE_ID_MASK; | ||
210 | |||
211 | if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { | ||
212 | dev_priv->pch_type = PCH_CPT; | ||
213 | DRM_DEBUG_KMS("Found CougarPoint PCH\n"); | ||
214 | } | ||
215 | } | ||
216 | pci_dev_put(pch); | ||
217 | } | ||
218 | } | ||
219 | |||
190 | static int i915_drm_freeze(struct drm_device *dev) | 220 | static int i915_drm_freeze(struct drm_device *dev) |
191 | { | 221 | { |
192 | struct drm_i915_private *dev_priv = dev->dev_private; | 222 | struct drm_i915_private *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6960849522f8..7f797ef1ab39 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -128,6 +128,7 @@ struct drm_i915_master_private { | |||
128 | 128 | ||
129 | struct drm_i915_fence_reg { | 129 | struct drm_i915_fence_reg { |
130 | struct drm_gem_object *obj; | 130 | struct drm_gem_object *obj; |
131 | struct list_head lru_list; | ||
131 | }; | 132 | }; |
132 | 133 | ||
133 | struct sdvo_device_mapping { | 134 | struct sdvo_device_mapping { |
@@ -135,6 +136,7 @@ struct sdvo_device_mapping { | |||
135 | u8 slave_addr; | 136 | u8 slave_addr; |
136 | u8 dvo_wiring; | 137 | u8 dvo_wiring; |
137 | u8 initialized; | 138 | u8 initialized; |
139 | u8 ddc_pin; | ||
138 | }; | 140 | }; |
139 | 141 | ||
140 | struct drm_i915_error_state { | 142 | struct drm_i915_error_state { |
@@ -175,7 +177,7 @@ struct drm_i915_error_state { | |||
175 | 177 | ||
176 | struct drm_i915_display_funcs { | 178 | struct drm_i915_display_funcs { |
177 | void (*dpms)(struct drm_crtc *crtc, int mode); | 179 | void (*dpms)(struct drm_crtc *crtc, int mode); |
178 | bool (*fbc_enabled)(struct drm_crtc *crtc); | 180 | bool (*fbc_enabled)(struct drm_device *dev); |
179 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); | 181 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); |
180 | void (*disable_fbc)(struct drm_device *dev); | 182 | void (*disable_fbc)(struct drm_device *dev); |
181 | int (*get_display_clock_speed)(struct drm_device *dev); | 183 | int (*get_display_clock_speed)(struct drm_device *dev); |
@@ -195,6 +197,7 @@ struct intel_overlay; | |||
195 | struct intel_device_info { | 197 | struct intel_device_info { |
196 | u8 is_mobile : 1; | 198 | u8 is_mobile : 1; |
197 | u8 is_i8xx : 1; | 199 | u8 is_i8xx : 1; |
200 | u8 is_i85x : 1; | ||
198 | u8 is_i915g : 1; | 201 | u8 is_i915g : 1; |
199 | u8 is_i9xx : 1; | 202 | u8 is_i9xx : 1; |
200 | u8 is_i945gm : 1; | 203 | u8 is_i945gm : 1; |
@@ -221,6 +224,13 @@ enum no_fbc_reason { | |||
221 | FBC_NOT_TILED, /* buffer not tiled */ | 224 | FBC_NOT_TILED, /* buffer not tiled */ |
222 | }; | 225 | }; |
223 | 226 | ||
227 | enum intel_pch { | ||
228 | PCH_IBX, /* Ibexpeak PCH */ | ||
229 | PCH_CPT, /* Cougarpoint PCH */ | ||
230 | }; | ||
231 | |||
232 | struct intel_fbdev; | ||
233 | |||
224 | typedef struct drm_i915_private { | 234 | typedef struct drm_i915_private { |
225 | struct drm_device *dev; | 235 | struct drm_device *dev; |
226 | 236 | ||
@@ -235,11 +245,14 @@ typedef struct drm_i915_private { | |||
235 | 245 | ||
236 | drm_dma_handle_t *status_page_dmah; | 246 | drm_dma_handle_t *status_page_dmah; |
237 | void *hw_status_page; | 247 | void *hw_status_page; |
248 | void *seqno_page; | ||
238 | dma_addr_t dma_status_page; | 249 | dma_addr_t dma_status_page; |
239 | uint32_t counter; | 250 | uint32_t counter; |
240 | unsigned int status_gfx_addr; | 251 | unsigned int status_gfx_addr; |
252 | unsigned int seqno_gfx_addr; | ||
241 | drm_local_map_t hws_map; | 253 | drm_local_map_t hws_map; |
242 | struct drm_gem_object *hws_obj; | 254 | struct drm_gem_object *hws_obj; |
255 | struct drm_gem_object *seqno_obj; | ||
243 | struct drm_gem_object *pwrctx; | 256 | struct drm_gem_object *pwrctx; |
244 | 257 | ||
245 | struct resource mch_res; | 258 | struct resource mch_res; |
@@ -331,6 +344,9 @@ typedef struct drm_i915_private { | |||
331 | /* Display functions */ | 344 | /* Display functions */ |
332 | struct drm_i915_display_funcs display; | 345 | struct drm_i915_display_funcs display; |
333 | 346 | ||
347 | /* PCH chipset type */ | ||
348 | enum intel_pch pch_type; | ||
349 | |||
334 | /* Register state */ | 350 | /* Register state */ |
335 | bool modeset_on_lid; | 351 | bool modeset_on_lid; |
336 | u8 saveLBB; | 352 | u8 saveLBB; |
@@ -630,11 +646,17 @@ typedef struct drm_i915_private { | |||
630 | u8 max_delay; | 646 | u8 max_delay; |
631 | 647 | ||
632 | enum no_fbc_reason no_fbc_reason; | 648 | enum no_fbc_reason no_fbc_reason; |
649 | |||
650 | struct drm_mm_node *compressed_fb; | ||
651 | struct drm_mm_node *compressed_llb; | ||
652 | |||
653 | /* list of fbdev register on this device */ | ||
654 | struct intel_fbdev *fbdev; | ||
633 | } drm_i915_private_t; | 655 | } drm_i915_private_t; |
634 | 656 | ||
635 | /** driver private structure attached to each drm_gem_object */ | 657 | /** driver private structure attached to each drm_gem_object */ |
636 | struct drm_i915_gem_object { | 658 | struct drm_i915_gem_object { |
637 | struct drm_gem_object *obj; | 659 | struct drm_gem_object base; |
638 | 660 | ||
639 | /** Current space allocated to this object in the GTT, if any. */ | 661 | /** Current space allocated to this object in the GTT, if any. */ |
640 | struct drm_mm_node *gtt_space; | 662 | struct drm_mm_node *gtt_space; |
@@ -644,9 +666,6 @@ struct drm_i915_gem_object { | |||
644 | /** This object's place on GPU write list */ | 666 | /** This object's place on GPU write list */ |
645 | struct list_head gpu_write_list; | 667 | struct list_head gpu_write_list; |
646 | 668 | ||
647 | /** This object's place on the fenced object LRU */ | ||
648 | struct list_head fence_list; | ||
649 | |||
650 | /** | 669 | /** |
651 | * This is set if the object is on the active or flushing lists | 670 | * This is set if the object is on the active or flushing lists |
652 | * (has pending rendering), and is not set if it's on inactive (ready | 671 | * (has pending rendering), and is not set if it's on inactive (ready |
@@ -733,7 +752,7 @@ struct drm_i915_gem_object { | |||
733 | atomic_t pending_flip; | 752 | atomic_t pending_flip; |
734 | }; | 753 | }; |
735 | 754 | ||
736 | #define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private) | 755 | #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) |
737 | 756 | ||
738 | /** | 757 | /** |
739 | * Request queue structure. | 758 | * Request queue structure. |
@@ -895,6 +914,8 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | |||
895 | struct drm_file *file_priv); | 914 | struct drm_file *file_priv); |
896 | void i915_gem_load(struct drm_device *dev); | 915 | void i915_gem_load(struct drm_device *dev); |
897 | int i915_gem_init_object(struct drm_gem_object *obj); | 916 | int i915_gem_init_object(struct drm_gem_object *obj); |
917 | struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, | ||
918 | size_t size); | ||
898 | void i915_gem_free_object(struct drm_gem_object *obj); | 919 | void i915_gem_free_object(struct drm_gem_object *obj); |
899 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); | 920 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); |
900 | void i915_gem_object_unpin(struct drm_gem_object *obj); | 921 | void i915_gem_object_unpin(struct drm_gem_object *obj); |
@@ -991,6 +1012,12 @@ extern void intel_modeset_cleanup(struct drm_device *dev); | |||
991 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); | 1012 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); |
992 | extern void i8xx_disable_fbc(struct drm_device *dev); | 1013 | extern void i8xx_disable_fbc(struct drm_device *dev); |
993 | extern void g4x_disable_fbc(struct drm_device *dev); | 1014 | extern void g4x_disable_fbc(struct drm_device *dev); |
1015 | extern void intel_disable_fbc(struct drm_device *dev); | ||
1016 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); | ||
1017 | extern bool intel_fbc_enabled(struct drm_device *dev); | ||
1018 | |||
1019 | extern void intel_detect_pch (struct drm_device *dev); | ||
1020 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | ||
994 | 1021 | ||
995 | /** | 1022 | /** |
996 | * Lock test for when it's just for synchronization of ring access. | 1023 | * Lock test for when it's just for synchronization of ring access. |
@@ -1070,7 +1097,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1070 | 1097 | ||
1071 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | 1098 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) |
1072 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | 1099 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) |
1073 | #define IS_I85X(dev) ((dev)->pci_device == 0x3582) | 1100 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) |
1074 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | 1101 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) |
1075 | #define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) | 1102 | #define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) |
1076 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) | 1103 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) |
@@ -1123,7 +1150,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1123 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) | 1150 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) |
1124 | #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) | 1151 | #define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) |
1125 | #define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \ | 1152 | #define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \ |
1126 | !IS_IRONLAKE(dev) && !IS_PINEVIEW(dev)) | 1153 | !IS_IRONLAKE(dev) && !IS_PINEVIEW(dev) && \ |
1154 | !IS_GEN6(dev)) | ||
1127 | #define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) | 1155 | #define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) |
1128 | /* dsparb controlled by hw only */ | 1156 | /* dsparb controlled by hw only */ |
1129 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) | 1157 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) |
@@ -1135,6 +1163,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1135 | 1163 | ||
1136 | #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \ | 1164 | #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \ |
1137 | IS_GEN6(dev)) | 1165 | IS_GEN6(dev)) |
1166 | #define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev)) | ||
1167 | |||
1168 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) | ||
1169 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) | ||
1138 | 1170 | ||
1139 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 1171 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
1140 | 1172 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 80871c62a571..112699f71fa4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -124,7 +124,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
124 | args->size = roundup(args->size, PAGE_SIZE); | 124 | args->size = roundup(args->size, PAGE_SIZE); |
125 | 125 | ||
126 | /* Allocate the new object */ | 126 | /* Allocate the new object */ |
127 | obj = drm_gem_object_alloc(dev, args->size); | 127 | obj = i915_gem_alloc_object(dev, args->size); |
128 | if (obj == NULL) | 128 | if (obj == NULL) |
129 | return -ENOMEM; | 129 | return -ENOMEM; |
130 | 130 | ||
@@ -1051,7 +1051,9 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1051 | * about to occur. | 1051 | * about to occur. |
1052 | */ | 1052 | */ |
1053 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | 1053 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
1054 | list_move_tail(&obj_priv->fence_list, | 1054 | struct drm_i915_fence_reg *reg = |
1055 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
1056 | list_move_tail(®->lru_list, | ||
1055 | &dev_priv->mm.fence_list); | 1057 | &dev_priv->mm.fence_list); |
1056 | } | 1058 | } |
1057 | 1059 | ||
@@ -1566,7 +1568,7 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1566 | list_for_each_entry_safe(obj_priv, next, | 1568 | list_for_each_entry_safe(obj_priv, next, |
1567 | &dev_priv->mm.gpu_write_list, | 1569 | &dev_priv->mm.gpu_write_list, |
1568 | gpu_write_list) { | 1570 | gpu_write_list) { |
1569 | struct drm_gem_object *obj = obj_priv->obj; | 1571 | struct drm_gem_object *obj = &obj_priv->base; |
1570 | 1572 | ||
1571 | if ((obj->write_domain & flush_domains) == | 1573 | if ((obj->write_domain & flush_domains) == |
1572 | obj->write_domain) { | 1574 | obj->write_domain) { |
@@ -1577,9 +1579,12 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1577 | i915_gem_object_move_to_active(obj, seqno); | 1579 | i915_gem_object_move_to_active(obj, seqno); |
1578 | 1580 | ||
1579 | /* update the fence lru list */ | 1581 | /* update the fence lru list */ |
1580 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1582 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
1581 | list_move_tail(&obj_priv->fence_list, | 1583 | struct drm_i915_fence_reg *reg = |
1584 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
1585 | list_move_tail(®->lru_list, | ||
1582 | &dev_priv->mm.fence_list); | 1586 | &dev_priv->mm.fence_list); |
1587 | } | ||
1583 | 1588 | ||
1584 | trace_i915_gem_object_change_domain(obj, | 1589 | trace_i915_gem_object_change_domain(obj, |
1585 | obj->read_domains, | 1590 | obj->read_domains, |
@@ -1588,6 +1593,13 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1588 | } | 1593 | } |
1589 | } | 1594 | } |
1590 | 1595 | ||
1596 | #define PIPE_CONTROL_FLUSH(addr) \ | ||
1597 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ | ||
1598 | PIPE_CONTROL_DEPTH_STALL); \ | ||
1599 | OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ | ||
1600 | OUT_RING(0); \ | ||
1601 | OUT_RING(0); \ | ||
1602 | |||
1591 | /** | 1603 | /** |
1592 | * Creates a new sequence number, emitting a write of it to the status page | 1604 | * Creates a new sequence number, emitting a write of it to the status page |
1593 | * plus an interrupt, which will trigger i915_user_interrupt_handler. | 1605 | * plus an interrupt, which will trigger i915_user_interrupt_handler. |
@@ -1622,13 +1634,47 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1622 | if (dev_priv->mm.next_gem_seqno == 0) | 1634 | if (dev_priv->mm.next_gem_seqno == 0) |
1623 | dev_priv->mm.next_gem_seqno++; | 1635 | dev_priv->mm.next_gem_seqno++; |
1624 | 1636 | ||
1625 | BEGIN_LP_RING(4); | 1637 | if (HAS_PIPE_CONTROL(dev)) { |
1626 | OUT_RING(MI_STORE_DWORD_INDEX); | 1638 | u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; |
1627 | OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
1628 | OUT_RING(seqno); | ||
1629 | 1639 | ||
1630 | OUT_RING(MI_USER_INTERRUPT); | 1640 | /* |
1631 | ADVANCE_LP_RING(); | 1641 | * Workaround qword write incoherence by flushing the |
1642 | * PIPE_NOTIFY buffers out to memory before requesting | ||
1643 | * an interrupt. | ||
1644 | */ | ||
1645 | BEGIN_LP_RING(32); | ||
1646 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
1647 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | ||
1648 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
1649 | OUT_RING(seqno); | ||
1650 | OUT_RING(0); | ||
1651 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1652 | scratch_addr += 128; /* write to separate cachelines */ | ||
1653 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1654 | scratch_addr += 128; | ||
1655 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1656 | scratch_addr += 128; | ||
1657 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1658 | scratch_addr += 128; | ||
1659 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1660 | scratch_addr += 128; | ||
1661 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1662 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
1663 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | ||
1664 | PIPE_CONTROL_NOTIFY); | ||
1665 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
1666 | OUT_RING(seqno); | ||
1667 | OUT_RING(0); | ||
1668 | ADVANCE_LP_RING(); | ||
1669 | } else { | ||
1670 | BEGIN_LP_RING(4); | ||
1671 | OUT_RING(MI_STORE_DWORD_INDEX); | ||
1672 | OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
1673 | OUT_RING(seqno); | ||
1674 | |||
1675 | OUT_RING(MI_USER_INTERRUPT); | ||
1676 | ADVANCE_LP_RING(); | ||
1677 | } | ||
1632 | 1678 | ||
1633 | DRM_DEBUG_DRIVER("%d\n", seqno); | 1679 | DRM_DEBUG_DRIVER("%d\n", seqno); |
1634 | 1680 | ||
@@ -1704,7 +1750,7 @@ i915_gem_retire_request(struct drm_device *dev, | |||
1704 | obj_priv = list_first_entry(&dev_priv->mm.active_list, | 1750 | obj_priv = list_first_entry(&dev_priv->mm.active_list, |
1705 | struct drm_i915_gem_object, | 1751 | struct drm_i915_gem_object, |
1706 | list); | 1752 | list); |
1707 | obj = obj_priv->obj; | 1753 | obj = &obj_priv->base; |
1708 | 1754 | ||
1709 | /* If the seqno being retired doesn't match the oldest in the | 1755 | /* If the seqno being retired doesn't match the oldest in the |
1710 | * list, then the oldest in the list must still be newer than | 1756 | * list, then the oldest in the list must still be newer than |
@@ -1752,7 +1798,10 @@ i915_get_gem_seqno(struct drm_device *dev) | |||
1752 | { | 1798 | { |
1753 | drm_i915_private_t *dev_priv = dev->dev_private; | 1799 | drm_i915_private_t *dev_priv = dev->dev_private; |
1754 | 1800 | ||
1755 | return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); | 1801 | if (HAS_PIPE_CONTROL(dev)) |
1802 | return ((volatile u32 *)(dev_priv->seqno_page))[0]; | ||
1803 | else | ||
1804 | return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); | ||
1756 | } | 1805 | } |
1757 | 1806 | ||
1758 | /** | 1807 | /** |
@@ -2075,7 +2124,7 @@ i915_gem_find_inactive_object(struct drm_device *dev, int min_size) | |||
2075 | 2124 | ||
2076 | /* Try to find the smallest clean object */ | 2125 | /* Try to find the smallest clean object */ |
2077 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | 2126 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { |
2078 | struct drm_gem_object *obj = obj_priv->obj; | 2127 | struct drm_gem_object *obj = &obj_priv->base; |
2079 | if (obj->size >= min_size) { | 2128 | if (obj->size >= min_size) { |
2080 | if ((!obj_priv->dirty || | 2129 | if ((!obj_priv->dirty || |
2081 | i915_gem_object_is_purgeable(obj_priv)) && | 2130 | i915_gem_object_is_purgeable(obj_priv)) && |
@@ -2209,7 +2258,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) | |||
2209 | 2258 | ||
2210 | /* Find an object that we can immediately reuse */ | 2259 | /* Find an object that we can immediately reuse */ |
2211 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | 2260 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { |
2212 | obj = obj_priv->obj; | 2261 | obj = &obj_priv->base; |
2213 | if (obj->size >= min_size) | 2262 | if (obj->size >= min_size) |
2214 | break; | 2263 | break; |
2215 | 2264 | ||
@@ -2362,6 +2411,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2362 | pitch_val = obj_priv->stride / tile_width; | 2411 | pitch_val = obj_priv->stride / tile_width; |
2363 | pitch_val = ffs(pitch_val) - 1; | 2412 | pitch_val = ffs(pitch_val) - 1; |
2364 | 2413 | ||
2414 | if (obj_priv->tiling_mode == I915_TILING_Y && | ||
2415 | HAS_128_BYTE_Y_TILING(dev)) | ||
2416 | WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); | ||
2417 | else | ||
2418 | WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); | ||
2419 | |||
2365 | val = obj_priv->gtt_offset; | 2420 | val = obj_priv->gtt_offset; |
2366 | if (obj_priv->tiling_mode == I915_TILING_Y) | 2421 | if (obj_priv->tiling_mode == I915_TILING_Y) |
2367 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | 2422 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; |
@@ -2435,9 +2490,10 @@ static int i915_find_fence_reg(struct drm_device *dev) | |||
2435 | 2490 | ||
2436 | /* None available, try to steal one or wait for a user to finish */ | 2491 | /* None available, try to steal one or wait for a user to finish */ |
2437 | i = I915_FENCE_REG_NONE; | 2492 | i = I915_FENCE_REG_NONE; |
2438 | list_for_each_entry(obj_priv, &dev_priv->mm.fence_list, | 2493 | list_for_each_entry(reg, &dev_priv->mm.fence_list, |
2439 | fence_list) { | 2494 | lru_list) { |
2440 | obj = obj_priv->obj; | 2495 | obj = reg->obj; |
2496 | obj_priv = to_intel_bo(obj); | ||
2441 | 2497 | ||
2442 | if (obj_priv->pin_count) | 2498 | if (obj_priv->pin_count) |
2443 | continue; | 2499 | continue; |
@@ -2486,7 +2542,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2486 | 2542 | ||
2487 | /* Just update our place in the LRU if our fence is getting used. */ | 2543 | /* Just update our place in the LRU if our fence is getting used. */ |
2488 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | 2544 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
2489 | list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | 2545 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; |
2546 | list_move_tail(®->lru_list, &dev_priv->mm.fence_list); | ||
2490 | return 0; | 2547 | return 0; |
2491 | } | 2548 | } |
2492 | 2549 | ||
@@ -2516,7 +2573,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2516 | 2573 | ||
2517 | obj_priv->fence_reg = ret; | 2574 | obj_priv->fence_reg = ret; |
2518 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; | 2575 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; |
2519 | list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | 2576 | list_add_tail(®->lru_list, &dev_priv->mm.fence_list); |
2520 | 2577 | ||
2521 | reg->obj = obj; | 2578 | reg->obj = obj; |
2522 | 2579 | ||
@@ -2548,6 +2605,8 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2548 | struct drm_device *dev = obj->dev; | 2605 | struct drm_device *dev = obj->dev; |
2549 | drm_i915_private_t *dev_priv = dev->dev_private; | 2606 | drm_i915_private_t *dev_priv = dev->dev_private; |
2550 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2607 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2608 | struct drm_i915_fence_reg *reg = | ||
2609 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
2551 | 2610 | ||
2552 | if (IS_GEN6(dev)) { | 2611 | if (IS_GEN6(dev)) { |
2553 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + | 2612 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + |
@@ -2566,9 +2625,9 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2566 | I915_WRITE(fence_reg, 0); | 2625 | I915_WRITE(fence_reg, 0); |
2567 | } | 2626 | } |
2568 | 2627 | ||
2569 | dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; | 2628 | reg->obj = NULL; |
2570 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2629 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2571 | list_del_init(&obj_priv->fence_list); | 2630 | list_del_init(®->lru_list); |
2572 | } | 2631 | } |
2573 | 2632 | ||
2574 | /** | 2633 | /** |
@@ -4421,34 +4480,38 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | |||
4421 | return 0; | 4480 | return 0; |
4422 | } | 4481 | } |
4423 | 4482 | ||
4424 | int i915_gem_init_object(struct drm_gem_object *obj) | 4483 | struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, |
4484 | size_t size) | ||
4425 | { | 4485 | { |
4426 | struct drm_i915_gem_object *obj_priv; | 4486 | struct drm_i915_gem_object *obj; |
4427 | 4487 | ||
4428 | obj_priv = kzalloc(sizeof(*obj_priv), GFP_KERNEL); | 4488 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); |
4429 | if (obj_priv == NULL) | 4489 | if (obj == NULL) |
4430 | return -ENOMEM; | 4490 | return NULL; |
4431 | 4491 | ||
4432 | /* | 4492 | if (drm_gem_object_init(dev, &obj->base, size) != 0) { |
4433 | * We've just allocated pages from the kernel, | 4493 | kfree(obj); |
4434 | * so they've just been written by the CPU with | 4494 | return NULL; |
4435 | * zeros. They'll need to be clflushed before we | 4495 | } |
4436 | * use them with the GPU. | ||
4437 | */ | ||
4438 | obj->write_domain = I915_GEM_DOMAIN_CPU; | ||
4439 | obj->read_domains = I915_GEM_DOMAIN_CPU; | ||
4440 | 4496 | ||
4441 | obj_priv->agp_type = AGP_USER_MEMORY; | 4497 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
4498 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | ||
4442 | 4499 | ||
4443 | obj->driver_private = obj_priv; | 4500 | obj->agp_type = AGP_USER_MEMORY; |
4444 | obj_priv->obj = obj; | 4501 | obj->base.driver_private = NULL; |
4445 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 4502 | obj->fence_reg = I915_FENCE_REG_NONE; |
4446 | INIT_LIST_HEAD(&obj_priv->list); | 4503 | INIT_LIST_HEAD(&obj->list); |
4447 | INIT_LIST_HEAD(&obj_priv->gpu_write_list); | 4504 | INIT_LIST_HEAD(&obj->gpu_write_list); |
4448 | INIT_LIST_HEAD(&obj_priv->fence_list); | 4505 | obj->madv = I915_MADV_WILLNEED; |
4449 | obj_priv->madv = I915_MADV_WILLNEED; | 4506 | |
4507 | trace_i915_gem_object_create(&obj->base); | ||
4450 | 4508 | ||
4451 | trace_i915_gem_object_create(obj); | 4509 | return &obj->base; |
4510 | } | ||
4511 | |||
4512 | int i915_gem_init_object(struct drm_gem_object *obj) | ||
4513 | { | ||
4514 | BUG(); | ||
4452 | 4515 | ||
4453 | return 0; | 4516 | return 0; |
4454 | } | 4517 | } |
@@ -4471,9 +4534,11 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
4471 | if (obj_priv->mmap_offset) | 4534 | if (obj_priv->mmap_offset) |
4472 | i915_gem_free_mmap_offset(obj); | 4535 | i915_gem_free_mmap_offset(obj); |
4473 | 4536 | ||
4537 | drm_gem_object_release(obj); | ||
4538 | |||
4474 | kfree(obj_priv->page_cpu_valid); | 4539 | kfree(obj_priv->page_cpu_valid); |
4475 | kfree(obj_priv->bit_17); | 4540 | kfree(obj_priv->bit_17); |
4476 | kfree(obj->driver_private); | 4541 | kfree(obj_priv); |
4477 | } | 4542 | } |
4478 | 4543 | ||
4479 | /** Unbinds all inactive objects. */ | 4544 | /** Unbinds all inactive objects. */ |
@@ -4486,9 +4551,9 @@ i915_gem_evict_from_inactive_list(struct drm_device *dev) | |||
4486 | struct drm_gem_object *obj; | 4551 | struct drm_gem_object *obj; |
4487 | int ret; | 4552 | int ret; |
4488 | 4553 | ||
4489 | obj = list_first_entry(&dev_priv->mm.inactive_list, | 4554 | obj = &list_first_entry(&dev_priv->mm.inactive_list, |
4490 | struct drm_i915_gem_object, | 4555 | struct drm_i915_gem_object, |
4491 | list)->obj; | 4556 | list)->base; |
4492 | 4557 | ||
4493 | ret = i915_gem_object_unbind(obj); | 4558 | ret = i915_gem_object_unbind(obj); |
4494 | if (ret != 0) { | 4559 | if (ret != 0) { |
@@ -4546,6 +4611,49 @@ i915_gem_idle(struct drm_device *dev) | |||
4546 | return 0; | 4611 | return 0; |
4547 | } | 4612 | } |
4548 | 4613 | ||
4614 | /* | ||
4615 | * 965+ support PIPE_CONTROL commands, which provide finer grained control | ||
4616 | * over cache flushing. | ||
4617 | */ | ||
4618 | static int | ||
4619 | i915_gem_init_pipe_control(struct drm_device *dev) | ||
4620 | { | ||
4621 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4622 | struct drm_gem_object *obj; | ||
4623 | struct drm_i915_gem_object *obj_priv; | ||
4624 | int ret; | ||
4625 | |||
4626 | obj = i915_gem_alloc_object(dev, 4096); | ||
4627 | if (obj == NULL) { | ||
4628 | DRM_ERROR("Failed to allocate seqno page\n"); | ||
4629 | ret = -ENOMEM; | ||
4630 | goto err; | ||
4631 | } | ||
4632 | obj_priv = to_intel_bo(obj); | ||
4633 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | ||
4634 | |||
4635 | ret = i915_gem_object_pin(obj, 4096); | ||
4636 | if (ret) | ||
4637 | goto err_unref; | ||
4638 | |||
4639 | dev_priv->seqno_gfx_addr = obj_priv->gtt_offset; | ||
4640 | dev_priv->seqno_page = kmap(obj_priv->pages[0]); | ||
4641 | if (dev_priv->seqno_page == NULL) | ||
4642 | goto err_unpin; | ||
4643 | |||
4644 | dev_priv->seqno_obj = obj; | ||
4645 | memset(dev_priv->seqno_page, 0, PAGE_SIZE); | ||
4646 | |||
4647 | return 0; | ||
4648 | |||
4649 | err_unpin: | ||
4650 | i915_gem_object_unpin(obj); | ||
4651 | err_unref: | ||
4652 | drm_gem_object_unreference(obj); | ||
4653 | err: | ||
4654 | return ret; | ||
4655 | } | ||
4656 | |||
4549 | static int | 4657 | static int |
4550 | i915_gem_init_hws(struct drm_device *dev) | 4658 | i915_gem_init_hws(struct drm_device *dev) |
4551 | { | 4659 | { |
@@ -4560,10 +4668,11 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4560 | if (!I915_NEED_GFX_HWS(dev)) | 4668 | if (!I915_NEED_GFX_HWS(dev)) |
4561 | return 0; | 4669 | return 0; |
4562 | 4670 | ||
4563 | obj = drm_gem_object_alloc(dev, 4096); | 4671 | obj = i915_gem_alloc_object(dev, 4096); |
4564 | if (obj == NULL) { | 4672 | if (obj == NULL) { |
4565 | DRM_ERROR("Failed to allocate status page\n"); | 4673 | DRM_ERROR("Failed to allocate status page\n"); |
4566 | return -ENOMEM; | 4674 | ret = -ENOMEM; |
4675 | goto err; | ||
4567 | } | 4676 | } |
4568 | obj_priv = to_intel_bo(obj); | 4677 | obj_priv = to_intel_bo(obj); |
4569 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | 4678 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; |
@@ -4571,7 +4680,7 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4571 | ret = i915_gem_object_pin(obj, 4096); | 4680 | ret = i915_gem_object_pin(obj, 4096); |
4572 | if (ret != 0) { | 4681 | if (ret != 0) { |
4573 | drm_gem_object_unreference(obj); | 4682 | drm_gem_object_unreference(obj); |
4574 | return ret; | 4683 | goto err_unref; |
4575 | } | 4684 | } |
4576 | 4685 | ||
4577 | dev_priv->status_gfx_addr = obj_priv->gtt_offset; | 4686 | dev_priv->status_gfx_addr = obj_priv->gtt_offset; |
@@ -4580,10 +4689,16 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4580 | if (dev_priv->hw_status_page == NULL) { | 4689 | if (dev_priv->hw_status_page == NULL) { |
4581 | DRM_ERROR("Failed to map status page.\n"); | 4690 | DRM_ERROR("Failed to map status page.\n"); |
4582 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | 4691 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); |
4583 | i915_gem_object_unpin(obj); | 4692 | ret = -EINVAL; |
4584 | drm_gem_object_unreference(obj); | 4693 | goto err_unpin; |
4585 | return -EINVAL; | ||
4586 | } | 4694 | } |
4695 | |||
4696 | if (HAS_PIPE_CONTROL(dev)) { | ||
4697 | ret = i915_gem_init_pipe_control(dev); | ||
4698 | if (ret) | ||
4699 | goto err_unpin; | ||
4700 | } | ||
4701 | |||
4587 | dev_priv->hws_obj = obj; | 4702 | dev_priv->hws_obj = obj; |
4588 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | 4703 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); |
4589 | if (IS_GEN6(dev)) { | 4704 | if (IS_GEN6(dev)) { |
@@ -4596,6 +4711,30 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4596 | DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); | 4711 | DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); |
4597 | 4712 | ||
4598 | return 0; | 4713 | return 0; |
4714 | |||
4715 | err_unpin: | ||
4716 | i915_gem_object_unpin(obj); | ||
4717 | err_unref: | ||
4718 | drm_gem_object_unreference(obj); | ||
4719 | err: | ||
4720 | return 0; | ||
4721 | } | ||
4722 | |||
4723 | static void | ||
4724 | i915_gem_cleanup_pipe_control(struct drm_device *dev) | ||
4725 | { | ||
4726 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4727 | struct drm_gem_object *obj; | ||
4728 | struct drm_i915_gem_object *obj_priv; | ||
4729 | |||
4730 | obj = dev_priv->seqno_obj; | ||
4731 | obj_priv = to_intel_bo(obj); | ||
4732 | kunmap(obj_priv->pages[0]); | ||
4733 | i915_gem_object_unpin(obj); | ||
4734 | drm_gem_object_unreference(obj); | ||
4735 | dev_priv->seqno_obj = NULL; | ||
4736 | |||
4737 | dev_priv->seqno_page = NULL; | ||
4599 | } | 4738 | } |
4600 | 4739 | ||
4601 | static void | 4740 | static void |
@@ -4619,6 +4758,9 @@ i915_gem_cleanup_hws(struct drm_device *dev) | |||
4619 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | 4758 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); |
4620 | dev_priv->hw_status_page = NULL; | 4759 | dev_priv->hw_status_page = NULL; |
4621 | 4760 | ||
4761 | if (HAS_PIPE_CONTROL(dev)) | ||
4762 | i915_gem_cleanup_pipe_control(dev); | ||
4763 | |||
4622 | /* Write high address into HWS_PGA when disabling. */ | 4764 | /* Write high address into HWS_PGA when disabling. */ |
4623 | I915_WRITE(HWS_PGA, 0x1ffff000); | 4765 | I915_WRITE(HWS_PGA, 0x1ffff000); |
4624 | } | 4766 | } |
@@ -4637,7 +4779,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
4637 | if (ret != 0) | 4779 | if (ret != 0) |
4638 | return ret; | 4780 | return ret; |
4639 | 4781 | ||
4640 | obj = drm_gem_object_alloc(dev, 128 * 1024); | 4782 | obj = i915_gem_alloc_object(dev, 128 * 1024); |
4641 | if (obj == NULL) { | 4783 | if (obj == NULL) { |
4642 | DRM_ERROR("Failed to allocate ringbuffer\n"); | 4784 | DRM_ERROR("Failed to allocate ringbuffer\n"); |
4643 | i915_gem_cleanup_hws(dev); | 4785 | i915_gem_cleanup_hws(dev); |
@@ -4830,6 +4972,8 @@ i915_gem_load(struct drm_device *dev) | |||
4830 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4972 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
4831 | INIT_LIST_HEAD(&dev_priv->mm.request_list); | 4973 | INIT_LIST_HEAD(&dev_priv->mm.request_list); |
4832 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | 4974 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
4975 | for (i = 0; i < 16; i++) | ||
4976 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); | ||
4833 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 4977 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
4834 | i915_gem_retire_work_handler); | 4978 | i915_gem_retire_work_handler); |
4835 | dev_priv->mm.next_gem_seqno = 1; | 4979 | dev_priv->mm.next_gem_seqno = 1; |
@@ -5058,6 +5202,20 @@ void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv) | |||
5058 | } | 5202 | } |
5059 | 5203 | ||
5060 | static int | 5204 | static int |
5205 | i915_gpu_is_active(struct drm_device *dev) | ||
5206 | { | ||
5207 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
5208 | int lists_empty; | ||
5209 | |||
5210 | spin_lock(&dev_priv->mm.active_list_lock); | ||
5211 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && | ||
5212 | list_empty(&dev_priv->mm.active_list); | ||
5213 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
5214 | |||
5215 | return !lists_empty; | ||
5216 | } | ||
5217 | |||
5218 | static int | ||
5061 | i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) | 5219 | i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) |
5062 | { | 5220 | { |
5063 | drm_i915_private_t *dev_priv, *next_dev; | 5221 | drm_i915_private_t *dev_priv, *next_dev; |
@@ -5086,6 +5244,7 @@ i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
5086 | 5244 | ||
5087 | spin_lock(&shrink_list_lock); | 5245 | spin_lock(&shrink_list_lock); |
5088 | 5246 | ||
5247 | rescan: | ||
5089 | /* first scan for clean buffers */ | 5248 | /* first scan for clean buffers */ |
5090 | list_for_each_entry_safe(dev_priv, next_dev, | 5249 | list_for_each_entry_safe(dev_priv, next_dev, |
5091 | &shrink_list, mm.shrink_list) { | 5250 | &shrink_list, mm.shrink_list) { |
@@ -5102,7 +5261,7 @@ i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
5102 | &dev_priv->mm.inactive_list, | 5261 | &dev_priv->mm.inactive_list, |
5103 | list) { | 5262 | list) { |
5104 | if (i915_gem_object_is_purgeable(obj_priv)) { | 5263 | if (i915_gem_object_is_purgeable(obj_priv)) { |
5105 | i915_gem_object_unbind(obj_priv->obj); | 5264 | i915_gem_object_unbind(&obj_priv->base); |
5106 | if (--nr_to_scan <= 0) | 5265 | if (--nr_to_scan <= 0) |
5107 | break; | 5266 | break; |
5108 | } | 5267 | } |
@@ -5131,7 +5290,7 @@ i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
5131 | &dev_priv->mm.inactive_list, | 5290 | &dev_priv->mm.inactive_list, |
5132 | list) { | 5291 | list) { |
5133 | if (nr_to_scan > 0) { | 5292 | if (nr_to_scan > 0) { |
5134 | i915_gem_object_unbind(obj_priv->obj); | 5293 | i915_gem_object_unbind(&obj_priv->base); |
5135 | nr_to_scan--; | 5294 | nr_to_scan--; |
5136 | } else | 5295 | } else |
5137 | cnt++; | 5296 | cnt++; |
@@ -5143,6 +5302,36 @@ i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
5143 | would_deadlock = 0; | 5302 | would_deadlock = 0; |
5144 | } | 5303 | } |
5145 | 5304 | ||
5305 | if (nr_to_scan) { | ||
5306 | int active = 0; | ||
5307 | |||
5308 | /* | ||
5309 | * We are desperate for pages, so as a last resort, wait | ||
5310 | * for the GPU to finish and discard whatever we can. | ||
5311 | * This has a dramatic impact to reduce the number of | ||
5312 | * OOM-killer events whilst running the GPU aggressively. | ||
5313 | */ | ||
5314 | list_for_each_entry(dev_priv, &shrink_list, mm.shrink_list) { | ||
5315 | struct drm_device *dev = dev_priv->dev; | ||
5316 | |||
5317 | if (!mutex_trylock(&dev->struct_mutex)) | ||
5318 | continue; | ||
5319 | |||
5320 | spin_unlock(&shrink_list_lock); | ||
5321 | |||
5322 | if (i915_gpu_is_active(dev)) { | ||
5323 | i915_gpu_idle(dev); | ||
5324 | active++; | ||
5325 | } | ||
5326 | |||
5327 | spin_lock(&shrink_list_lock); | ||
5328 | mutex_unlock(&dev->struct_mutex); | ||
5329 | } | ||
5330 | |||
5331 | if (active) | ||
5332 | goto rescan; | ||
5333 | } | ||
5334 | |||
5146 | spin_unlock(&shrink_list_lock); | 5335 | spin_unlock(&shrink_list_lock); |
5147 | 5336 | ||
5148 | if (would_deadlock) | 5337 | if (would_deadlock) |
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index 35507cf53fa3..80f380b1d951 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c | |||
@@ -39,7 +39,7 @@ i915_verify_inactive(struct drm_device *dev, char *file, int line) | |||
39 | struct drm_i915_gem_object *obj_priv; | 39 | struct drm_i915_gem_object *obj_priv; |
40 | 40 | ||
41 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | 41 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { |
42 | obj = obj_priv->obj; | 42 | obj = &obj_priv->base; |
43 | if (obj_priv->pin_count || obj_priv->active || | 43 | if (obj_priv->pin_count || obj_priv->active || |
44 | (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | | 44 | (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | |
45 | I915_GEM_DOMAIN_GTT))) | 45 | I915_GEM_DOMAIN_GTT))) |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 449157f71610..4b7c49d4257d 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -202,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | |||
202 | * reg, so dont bother to check the size */ | 202 | * reg, so dont bother to check the size */ |
203 | if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) | 203 | if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) |
204 | return false; | 204 | return false; |
205 | } else if (IS_I9XX(dev)) { | 205 | } else if (IS_GEN3(dev) || IS_GEN2(dev)) { |
206 | uint32_t pitch_val = ffs(stride / tile_width) - 1; | 206 | if (stride > 8192) |
207 | |||
208 | /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB) | ||
209 | * instead of 4 (2KB) on 945s. | ||
210 | */ | ||
211 | if (pitch_val > I915_FENCE_MAX_PITCH_VAL || | ||
212 | size > (I830_FENCE_MAX_SIZE_VAL << 20)) | ||
213 | return false; | 207 | return false; |
214 | } else { | ||
215 | uint32_t pitch_val = ffs(stride / tile_width) - 1; | ||
216 | 208 | ||
217 | if (pitch_val > I830_FENCE_MAX_PITCH_VAL || | 209 | if (IS_GEN3(dev)) { |
218 | size > (I830_FENCE_MAX_SIZE_VAL << 19)) | 210 | if (size > I830_FENCE_MAX_SIZE_VAL << 20) |
219 | return false; | 211 | return false; |
212 | } else { | ||
213 | if (size > I830_FENCE_MAX_SIZE_VAL << 19) | ||
214 | return false; | ||
215 | } | ||
220 | } | 216 | } |
221 | 217 | ||
222 | /* 965+ just needs multiples of tile width */ | 218 | /* 965+ just needs multiples of tile width */ |
@@ -287,6 +283,11 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
287 | return -EINVAL; | 283 | return -EINVAL; |
288 | } | 284 | } |
289 | 285 | ||
286 | if (obj_priv->pin_count) { | ||
287 | drm_gem_object_unreference_unlocked(obj); | ||
288 | return -EBUSY; | ||
289 | } | ||
290 | |||
290 | if (args->tiling_mode == I915_TILING_NONE) { | 291 | if (args->tiling_mode == I915_TILING_NONE) { |
291 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; | 292 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; |
292 | args->stride = 0; | 293 | args->stride = 0; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6421481d6222..8c3f0802686d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -169,9 +169,13 @@ void intel_enable_asle (struct drm_device *dev) | |||
169 | 169 | ||
170 | if (HAS_PCH_SPLIT(dev)) | 170 | if (HAS_PCH_SPLIT(dev)) |
171 | ironlake_enable_display_irq(dev_priv, DE_GSE); | 171 | ironlake_enable_display_irq(dev_priv, DE_GSE); |
172 | else | 172 | else { |
173 | i915_enable_pipestat(dev_priv, 1, | 173 | i915_enable_pipestat(dev_priv, 1, |
174 | I915_LEGACY_BLC_EVENT_ENABLE); | 174 | I915_LEGACY_BLC_EVENT_ENABLE); |
175 | if (IS_I965G(dev)) | ||
176 | i915_enable_pipestat(dev_priv, 0, | ||
177 | I915_LEGACY_BLC_EVENT_ENABLE); | ||
178 | } | ||
175 | } | 179 | } |
176 | 180 | ||
177 | /** | 181 | /** |
@@ -256,18 +260,18 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
256 | hotplug_work); | 260 | hotplug_work); |
257 | struct drm_device *dev = dev_priv->dev; | 261 | struct drm_device *dev = dev_priv->dev; |
258 | struct drm_mode_config *mode_config = &dev->mode_config; | 262 | struct drm_mode_config *mode_config = &dev->mode_config; |
259 | struct drm_connector *connector; | 263 | struct drm_encoder *encoder; |
260 | 264 | ||
261 | if (mode_config->num_connector) { | 265 | if (mode_config->num_encoder) { |
262 | list_for_each_entry(connector, &mode_config->connector_list, head) { | 266 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
263 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 267 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
264 | 268 | ||
265 | if (intel_encoder->hot_plug) | 269 | if (intel_encoder->hot_plug) |
266 | (*intel_encoder->hot_plug) (intel_encoder); | 270 | (*intel_encoder->hot_plug) (intel_encoder); |
267 | } | 271 | } |
268 | } | 272 | } |
269 | /* Just fire off a uevent and let userspace tell us what to do */ | 273 | /* Just fire off a uevent and let userspace tell us what to do */ |
270 | drm_sysfs_hotplug_event(dev); | 274 | drm_helper_hpd_irq_event(dev); |
271 | } | 275 | } |
272 | 276 | ||
273 | static void i915_handle_rps_change(struct drm_device *dev) | 277 | static void i915_handle_rps_change(struct drm_device *dev) |
@@ -349,7 +353,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
349 | READ_BREADCRUMB(dev_priv); | 353 | READ_BREADCRUMB(dev_priv); |
350 | } | 354 | } |
351 | 355 | ||
352 | if (gt_iir & GT_USER_INTERRUPT) { | 356 | if (gt_iir & GT_PIPE_NOTIFY) { |
353 | u32 seqno = i915_get_gem_seqno(dev); | 357 | u32 seqno = i915_get_gem_seqno(dev); |
354 | dev_priv->mm.irq_gem_seqno = seqno; | 358 | dev_priv->mm.irq_gem_seqno = seqno; |
355 | trace_i915_gem_request_complete(dev, seqno); | 359 | trace_i915_gem_request_complete(dev, seqno); |
@@ -456,11 +460,15 @@ i915_error_object_create(struct drm_device *dev, | |||
456 | 460 | ||
457 | for (page = 0; page < page_count; page++) { | 461 | for (page = 0; page < page_count; page++) { |
458 | void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | 462 | void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); |
463 | unsigned long flags; | ||
464 | |||
459 | if (d == NULL) | 465 | if (d == NULL) |
460 | goto unwind; | 466 | goto unwind; |
461 | s = kmap_atomic(src_priv->pages[page], KM_USER0); | 467 | local_irq_save(flags); |
468 | s = kmap_atomic(src_priv->pages[page], KM_IRQ0); | ||
462 | memcpy(d, s, PAGE_SIZE); | 469 | memcpy(d, s, PAGE_SIZE); |
463 | kunmap_atomic(s, KM_USER0); | 470 | kunmap_atomic(s, KM_IRQ0); |
471 | local_irq_restore(flags); | ||
464 | dst->pages[page] = d; | 472 | dst->pages[page] = d; |
465 | } | 473 | } |
466 | dst->page_count = page_count; | 474 | dst->page_count = page_count; |
@@ -608,7 +616,7 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
608 | batchbuffer[1] = NULL; | 616 | batchbuffer[1] = NULL; |
609 | count = 0; | 617 | count = 0; |
610 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | 618 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { |
611 | struct drm_gem_object *obj = obj_priv->obj; | 619 | struct drm_gem_object *obj = &obj_priv->base; |
612 | 620 | ||
613 | if (batchbuffer[0] == NULL && | 621 | if (batchbuffer[0] == NULL && |
614 | bbaddr >= obj_priv->gtt_offset && | 622 | bbaddr >= obj_priv->gtt_offset && |
@@ -644,7 +652,7 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
644 | if (error->active_bo) { | 652 | if (error->active_bo) { |
645 | int i = 0; | 653 | int i = 0; |
646 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | 654 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { |
647 | struct drm_gem_object *obj = obj_priv->obj; | 655 | struct drm_gem_object *obj = &obj_priv->base; |
648 | 656 | ||
649 | error->active_bo[i].size = obj->size; | 657 | error->active_bo[i].size = obj->size; |
650 | error->active_bo[i].name = obj->name; | 658 | error->active_bo[i].name = obj->name; |
@@ -946,7 +954,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
946 | intel_finish_page_flip(dev, 1); | 954 | intel_finish_page_flip(dev, 1); |
947 | } | 955 | } |
948 | 956 | ||
949 | if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) || | 957 | if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || |
958 | (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) || | ||
950 | (iir & I915_ASLE_INTERRUPT)) | 959 | (iir & I915_ASLE_INTERRUPT)) |
951 | opregion_asle_intr(dev); | 960 | opregion_asle_intr(dev); |
952 | 961 | ||
@@ -1005,7 +1014,7 @@ void i915_user_irq_get(struct drm_device *dev) | |||
1005 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1014 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
1006 | if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { | 1015 | if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { |
1007 | if (HAS_PCH_SPLIT(dev)) | 1016 | if (HAS_PCH_SPLIT(dev)) |
1008 | ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); | 1017 | ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); |
1009 | else | 1018 | else |
1010 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | 1019 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); |
1011 | } | 1020 | } |
@@ -1021,7 +1030,7 @@ void i915_user_irq_put(struct drm_device *dev) | |||
1021 | BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); | 1030 | BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); |
1022 | if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { | 1031 | if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { |
1023 | if (HAS_PCH_SPLIT(dev)) | 1032 | if (HAS_PCH_SPLIT(dev)) |
1024 | ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT); | 1033 | ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); |
1025 | else | 1034 | else |
1026 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | 1035 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); |
1027 | } | 1036 | } |
@@ -1305,7 +1314,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1305 | /* enable kind of interrupts always enabled */ | 1314 | /* enable kind of interrupts always enabled */ |
1306 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | | 1315 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
1307 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; | 1316 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; |
1308 | u32 render_mask = GT_USER_INTERRUPT; | 1317 | u32 render_mask = GT_PIPE_NOTIFY; |
1309 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | | 1318 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | |
1310 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; | 1319 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; |
1311 | 1320 | ||
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index 7cc8410239cb..8fcc75c1aa28 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
@@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev) | |||
382 | struct drm_i915_private *dev_priv = dev->dev_private; | 382 | struct drm_i915_private *dev_priv = dev->dev_private; |
383 | struct intel_opregion *opregion = &dev_priv->opregion; | 383 | struct intel_opregion *opregion = &dev_priv->opregion; |
384 | struct drm_connector *connector; | 384 | struct drm_connector *connector; |
385 | acpi_handle handle; | ||
386 | struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; | ||
387 | unsigned long long device_id; | ||
388 | acpi_status status; | ||
385 | int i = 0; | 389 | int i = 0; |
386 | 390 | ||
391 | handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); | ||
392 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) | ||
393 | return; | ||
394 | |||
395 | if (acpi_is_video_device(acpi_dev)) | ||
396 | acpi_video_bus = acpi_dev; | ||
397 | else { | ||
398 | list_for_each_entry(acpi_cdev, &acpi_dev->children, node) { | ||
399 | if (acpi_is_video_device(acpi_cdev)) { | ||
400 | acpi_video_bus = acpi_cdev; | ||
401 | break; | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | |||
406 | if (!acpi_video_bus) { | ||
407 | printk(KERN_WARNING "No ACPI video bus found\n"); | ||
408 | return; | ||
409 | } | ||
410 | |||
411 | list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { | ||
412 | if (i >= 8) { | ||
413 | dev_printk (KERN_ERR, &dev->pdev->dev, | ||
414 | "More than 8 outputs detected\n"); | ||
415 | return; | ||
416 | } | ||
417 | status = | ||
418 | acpi_evaluate_integer(acpi_cdev->handle, "_ADR", | ||
419 | NULL, &device_id); | ||
420 | if (ACPI_SUCCESS(status)) { | ||
421 | if (!device_id) | ||
422 | goto blind_set; | ||
423 | opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f); | ||
424 | i++; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | end: | ||
429 | /* If fewer than 8 outputs, the list must be null terminated */ | ||
430 | if (i < 8) | ||
431 | opregion->acpi->didl[i] = 0; | ||
432 | return; | ||
433 | |||
434 | blind_set: | ||
435 | i = 0; | ||
387 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 436 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
388 | int output_type = ACPI_OTHER_OUTPUT; | 437 | int output_type = ACPI_OTHER_OUTPUT; |
389 | if (i >= 8) { | 438 | if (i >= 8) { |
@@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev) | |||
416 | opregion->acpi->didl[i] |= (1<<31) | output_type | i; | 465 | opregion->acpi->didl[i] |= (1<<31) | output_type | i; |
417 | i++; | 466 | i++; |
418 | } | 467 | } |
419 | 468 | goto end; | |
420 | /* If fewer than 8 outputs, the list must be null terminated */ | ||
421 | if (i < 8) | ||
422 | opregion->acpi->didl[i] = 0; | ||
423 | } | 469 | } |
424 | 470 | ||
425 | int intel_opregion_init(struct drm_device *dev, int resume) | 471 | int intel_opregion_init(struct drm_device *dev, int resume) |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cbbf59f56dfa..f3e39cc46f0d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -230,6 +230,16 @@ | |||
230 | #define ASYNC_FLIP (1<<22) | 230 | #define ASYNC_FLIP (1<<22) |
231 | #define DISPLAY_PLANE_A (0<<20) | 231 | #define DISPLAY_PLANE_A (0<<20) |
232 | #define DISPLAY_PLANE_B (1<<20) | 232 | #define DISPLAY_PLANE_B (1<<20) |
233 | #define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2) | ||
234 | #define PIPE_CONTROL_QW_WRITE (1<<14) | ||
235 | #define PIPE_CONTROL_DEPTH_STALL (1<<13) | ||
236 | #define PIPE_CONTROL_WC_FLUSH (1<<12) | ||
237 | #define PIPE_CONTROL_IS_FLUSH (1<<11) /* MBZ on Ironlake */ | ||
238 | #define PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */ | ||
239 | #define PIPE_CONTROL_ISP_DIS (1<<9) | ||
240 | #define PIPE_CONTROL_NOTIFY (1<<8) | ||
241 | #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ | ||
242 | #define PIPE_CONTROL_STALL_EN (1<<1) /* in addr word, Ironlake+ only */ | ||
233 | 243 | ||
234 | /* | 244 | /* |
235 | * Fence registers | 245 | * Fence registers |
@@ -241,7 +251,7 @@ | |||
241 | #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) | 251 | #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) |
242 | #define I830_FENCE_PITCH_SHIFT 4 | 252 | #define I830_FENCE_PITCH_SHIFT 4 |
243 | #define I830_FENCE_REG_VALID (1<<0) | 253 | #define I830_FENCE_REG_VALID (1<<0) |
244 | #define I915_FENCE_MAX_PITCH_VAL 0x10 | 254 | #define I915_FENCE_MAX_PITCH_VAL 4 |
245 | #define I830_FENCE_MAX_PITCH_VAL 6 | 255 | #define I830_FENCE_MAX_PITCH_VAL 6 |
246 | #define I830_FENCE_MAX_SIZE_VAL (1<<8) | 256 | #define I830_FENCE_MAX_SIZE_VAL (1<<8) |
247 | 257 | ||
@@ -1754,6 +1764,14 @@ | |||
1754 | #define DP_LINK_TRAIN_MASK (3 << 28) | 1764 | #define DP_LINK_TRAIN_MASK (3 << 28) |
1755 | #define DP_LINK_TRAIN_SHIFT 28 | 1765 | #define DP_LINK_TRAIN_SHIFT 28 |
1756 | 1766 | ||
1767 | /* CPT Link training mode */ | ||
1768 | #define DP_LINK_TRAIN_PAT_1_CPT (0 << 8) | ||
1769 | #define DP_LINK_TRAIN_PAT_2_CPT (1 << 8) | ||
1770 | #define DP_LINK_TRAIN_PAT_IDLE_CPT (2 << 8) | ||
1771 | #define DP_LINK_TRAIN_OFF_CPT (3 << 8) | ||
1772 | #define DP_LINK_TRAIN_MASK_CPT (7 << 8) | ||
1773 | #define DP_LINK_TRAIN_SHIFT_CPT 8 | ||
1774 | |||
1757 | /* Signal voltages. These are mostly controlled by the other end */ | 1775 | /* Signal voltages. These are mostly controlled by the other end */ |
1758 | #define DP_VOLTAGE_0_4 (0 << 25) | 1776 | #define DP_VOLTAGE_0_4 (0 << 25) |
1759 | #define DP_VOLTAGE_0_6 (1 << 25) | 1777 | #define DP_VOLTAGE_0_6 (1 << 25) |
@@ -1914,7 +1932,10 @@ | |||
1914 | /* Display & cursor control */ | 1932 | /* Display & cursor control */ |
1915 | 1933 | ||
1916 | /* dithering flag on Ironlake */ | 1934 | /* dithering flag on Ironlake */ |
1917 | #define PIPE_ENABLE_DITHER (1 << 4) | 1935 | #define PIPE_ENABLE_DITHER (1 << 4) |
1936 | #define PIPE_DITHER_TYPE_MASK (3 << 2) | ||
1937 | #define PIPE_DITHER_TYPE_SPATIAL (0 << 2) | ||
1938 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) | ||
1918 | /* Pipe A */ | 1939 | /* Pipe A */ |
1919 | #define PIPEADSL 0x70000 | 1940 | #define PIPEADSL 0x70000 |
1920 | #define PIPEACONF 0x70008 | 1941 | #define PIPEACONF 0x70008 |
@@ -1978,15 +1999,24 @@ | |||
1978 | 1999 | ||
1979 | #define DSPFW1 0x70034 | 2000 | #define DSPFW1 0x70034 |
1980 | #define DSPFW_SR_SHIFT 23 | 2001 | #define DSPFW_SR_SHIFT 23 |
2002 | #define DSPFW_SR_MASK (0x1ff<<23) | ||
1981 | #define DSPFW_CURSORB_SHIFT 16 | 2003 | #define DSPFW_CURSORB_SHIFT 16 |
2004 | #define DSPFW_CURSORB_MASK (0x3f<<16) | ||
1982 | #define DSPFW_PLANEB_SHIFT 8 | 2005 | #define DSPFW_PLANEB_SHIFT 8 |
2006 | #define DSPFW_PLANEB_MASK (0x7f<<8) | ||
2007 | #define DSPFW_PLANEA_MASK (0x7f) | ||
1983 | #define DSPFW2 0x70038 | 2008 | #define DSPFW2 0x70038 |
1984 | #define DSPFW_CURSORA_MASK 0x00003f00 | 2009 | #define DSPFW_CURSORA_MASK 0x00003f00 |
1985 | #define DSPFW_CURSORA_SHIFT 8 | 2010 | #define DSPFW_CURSORA_SHIFT 8 |
2011 | #define DSPFW_PLANEC_MASK (0x7f) | ||
1986 | #define DSPFW3 0x7003c | 2012 | #define DSPFW3 0x7003c |
1987 | #define DSPFW_HPLL_SR_EN (1<<31) | 2013 | #define DSPFW_HPLL_SR_EN (1<<31) |
1988 | #define DSPFW_CURSOR_SR_SHIFT 24 | 2014 | #define DSPFW_CURSOR_SR_SHIFT 24 |
1989 | #define PINEVIEW_SELF_REFRESH_EN (1<<30) | 2015 | #define PINEVIEW_SELF_REFRESH_EN (1<<30) |
2016 | #define DSPFW_CURSOR_SR_MASK (0x3f<<24) | ||
2017 | #define DSPFW_HPLL_CURSOR_SHIFT 16 | ||
2018 | #define DSPFW_HPLL_CURSOR_MASK (0x3f<<16) | ||
2019 | #define DSPFW_HPLL_SR_MASK (0x1ff) | ||
1990 | 2020 | ||
1991 | /* FIFO watermark sizes etc */ | 2021 | /* FIFO watermark sizes etc */ |
1992 | #define G4X_FIFO_LINE_SIZE 64 | 2022 | #define G4X_FIFO_LINE_SIZE 64 |
@@ -2013,6 +2043,43 @@ | |||
2013 | #define PINEVIEW_CURSOR_DFT_WM 0 | 2043 | #define PINEVIEW_CURSOR_DFT_WM 0 |
2014 | #define PINEVIEW_CURSOR_GUARD_WM 5 | 2044 | #define PINEVIEW_CURSOR_GUARD_WM 5 |
2015 | 2045 | ||
2046 | |||
2047 | /* define the Watermark register on Ironlake */ | ||
2048 | #define WM0_PIPEA_ILK 0x45100 | ||
2049 | #define WM0_PIPE_PLANE_MASK (0x7f<<16) | ||
2050 | #define WM0_PIPE_PLANE_SHIFT 16 | ||
2051 | #define WM0_PIPE_SPRITE_MASK (0x3f<<8) | ||
2052 | #define WM0_PIPE_SPRITE_SHIFT 8 | ||
2053 | #define WM0_PIPE_CURSOR_MASK (0x1f) | ||
2054 | |||
2055 | #define WM0_PIPEB_ILK 0x45104 | ||
2056 | #define WM1_LP_ILK 0x45108 | ||
2057 | #define WM1_LP_SR_EN (1<<31) | ||
2058 | #define WM1_LP_LATENCY_SHIFT 24 | ||
2059 | #define WM1_LP_LATENCY_MASK (0x7f<<24) | ||
2060 | #define WM1_LP_SR_MASK (0x1ff<<8) | ||
2061 | #define WM1_LP_SR_SHIFT 8 | ||
2062 | #define WM1_LP_CURSOR_MASK (0x3f) | ||
2063 | |||
2064 | /* Memory latency timer register */ | ||
2065 | #define MLTR_ILK 0x11222 | ||
2066 | /* the unit of memory self-refresh latency time is 0.5us */ | ||
2067 | #define ILK_SRLT_MASK 0x3f | ||
2068 | |||
2069 | /* define the fifo size on Ironlake */ | ||
2070 | #define ILK_DISPLAY_FIFO 128 | ||
2071 | #define ILK_DISPLAY_MAXWM 64 | ||
2072 | #define ILK_DISPLAY_DFTWM 8 | ||
2073 | |||
2074 | #define ILK_DISPLAY_SR_FIFO 512 | ||
2075 | #define ILK_DISPLAY_MAX_SRWM 0x1ff | ||
2076 | #define ILK_DISPLAY_DFT_SRWM 0x3f | ||
2077 | #define ILK_CURSOR_SR_FIFO 64 | ||
2078 | #define ILK_CURSOR_MAX_SRWM 0x3f | ||
2079 | #define ILK_CURSOR_DFT_SRWM 8 | ||
2080 | |||
2081 | #define ILK_FIFO_LINE_SIZE 64 | ||
2082 | |||
2016 | /* | 2083 | /* |
2017 | * The two pipe frame counter registers are not synchronized, so | 2084 | * The two pipe frame counter registers are not synchronized, so |
2018 | * reading a stable value is somewhat tricky. The following code | 2085 | * reading a stable value is somewhat tricky. The following code |
@@ -2285,6 +2352,7 @@ | |||
2285 | #define DEIER 0x4400c | 2352 | #define DEIER 0x4400c |
2286 | 2353 | ||
2287 | /* GT interrupt */ | 2354 | /* GT interrupt */ |
2355 | #define GT_PIPE_NOTIFY (1 << 4) | ||
2288 | #define GT_SYNC_STATUS (1 << 2) | 2356 | #define GT_SYNC_STATUS (1 << 2) |
2289 | #define GT_USER_INTERRUPT (1 << 0) | 2357 | #define GT_USER_INTERRUPT (1 << 0) |
2290 | 2358 | ||
@@ -2293,8 +2361,15 @@ | |||
2293 | #define GTIIR 0x44018 | 2361 | #define GTIIR 0x44018 |
2294 | #define GTIER 0x4401c | 2362 | #define GTIER 0x4401c |
2295 | 2363 | ||
2364 | #define ILK_DISPLAY_CHICKEN2 0x42004 | ||
2365 | #define ILK_DPARB_GATE (1<<22) | ||
2366 | #define ILK_VSDPFD_FULL (1<<21) | ||
2367 | #define ILK_DSPCLK_GATE 0x42020 | ||
2368 | #define ILK_DPARB_CLK_GATE (1<<5) | ||
2369 | |||
2296 | #define DISP_ARB_CTL 0x45000 | 2370 | #define DISP_ARB_CTL 0x45000 |
2297 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) | 2371 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) |
2372 | #define DISP_FBC_WM_DIS (1<<15) | ||
2298 | 2373 | ||
2299 | /* PCH */ | 2374 | /* PCH */ |
2300 | 2375 | ||
@@ -2305,6 +2380,11 @@ | |||
2305 | #define SDE_PORTB_HOTPLUG (1 << 8) | 2380 | #define SDE_PORTB_HOTPLUG (1 << 8) |
2306 | #define SDE_SDVOB_HOTPLUG (1 << 6) | 2381 | #define SDE_SDVOB_HOTPLUG (1 << 6) |
2307 | #define SDE_HOTPLUG_MASK (0xf << 8) | 2382 | #define SDE_HOTPLUG_MASK (0xf << 8) |
2383 | /* CPT */ | ||
2384 | #define SDE_CRT_HOTPLUG_CPT (1 << 19) | ||
2385 | #define SDE_PORTD_HOTPLUG_CPT (1 << 23) | ||
2386 | #define SDE_PORTC_HOTPLUG_CPT (1 << 22) | ||
2387 | #define SDE_PORTB_HOTPLUG_CPT (1 << 21) | ||
2308 | 2388 | ||
2309 | #define SDEISR 0xc4000 | 2389 | #define SDEISR 0xc4000 |
2310 | #define SDEIMR 0xc4004 | 2390 | #define SDEIMR 0xc4004 |
@@ -2396,6 +2476,17 @@ | |||
2396 | #define PCH_SSC4_PARMS 0xc6210 | 2476 | #define PCH_SSC4_PARMS 0xc6210 |
2397 | #define PCH_SSC4_AUX_PARMS 0xc6214 | 2477 | #define PCH_SSC4_AUX_PARMS 0xc6214 |
2398 | 2478 | ||
2479 | #define PCH_DPLL_SEL 0xc7000 | ||
2480 | #define TRANSA_DPLL_ENABLE (1<<3) | ||
2481 | #define TRANSA_DPLLB_SEL (1<<0) | ||
2482 | #define TRANSA_DPLLA_SEL 0 | ||
2483 | #define TRANSB_DPLL_ENABLE (1<<7) | ||
2484 | #define TRANSB_DPLLB_SEL (1<<4) | ||
2485 | #define TRANSB_DPLLA_SEL (0) | ||
2486 | #define TRANSC_DPLL_ENABLE (1<<11) | ||
2487 | #define TRANSC_DPLLB_SEL (1<<8) | ||
2488 | #define TRANSC_DPLLA_SEL (0) | ||
2489 | |||
2399 | /* transcoder */ | 2490 | /* transcoder */ |
2400 | 2491 | ||
2401 | #define TRANS_HTOTAL_A 0xe0000 | 2492 | #define TRANS_HTOTAL_A 0xe0000 |
@@ -2482,6 +2573,19 @@ | |||
2482 | #define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1<<22) | 2573 | #define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1<<22) |
2483 | #define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2<<22) | 2574 | #define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2<<22) |
2484 | #define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3<<22) | 2575 | #define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3<<22) |
2576 | /* ILK always use 400mV 0dB for voltage swing and pre-emphasis level. | ||
2577 | SNB has different settings. */ | ||
2578 | /* SNB A-stepping */ | ||
2579 | #define FDI_LINK_TRAIN_400MV_0DB_SNB_A (0x38<<22) | ||
2580 | #define FDI_LINK_TRAIN_400MV_6DB_SNB_A (0x02<<22) | ||
2581 | #define FDI_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01<<22) | ||
2582 | #define FDI_LINK_TRAIN_800MV_0DB_SNB_A (0x0<<22) | ||
2583 | /* SNB B-stepping */ | ||
2584 | #define FDI_LINK_TRAIN_400MV_0DB_SNB_B (0x0<<22) | ||
2585 | #define FDI_LINK_TRAIN_400MV_6DB_SNB_B (0x3a<<22) | ||
2586 | #define FDI_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39<<22) | ||
2587 | #define FDI_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) | ||
2588 | #define FDI_LINK_TRAIN_VOL_EMP_MASK (0x3f<<22) | ||
2485 | #define FDI_DP_PORT_WIDTH_X1 (0<<19) | 2589 | #define FDI_DP_PORT_WIDTH_X1 (0<<19) |
2486 | #define FDI_DP_PORT_WIDTH_X2 (1<<19) | 2590 | #define FDI_DP_PORT_WIDTH_X2 (1<<19) |
2487 | #define FDI_DP_PORT_WIDTH_X3 (2<<19) | 2591 | #define FDI_DP_PORT_WIDTH_X3 (2<<19) |
@@ -2514,6 +2618,13 @@ | |||
2514 | #define FDI_RX_ENHANCE_FRAME_ENABLE (1<<6) | 2618 | #define FDI_RX_ENHANCE_FRAME_ENABLE (1<<6) |
2515 | #define FDI_SEL_RAWCLK (0<<4) | 2619 | #define FDI_SEL_RAWCLK (0<<4) |
2516 | #define FDI_SEL_PCDCLK (1<<4) | 2620 | #define FDI_SEL_PCDCLK (1<<4) |
2621 | /* CPT */ | ||
2622 | #define FDI_AUTO_TRAINING (1<<10) | ||
2623 | #define FDI_LINK_TRAIN_PATTERN_1_CPT (0<<8) | ||
2624 | #define FDI_LINK_TRAIN_PATTERN_2_CPT (1<<8) | ||
2625 | #define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2<<8) | ||
2626 | #define FDI_LINK_TRAIN_NORMAL_CPT (3<<8) | ||
2627 | #define FDI_LINK_TRAIN_PATTERN_MASK_CPT (3<<8) | ||
2517 | 2628 | ||
2518 | #define FDI_RXA_MISC 0xf0010 | 2629 | #define FDI_RXA_MISC 0xf0010 |
2519 | #define FDI_RXB_MISC 0xf1010 | 2630 | #define FDI_RXB_MISC 0xf1010 |
@@ -2585,6 +2696,9 @@ | |||
2585 | #define HSYNC_ACTIVE_HIGH (1 << 3) | 2696 | #define HSYNC_ACTIVE_HIGH (1 << 3) |
2586 | #define PORT_DETECTED (1 << 2) | 2697 | #define PORT_DETECTED (1 << 2) |
2587 | 2698 | ||
2699 | /* PCH SDVOB multiplex with HDMIB */ | ||
2700 | #define PCH_SDVOB HDMIB | ||
2701 | |||
2588 | #define HDMIC 0xe1150 | 2702 | #define HDMIC 0xe1150 |
2589 | #define HDMID 0xe1160 | 2703 | #define HDMID 0xe1160 |
2590 | 2704 | ||
@@ -2642,4 +2756,42 @@ | |||
2642 | #define PCH_DPD_AUX_CH_DATA4 0xe4320 | 2756 | #define PCH_DPD_AUX_CH_DATA4 0xe4320 |
2643 | #define PCH_DPD_AUX_CH_DATA5 0xe4324 | 2757 | #define PCH_DPD_AUX_CH_DATA5 0xe4324 |
2644 | 2758 | ||
2759 | /* CPT */ | ||
2760 | #define PORT_TRANS_A_SEL_CPT 0 | ||
2761 | #define PORT_TRANS_B_SEL_CPT (1<<29) | ||
2762 | #define PORT_TRANS_C_SEL_CPT (2<<29) | ||
2763 | #define PORT_TRANS_SEL_MASK (3<<29) | ||
2764 | |||
2765 | #define TRANS_DP_CTL_A 0xe0300 | ||
2766 | #define TRANS_DP_CTL_B 0xe1300 | ||
2767 | #define TRANS_DP_CTL_C 0xe2300 | ||
2768 | #define TRANS_DP_OUTPUT_ENABLE (1<<31) | ||
2769 | #define TRANS_DP_PORT_SEL_B (0<<29) | ||
2770 | #define TRANS_DP_PORT_SEL_C (1<<29) | ||
2771 | #define TRANS_DP_PORT_SEL_D (2<<29) | ||
2772 | #define TRANS_DP_PORT_SEL_MASK (3<<29) | ||
2773 | #define TRANS_DP_AUDIO_ONLY (1<<26) | ||
2774 | #define TRANS_DP_ENH_FRAMING (1<<18) | ||
2775 | #define TRANS_DP_8BPC (0<<9) | ||
2776 | #define TRANS_DP_10BPC (1<<9) | ||
2777 | #define TRANS_DP_6BPC (2<<9) | ||
2778 | #define TRANS_DP_12BPC (3<<9) | ||
2779 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) | ||
2780 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | ||
2781 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | ||
2782 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 | ||
2783 | |||
2784 | /* SNB eDP training params */ | ||
2785 | /* SNB A-stepping */ | ||
2786 | #define EDP_LINK_TRAIN_400MV_0DB_SNB_A (0x38<<22) | ||
2787 | #define EDP_LINK_TRAIN_400MV_6DB_SNB_A (0x02<<22) | ||
2788 | #define EDP_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01<<22) | ||
2789 | #define EDP_LINK_TRAIN_800MV_0DB_SNB_A (0x0<<22) | ||
2790 | /* SNB B-stepping */ | ||
2791 | #define EDP_LINK_TRAIN_400MV_0DB_SNB_B (0x0<<22) | ||
2792 | #define EDP_LINK_TRAIN_400MV_6DB_SNB_B (0x3a<<22) | ||
2793 | #define EDP_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39<<22) | ||
2794 | #define EDP_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) | ||
2795 | #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) | ||
2796 | |||
2645 | #endif /* _I915_REG_H_ */ | 2797 | #endif /* _I915_REG_H_ */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index ac0d1a73ac22..60a5800fba6e 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -600,14 +600,16 @@ void i915_save_display(struct drm_device *dev) | |||
600 | } | 600 | } |
601 | /* FIXME: save TV & SDVO state */ | 601 | /* FIXME: save TV & SDVO state */ |
602 | 602 | ||
603 | /* FBC state */ | 603 | /* Only save FBC state on the platform that supports FBC */ |
604 | if (IS_GM45(dev)) { | 604 | if (I915_HAS_FBC(dev)) { |
605 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); | 605 | if (IS_GM45(dev)) { |
606 | } else { | 606 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); |
607 | dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); | 607 | } else { |
608 | dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); | 608 | dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); |
609 | dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); | 609 | dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); |
610 | dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); | 610 | dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); |
611 | dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); | ||
612 | } | ||
611 | } | 613 | } |
612 | 614 | ||
613 | /* VGA state */ | 615 | /* VGA state */ |
@@ -702,18 +704,19 @@ void i915_restore_display(struct drm_device *dev) | |||
702 | } | 704 | } |
703 | /* FIXME: restore TV & SDVO state */ | 705 | /* FIXME: restore TV & SDVO state */ |
704 | 706 | ||
705 | /* FBC info */ | 707 | /* only restore FBC info on the platform that supports FBC*/ |
706 | if (IS_GM45(dev)) { | 708 | if (I915_HAS_FBC(dev)) { |
707 | g4x_disable_fbc(dev); | 709 | if (IS_GM45(dev)) { |
708 | I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); | 710 | g4x_disable_fbc(dev); |
709 | } else { | 711 | I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); |
710 | i8xx_disable_fbc(dev); | 712 | } else { |
711 | I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); | 713 | i8xx_disable_fbc(dev); |
712 | I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); | 714 | I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); |
713 | I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); | 715 | I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); |
714 | I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); | 716 | I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); |
717 | I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); | ||
718 | } | ||
715 | } | 719 | } |
716 | |||
717 | /* VGA state */ | 720 | /* VGA state */ |
718 | if (IS_IRONLAKE(dev)) | 721 | if (IS_IRONLAKE(dev)) |
719 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); | 722 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 01840d9bc38f..9e4c45f68d6e 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -115,7 +115,7 @@ TRACE_EVENT(i915_gem_object_get_fence, | |||
115 | __entry->obj, __entry->fence, __entry->tiling_mode) | 115 | __entry->obj, __entry->fence, __entry->tiling_mode) |
116 | ); | 116 | ); |
117 | 117 | ||
118 | TRACE_EVENT(i915_gem_object_unbind, | 118 | DECLARE_EVENT_CLASS(i915_gem_object, |
119 | 119 | ||
120 | TP_PROTO(struct drm_gem_object *obj), | 120 | TP_PROTO(struct drm_gem_object *obj), |
121 | 121 | ||
@@ -132,21 +132,18 @@ TRACE_EVENT(i915_gem_object_unbind, | |||
132 | TP_printk("obj=%p", __entry->obj) | 132 | TP_printk("obj=%p", __entry->obj) |
133 | ); | 133 | ); |
134 | 134 | ||
135 | TRACE_EVENT(i915_gem_object_destroy, | 135 | DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, |
136 | 136 | ||
137 | TP_PROTO(struct drm_gem_object *obj), | 137 | TP_PROTO(struct drm_gem_object *obj), |
138 | 138 | ||
139 | TP_ARGS(obj), | 139 | TP_ARGS(obj) |
140 | ); | ||
140 | 141 | ||
141 | TP_STRUCT__entry( | 142 | DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy, |
142 | __field(struct drm_gem_object *, obj) | ||
143 | ), | ||
144 | 143 | ||
145 | TP_fast_assign( | 144 | TP_PROTO(struct drm_gem_object *obj), |
146 | __entry->obj = obj; | ||
147 | ), | ||
148 | 145 | ||
149 | TP_printk("obj=%p", __entry->obj) | 146 | TP_ARGS(obj) |
150 | ); | 147 | ); |
151 | 148 | ||
152 | /* batch tracing */ | 149 | /* batch tracing */ |
@@ -197,8 +194,7 @@ TRACE_EVENT(i915_gem_request_flush, | |||
197 | __entry->flush_domains, __entry->invalidate_domains) | 194 | __entry->flush_domains, __entry->invalidate_domains) |
198 | ); | 195 | ); |
199 | 196 | ||
200 | 197 | DECLARE_EVENT_CLASS(i915_gem_request, | |
201 | TRACE_EVENT(i915_gem_request_complete, | ||
202 | 198 | ||
203 | TP_PROTO(struct drm_device *dev, u32 seqno), | 199 | TP_PROTO(struct drm_device *dev, u32 seqno), |
204 | 200 | ||
@@ -217,64 +213,35 @@ TRACE_EVENT(i915_gem_request_complete, | |||
217 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) | 213 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) |
218 | ); | 214 | ); |
219 | 215 | ||
220 | TRACE_EVENT(i915_gem_request_retire, | 216 | DEFINE_EVENT(i915_gem_request, i915_gem_request_complete, |
221 | 217 | ||
222 | TP_PROTO(struct drm_device *dev, u32 seqno), | 218 | TP_PROTO(struct drm_device *dev, u32 seqno), |
223 | 219 | ||
224 | TP_ARGS(dev, seqno), | 220 | TP_ARGS(dev, seqno) |
225 | |||
226 | TP_STRUCT__entry( | ||
227 | __field(u32, dev) | ||
228 | __field(u32, seqno) | ||
229 | ), | ||
230 | |||
231 | TP_fast_assign( | ||
232 | __entry->dev = dev->primary->index; | ||
233 | __entry->seqno = seqno; | ||
234 | ), | ||
235 | |||
236 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) | ||
237 | ); | 221 | ); |
238 | 222 | ||
239 | TRACE_EVENT(i915_gem_request_wait_begin, | 223 | DEFINE_EVENT(i915_gem_request, i915_gem_request_retire, |
240 | 224 | ||
241 | TP_PROTO(struct drm_device *dev, u32 seqno), | 225 | TP_PROTO(struct drm_device *dev, u32 seqno), |
242 | 226 | ||
243 | TP_ARGS(dev, seqno), | 227 | TP_ARGS(dev, seqno) |
244 | |||
245 | TP_STRUCT__entry( | ||
246 | __field(u32, dev) | ||
247 | __field(u32, seqno) | ||
248 | ), | ||
249 | |||
250 | TP_fast_assign( | ||
251 | __entry->dev = dev->primary->index; | ||
252 | __entry->seqno = seqno; | ||
253 | ), | ||
254 | |||
255 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) | ||
256 | ); | 228 | ); |
257 | 229 | ||
258 | TRACE_EVENT(i915_gem_request_wait_end, | 230 | DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_begin, |
259 | 231 | ||
260 | TP_PROTO(struct drm_device *dev, u32 seqno), | 232 | TP_PROTO(struct drm_device *dev, u32 seqno), |
261 | 233 | ||
262 | TP_ARGS(dev, seqno), | 234 | TP_ARGS(dev, seqno) |
235 | ); | ||
263 | 236 | ||
264 | TP_STRUCT__entry( | 237 | DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end, |
265 | __field(u32, dev) | ||
266 | __field(u32, seqno) | ||
267 | ), | ||
268 | 238 | ||
269 | TP_fast_assign( | 239 | TP_PROTO(struct drm_device *dev, u32 seqno), |
270 | __entry->dev = dev->primary->index; | ||
271 | __entry->seqno = seqno; | ||
272 | ), | ||
273 | 240 | ||
274 | TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) | 241 | TP_ARGS(dev, seqno) |
275 | ); | 242 | ); |
276 | 243 | ||
277 | TRACE_EVENT(i915_ring_wait_begin, | 244 | DECLARE_EVENT_CLASS(i915_ring, |
278 | 245 | ||
279 | TP_PROTO(struct drm_device *dev), | 246 | TP_PROTO(struct drm_device *dev), |
280 | 247 | ||
@@ -291,26 +258,23 @@ TRACE_EVENT(i915_ring_wait_begin, | |||
291 | TP_printk("dev=%u", __entry->dev) | 258 | TP_printk("dev=%u", __entry->dev) |
292 | ); | 259 | ); |
293 | 260 | ||
294 | TRACE_EVENT(i915_ring_wait_end, | 261 | DEFINE_EVENT(i915_ring, i915_ring_wait_begin, |
295 | 262 | ||
296 | TP_PROTO(struct drm_device *dev), | 263 | TP_PROTO(struct drm_device *dev), |
297 | 264 | ||
298 | TP_ARGS(dev), | 265 | TP_ARGS(dev) |
266 | ); | ||
299 | 267 | ||
300 | TP_STRUCT__entry( | 268 | DEFINE_EVENT(i915_ring, i915_ring_wait_end, |
301 | __field(u32, dev) | ||
302 | ), | ||
303 | 269 | ||
304 | TP_fast_assign( | 270 | TP_PROTO(struct drm_device *dev), |
305 | __entry->dev = dev->primary->index; | ||
306 | ), | ||
307 | 271 | ||
308 | TP_printk("dev=%u", __entry->dev) | 272 | TP_ARGS(dev) |
309 | ); | 273 | ); |
310 | 274 | ||
311 | #endif /* _I915_TRACE_H_ */ | 275 | #endif /* _I915_TRACE_H_ */ |
312 | 276 | ||
313 | /* This part must be outside protection */ | 277 | /* This part must be outside protection */ |
314 | #undef TRACE_INCLUDE_PATH | 278 | #undef TRACE_INCLUDE_PATH |
315 | #define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/i915 | 279 | #define TRACE_INCLUDE_PATH . |
316 | #include <trace/define_trace.h> | 280 | #include <trace/define_trace.h> |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index f9ba452f0cbf..4c748d8f73d6 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -366,6 +366,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
366 | p_mapping->dvo_port = p_child->dvo_port; | 366 | p_mapping->dvo_port = p_child->dvo_port; |
367 | p_mapping->slave_addr = p_child->slave_addr; | 367 | p_mapping->slave_addr = p_child->slave_addr; |
368 | p_mapping->dvo_wiring = p_child->dvo_wiring; | 368 | p_mapping->dvo_wiring = p_child->dvo_wiring; |
369 | p_mapping->ddc_pin = p_child->ddc_pin; | ||
369 | p_mapping->initialized = 1; | 370 | p_mapping->initialized = 1; |
370 | } else { | 371 | } else { |
371 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " | 372 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 759c2ef72eff..e16ac5a28c3c 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -136,11 +136,17 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, | |||
136 | adpa |= ADPA_VSYNC_ACTIVE_HIGH; | 136 | adpa |= ADPA_VSYNC_ACTIVE_HIGH; |
137 | 137 | ||
138 | if (intel_crtc->pipe == 0) { | 138 | if (intel_crtc->pipe == 0) { |
139 | adpa |= ADPA_PIPE_A_SELECT; | 139 | if (HAS_PCH_CPT(dev)) |
140 | adpa |= PORT_TRANS_A_SEL_CPT; | ||
141 | else | ||
142 | adpa |= ADPA_PIPE_A_SELECT; | ||
140 | if (!HAS_PCH_SPLIT(dev)) | 143 | if (!HAS_PCH_SPLIT(dev)) |
141 | I915_WRITE(BCLRPAT_A, 0); | 144 | I915_WRITE(BCLRPAT_A, 0); |
142 | } else { | 145 | } else { |
143 | adpa |= ADPA_PIPE_B_SELECT; | 146 | if (HAS_PCH_CPT(dev)) |
147 | adpa |= PORT_TRANS_B_SEL_CPT; | ||
148 | else | ||
149 | adpa |= ADPA_PIPE_B_SELECT; | ||
144 | if (!HAS_PCH_SPLIT(dev)) | 150 | if (!HAS_PCH_SPLIT(dev)) |
145 | I915_WRITE(BCLRPAT_B, 0); | 151 | I915_WRITE(BCLRPAT_B, 0); |
146 | } | 152 | } |
@@ -152,15 +158,21 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
152 | { | 158 | { |
153 | struct drm_device *dev = connector->dev; | 159 | struct drm_device *dev = connector->dev; |
154 | struct drm_i915_private *dev_priv = dev->dev_private; | 160 | struct drm_i915_private *dev_priv = dev->dev_private; |
155 | u32 adpa; | 161 | u32 adpa, temp; |
156 | bool ret; | 162 | bool ret; |
157 | 163 | ||
158 | adpa = I915_READ(PCH_ADPA); | 164 | temp = adpa = I915_READ(PCH_ADPA); |
159 | 165 | ||
160 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 166 | if (HAS_PCH_CPT(dev)) { |
161 | /* disable HPD first */ | 167 | /* Disable DAC before force detect */ |
162 | I915_WRITE(PCH_ADPA, adpa); | 168 | I915_WRITE(PCH_ADPA, adpa & ~ADPA_DAC_ENABLE); |
163 | (void)I915_READ(PCH_ADPA); | 169 | (void)I915_READ(PCH_ADPA); |
170 | } else { | ||
171 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | ||
172 | /* disable HPD first */ | ||
173 | I915_WRITE(PCH_ADPA, adpa); | ||
174 | (void)I915_READ(PCH_ADPA); | ||
175 | } | ||
164 | 176 | ||
165 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 177 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | |
166 | ADPA_CRT_HOTPLUG_WARMUP_10MS | | 178 | ADPA_CRT_HOTPLUG_WARMUP_10MS | |
@@ -176,6 +188,11 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
176 | while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) | 188 | while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) |
177 | ; | 189 | ; |
178 | 190 | ||
191 | if (HAS_PCH_CPT(dev)) { | ||
192 | I915_WRITE(PCH_ADPA, temp); | ||
193 | (void)I915_READ(PCH_ADPA); | ||
194 | } | ||
195 | |||
179 | /* Check the status to see if both blue and green are on now */ | 196 | /* Check the status to see if both blue and green are on now */ |
180 | adpa = I915_READ(PCH_ADPA); | 197 | adpa = I915_READ(PCH_ADPA); |
181 | adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK; | 198 | adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK; |
@@ -245,9 +262,9 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
245 | return false; | 262 | return false; |
246 | } | 263 | } |
247 | 264 | ||
248 | static bool intel_crt_detect_ddc(struct drm_connector *connector) | 265 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) |
249 | { | 266 | { |
250 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 267 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
251 | 268 | ||
252 | /* CRT should always be at 0, but check anyway */ | 269 | /* CRT should always be at 0, but check anyway */ |
253 | if (intel_encoder->type != INTEL_OUTPUT_ANALOG) | 270 | if (intel_encoder->type != INTEL_OUTPUT_ANALOG) |
@@ -387,8 +404,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
387 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) | 404 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) |
388 | { | 405 | { |
389 | struct drm_device *dev = connector->dev; | 406 | struct drm_device *dev = connector->dev; |
390 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 407 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
391 | struct drm_encoder *encoder = &intel_encoder->enc; | 408 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
392 | struct drm_crtc *crtc; | 409 | struct drm_crtc *crtc; |
393 | int dpms_mode; | 410 | int dpms_mode; |
394 | enum drm_connector_status status; | 411 | enum drm_connector_status status; |
@@ -400,18 +417,19 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto | |||
400 | return connector_status_disconnected; | 417 | return connector_status_disconnected; |
401 | } | 418 | } |
402 | 419 | ||
403 | if (intel_crt_detect_ddc(connector)) | 420 | if (intel_crt_detect_ddc(encoder)) |
404 | return connector_status_connected; | 421 | return connector_status_connected; |
405 | 422 | ||
406 | /* for pre-945g platforms use load detect */ | 423 | /* for pre-945g platforms use load detect */ |
407 | if (encoder->crtc && encoder->crtc->enabled) { | 424 | if (encoder->crtc && encoder->crtc->enabled) { |
408 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); | 425 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); |
409 | } else { | 426 | } else { |
410 | crtc = intel_get_load_detect_pipe(intel_encoder, | 427 | crtc = intel_get_load_detect_pipe(intel_encoder, connector, |
411 | NULL, &dpms_mode); | 428 | NULL, &dpms_mode); |
412 | if (crtc) { | 429 | if (crtc) { |
413 | status = intel_crt_load_detect(crtc, intel_encoder); | 430 | status = intel_crt_load_detect(crtc, intel_encoder); |
414 | intel_release_load_detect_pipe(intel_encoder, dpms_mode); | 431 | intel_release_load_detect_pipe(intel_encoder, |
432 | connector, dpms_mode); | ||
415 | } else | 433 | } else |
416 | status = connector_status_unknown; | 434 | status = connector_status_unknown; |
417 | } | 435 | } |
@@ -421,9 +439,6 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto | |||
421 | 439 | ||
422 | static void intel_crt_destroy(struct drm_connector *connector) | 440 | static void intel_crt_destroy(struct drm_connector *connector) |
423 | { | 441 | { |
424 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
425 | |||
426 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
427 | drm_sysfs_connector_remove(connector); | 442 | drm_sysfs_connector_remove(connector); |
428 | drm_connector_cleanup(connector); | 443 | drm_connector_cleanup(connector); |
429 | kfree(connector); | 444 | kfree(connector); |
@@ -432,29 +447,27 @@ static void intel_crt_destroy(struct drm_connector *connector) | |||
432 | static int intel_crt_get_modes(struct drm_connector *connector) | 447 | static int intel_crt_get_modes(struct drm_connector *connector) |
433 | { | 448 | { |
434 | int ret; | 449 | int ret; |
435 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 450 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
436 | struct i2c_adapter *ddcbus; | 451 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
452 | struct i2c_adapter *ddc_bus; | ||
437 | struct drm_device *dev = connector->dev; | 453 | struct drm_device *dev = connector->dev; |
438 | 454 | ||
439 | 455 | ||
440 | ret = intel_ddc_get_modes(intel_encoder); | 456 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
441 | if (ret || !IS_G4X(dev)) | 457 | if (ret || !IS_G4X(dev)) |
442 | goto end; | 458 | goto end; |
443 | 459 | ||
444 | ddcbus = intel_encoder->ddc_bus; | ||
445 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | 460 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ |
446 | intel_encoder->ddc_bus = | 461 | ddc_bus = intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); |
447 | intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); | ||
448 | 462 | ||
449 | if (!intel_encoder->ddc_bus) { | 463 | if (!ddc_bus) { |
450 | intel_encoder->ddc_bus = ddcbus; | ||
451 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, | 464 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, |
452 | "DDC bus registration failed for CRTDDC_D.\n"); | 465 | "DDC bus registration failed for CRTDDC_D.\n"); |
453 | goto end; | 466 | goto end; |
454 | } | 467 | } |
455 | /* Try to get modes by GPIOD port */ | 468 | /* Try to get modes by GPIOD port */ |
456 | ret = intel_ddc_get_modes(intel_encoder); | 469 | ret = intel_ddc_get_modes(connector, ddc_bus); |
457 | intel_i2c_destroy(ddcbus); | 470 | intel_i2c_destroy(ddc_bus); |
458 | 471 | ||
459 | end: | 472 | end: |
460 | return ret; | 473 | return ret; |
@@ -491,12 +504,16 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = { | |||
491 | static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { | 504 | static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { |
492 | .mode_valid = intel_crt_mode_valid, | 505 | .mode_valid = intel_crt_mode_valid, |
493 | .get_modes = intel_crt_get_modes, | 506 | .get_modes = intel_crt_get_modes, |
494 | .best_encoder = intel_best_encoder, | 507 | .best_encoder = intel_attached_encoder, |
495 | }; | 508 | }; |
496 | 509 | ||
497 | static void intel_crt_enc_destroy(struct drm_encoder *encoder) | 510 | static void intel_crt_enc_destroy(struct drm_encoder *encoder) |
498 | { | 511 | { |
512 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
513 | |||
514 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
499 | drm_encoder_cleanup(encoder); | 515 | drm_encoder_cleanup(encoder); |
516 | kfree(intel_encoder); | ||
500 | } | 517 | } |
501 | 518 | ||
502 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { | 519 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { |
@@ -507,6 +524,7 @@ void intel_crt_init(struct drm_device *dev) | |||
507 | { | 524 | { |
508 | struct drm_connector *connector; | 525 | struct drm_connector *connector; |
509 | struct intel_encoder *intel_encoder; | 526 | struct intel_encoder *intel_encoder; |
527 | struct intel_connector *intel_connector; | ||
510 | struct drm_i915_private *dev_priv = dev->dev_private; | 528 | struct drm_i915_private *dev_priv = dev->dev_private; |
511 | u32 i2c_reg; | 529 | u32 i2c_reg; |
512 | 530 | ||
@@ -514,14 +532,20 @@ void intel_crt_init(struct drm_device *dev) | |||
514 | if (!intel_encoder) | 532 | if (!intel_encoder) |
515 | return; | 533 | return; |
516 | 534 | ||
517 | connector = &intel_encoder->base; | 535 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
518 | drm_connector_init(dev, &intel_encoder->base, | 536 | if (!intel_connector) { |
537 | kfree(intel_encoder); | ||
538 | return; | ||
539 | } | ||
540 | |||
541 | connector = &intel_connector->base; | ||
542 | drm_connector_init(dev, &intel_connector->base, | ||
519 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); | 543 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); |
520 | 544 | ||
521 | drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs, | 545 | drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs, |
522 | DRM_MODE_ENCODER_DAC); | 546 | DRM_MODE_ENCODER_DAC); |
523 | 547 | ||
524 | drm_mode_connector_attach_encoder(&intel_encoder->base, | 548 | drm_mode_connector_attach_encoder(&intel_connector->base, |
525 | &intel_encoder->enc); | 549 | &intel_encoder->enc); |
526 | 550 | ||
527 | /* Set up the DDC bus. */ | 551 | /* Set up the DDC bus. */ |
@@ -553,5 +577,10 @@ void intel_crt_init(struct drm_device *dev) | |||
553 | 577 | ||
554 | drm_sysfs_connector_add(connector); | 578 | drm_sysfs_connector_add(connector); |
555 | 579 | ||
580 | if (I915_HAS_HOTPLUG(dev)) | ||
581 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
582 | else | ||
583 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
584 | |||
556 | dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; | 585 | dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; |
557 | } | 586 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e7356fb6c918..f469a84cacfd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -742,12 +742,11 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | |||
742 | { | 742 | { |
743 | struct drm_device *dev = crtc->dev; | 743 | struct drm_device *dev = crtc->dev; |
744 | struct drm_mode_config *mode_config = &dev->mode_config; | 744 | struct drm_mode_config *mode_config = &dev->mode_config; |
745 | struct drm_connector *l_entry; | 745 | struct drm_encoder *l_entry; |
746 | 746 | ||
747 | list_for_each_entry(l_entry, &mode_config->connector_list, head) { | 747 | list_for_each_entry(l_entry, &mode_config->encoder_list, head) { |
748 | if (l_entry->encoder && | 748 | if (l_entry && l_entry->crtc == crtc) { |
749 | l_entry->encoder->crtc == crtc) { | 749 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(l_entry); |
750 | struct intel_encoder *intel_encoder = to_intel_encoder(l_entry); | ||
751 | if (intel_encoder->type == type) | 750 | if (intel_encoder->type == type) |
752 | return true; | 751 | return true; |
753 | } | 752 | } |
@@ -755,23 +754,6 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | |||
755 | return false; | 754 | return false; |
756 | } | 755 | } |
757 | 756 | ||
758 | static struct drm_connector * | ||
759 | intel_pipe_get_connector (struct drm_crtc *crtc) | ||
760 | { | ||
761 | struct drm_device *dev = crtc->dev; | ||
762 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
763 | struct drm_connector *l_entry, *ret = NULL; | ||
764 | |||
765 | list_for_each_entry(l_entry, &mode_config->connector_list, head) { | ||
766 | if (l_entry->encoder && | ||
767 | l_entry->encoder->crtc == crtc) { | ||
768 | ret = l_entry; | ||
769 | break; | ||
770 | } | ||
771 | } | ||
772 | return ret; | ||
773 | } | ||
774 | |||
775 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) | 757 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) |
776 | /** | 758 | /** |
777 | * Returns whether the given set of divisors are valid for a given refclk with | 759 | * Returns whether the given set of divisors are valid for a given refclk with |
@@ -905,9 +887,9 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
905 | 887 | ||
906 | memset(best_clock, 0, sizeof(*best_clock)); | 888 | memset(best_clock, 0, sizeof(*best_clock)); |
907 | max_n = limit->n.max; | 889 | max_n = limit->n.max; |
908 | /* based on hardware requriment prefer smaller n to precision */ | 890 | /* based on hardware requirement, prefer smaller n to precision */ |
909 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { | 891 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { |
910 | /* based on hardware requirment prefere larger m1,m2 */ | 892 | /* based on hardware requirement, prefere larger m1,m2 */ |
911 | for (clock.m1 = limit->m1.max; | 893 | for (clock.m1 = limit->m1.max; |
912 | clock.m1 >= limit->m1.min; clock.m1--) { | 894 | clock.m1 >= limit->m1.min; clock.m1--) { |
913 | for (clock.m2 = limit->m2.max; | 895 | for (clock.m2 = limit->m2.max; |
@@ -1066,9 +1048,8 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
1066 | DRM_DEBUG_KMS("disabled FBC\n"); | 1048 | DRM_DEBUG_KMS("disabled FBC\n"); |
1067 | } | 1049 | } |
1068 | 1050 | ||
1069 | static bool i8xx_fbc_enabled(struct drm_crtc *crtc) | 1051 | static bool i8xx_fbc_enabled(struct drm_device *dev) |
1070 | { | 1052 | { |
1071 | struct drm_device *dev = crtc->dev; | ||
1072 | struct drm_i915_private *dev_priv = dev->dev_private; | 1053 | struct drm_i915_private *dev_priv = dev->dev_private; |
1073 | 1054 | ||
1074 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; | 1055 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; |
@@ -1125,14 +1106,43 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
1125 | DRM_DEBUG_KMS("disabled FBC\n"); | 1106 | DRM_DEBUG_KMS("disabled FBC\n"); |
1126 | } | 1107 | } |
1127 | 1108 | ||
1128 | static bool g4x_fbc_enabled(struct drm_crtc *crtc) | 1109 | static bool g4x_fbc_enabled(struct drm_device *dev) |
1129 | { | 1110 | { |
1130 | struct drm_device *dev = crtc->dev; | ||
1131 | struct drm_i915_private *dev_priv = dev->dev_private; | 1111 | struct drm_i915_private *dev_priv = dev->dev_private; |
1132 | 1112 | ||
1133 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; | 1113 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; |
1134 | } | 1114 | } |
1135 | 1115 | ||
1116 | bool intel_fbc_enabled(struct drm_device *dev) | ||
1117 | { | ||
1118 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1119 | |||
1120 | if (!dev_priv->display.fbc_enabled) | ||
1121 | return false; | ||
1122 | |||
1123 | return dev_priv->display.fbc_enabled(dev); | ||
1124 | } | ||
1125 | |||
1126 | void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
1127 | { | ||
1128 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | ||
1129 | |||
1130 | if (!dev_priv->display.enable_fbc) | ||
1131 | return; | ||
1132 | |||
1133 | dev_priv->display.enable_fbc(crtc, interval); | ||
1134 | } | ||
1135 | |||
1136 | void intel_disable_fbc(struct drm_device *dev) | ||
1137 | { | ||
1138 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1139 | |||
1140 | if (!dev_priv->display.disable_fbc) | ||
1141 | return; | ||
1142 | |||
1143 | dev_priv->display.disable_fbc(dev); | ||
1144 | } | ||
1145 | |||
1136 | /** | 1146 | /** |
1137 | * intel_update_fbc - enable/disable FBC as needed | 1147 | * intel_update_fbc - enable/disable FBC as needed |
1138 | * @crtc: CRTC to point the compressor at | 1148 | * @crtc: CRTC to point the compressor at |
@@ -1167,9 +1177,7 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1167 | if (!i915_powersave) | 1177 | if (!i915_powersave) |
1168 | return; | 1178 | return; |
1169 | 1179 | ||
1170 | if (!dev_priv->display.fbc_enabled || | 1180 | if (!I915_HAS_FBC(dev)) |
1171 | !dev_priv->display.enable_fbc || | ||
1172 | !dev_priv->display.disable_fbc) | ||
1173 | return; | 1181 | return; |
1174 | 1182 | ||
1175 | if (!crtc->fb) | 1183 | if (!crtc->fb) |
@@ -1216,28 +1224,25 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1216 | goto out_disable; | 1224 | goto out_disable; |
1217 | } | 1225 | } |
1218 | 1226 | ||
1219 | if (dev_priv->display.fbc_enabled(crtc)) { | 1227 | if (intel_fbc_enabled(dev)) { |
1220 | /* We can re-enable it in this case, but need to update pitch */ | 1228 | /* We can re-enable it in this case, but need to update pitch */ |
1221 | if (fb->pitch > dev_priv->cfb_pitch) | 1229 | if ((fb->pitch > dev_priv->cfb_pitch) || |
1222 | dev_priv->display.disable_fbc(dev); | 1230 | (obj_priv->fence_reg != dev_priv->cfb_fence) || |
1223 | if (obj_priv->fence_reg != dev_priv->cfb_fence) | 1231 | (plane != dev_priv->cfb_plane)) |
1224 | dev_priv->display.disable_fbc(dev); | 1232 | intel_disable_fbc(dev); |
1225 | if (plane != dev_priv->cfb_plane) | ||
1226 | dev_priv->display.disable_fbc(dev); | ||
1227 | } | 1233 | } |
1228 | 1234 | ||
1229 | if (!dev_priv->display.fbc_enabled(crtc)) { | 1235 | /* Now try to turn it back on if possible */ |
1230 | /* Now try to turn it back on if possible */ | 1236 | if (!intel_fbc_enabled(dev)) |
1231 | dev_priv->display.enable_fbc(crtc, 500); | 1237 | intel_enable_fbc(crtc, 500); |
1232 | } | ||
1233 | 1238 | ||
1234 | return; | 1239 | return; |
1235 | 1240 | ||
1236 | out_disable: | 1241 | out_disable: |
1237 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | 1242 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); |
1238 | /* Multiple disables should be harmless */ | 1243 | /* Multiple disables should be harmless */ |
1239 | if (dev_priv->display.fbc_enabled(crtc)) | 1244 | if (intel_fbc_enabled(dev)) |
1240 | dev_priv->display.disable_fbc(dev); | 1245 | intel_disable_fbc(dev); |
1241 | } | 1246 | } |
1242 | 1247 | ||
1243 | static int | 1248 | static int |
@@ -1510,6 +1515,219 @@ static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) | |||
1510 | udelay(500); | 1515 | udelay(500); |
1511 | } | 1516 | } |
1512 | 1517 | ||
1518 | /* The FDI link training functions for ILK/Ibexpeak. */ | ||
1519 | static void ironlake_fdi_link_train(struct drm_crtc *crtc) | ||
1520 | { | ||
1521 | struct drm_device *dev = crtc->dev; | ||
1522 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1523 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
1524 | int pipe = intel_crtc->pipe; | ||
1525 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | ||
1526 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | ||
1527 | int fdi_rx_iir_reg = (pipe == 0) ? FDI_RXA_IIR : FDI_RXB_IIR; | ||
1528 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | ||
1529 | u32 temp, tries = 0; | ||
1530 | |||
1531 | /* enable CPU FDI TX and PCH FDI RX */ | ||
1532 | temp = I915_READ(fdi_tx_reg); | ||
1533 | temp |= FDI_TX_ENABLE; | ||
1534 | temp &= ~(7 << 19); | ||
1535 | temp |= (intel_crtc->fdi_lanes - 1) << 19; | ||
1536 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1537 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
1538 | I915_WRITE(fdi_tx_reg, temp); | ||
1539 | I915_READ(fdi_tx_reg); | ||
1540 | |||
1541 | temp = I915_READ(fdi_rx_reg); | ||
1542 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1543 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
1544 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | ||
1545 | I915_READ(fdi_rx_reg); | ||
1546 | udelay(150); | ||
1547 | |||
1548 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit | ||
1549 | for train result */ | ||
1550 | temp = I915_READ(fdi_rx_imr_reg); | ||
1551 | temp &= ~FDI_RX_SYMBOL_LOCK; | ||
1552 | temp &= ~FDI_RX_BIT_LOCK; | ||
1553 | I915_WRITE(fdi_rx_imr_reg, temp); | ||
1554 | I915_READ(fdi_rx_imr_reg); | ||
1555 | udelay(150); | ||
1556 | |||
1557 | for (;;) { | ||
1558 | temp = I915_READ(fdi_rx_iir_reg); | ||
1559 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | ||
1560 | |||
1561 | if ((temp & FDI_RX_BIT_LOCK)) { | ||
1562 | DRM_DEBUG_KMS("FDI train 1 done.\n"); | ||
1563 | I915_WRITE(fdi_rx_iir_reg, | ||
1564 | temp | FDI_RX_BIT_LOCK); | ||
1565 | break; | ||
1566 | } | ||
1567 | |||
1568 | tries++; | ||
1569 | |||
1570 | if (tries > 5) { | ||
1571 | DRM_DEBUG_KMS("FDI train 1 fail!\n"); | ||
1572 | break; | ||
1573 | } | ||
1574 | } | ||
1575 | |||
1576 | /* Train 2 */ | ||
1577 | temp = I915_READ(fdi_tx_reg); | ||
1578 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1579 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1580 | I915_WRITE(fdi_tx_reg, temp); | ||
1581 | |||
1582 | temp = I915_READ(fdi_rx_reg); | ||
1583 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1584 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1585 | I915_WRITE(fdi_rx_reg, temp); | ||
1586 | udelay(150); | ||
1587 | |||
1588 | tries = 0; | ||
1589 | |||
1590 | for (;;) { | ||
1591 | temp = I915_READ(fdi_rx_iir_reg); | ||
1592 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | ||
1593 | |||
1594 | if (temp & FDI_RX_SYMBOL_LOCK) { | ||
1595 | I915_WRITE(fdi_rx_iir_reg, | ||
1596 | temp | FDI_RX_SYMBOL_LOCK); | ||
1597 | DRM_DEBUG_KMS("FDI train 2 done.\n"); | ||
1598 | break; | ||
1599 | } | ||
1600 | |||
1601 | tries++; | ||
1602 | |||
1603 | if (tries > 5) { | ||
1604 | DRM_DEBUG_KMS("FDI train 2 fail!\n"); | ||
1605 | break; | ||
1606 | } | ||
1607 | } | ||
1608 | |||
1609 | DRM_DEBUG_KMS("FDI train done\n"); | ||
1610 | } | ||
1611 | |||
1612 | static int snb_b_fdi_train_param [] = { | ||
1613 | FDI_LINK_TRAIN_400MV_0DB_SNB_B, | ||
1614 | FDI_LINK_TRAIN_400MV_6DB_SNB_B, | ||
1615 | FDI_LINK_TRAIN_600MV_3_5DB_SNB_B, | ||
1616 | FDI_LINK_TRAIN_800MV_0DB_SNB_B, | ||
1617 | }; | ||
1618 | |||
1619 | /* The FDI link training functions for SNB/Cougarpoint. */ | ||
1620 | static void gen6_fdi_link_train(struct drm_crtc *crtc) | ||
1621 | { | ||
1622 | struct drm_device *dev = crtc->dev; | ||
1623 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1624 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
1625 | int pipe = intel_crtc->pipe; | ||
1626 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | ||
1627 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | ||
1628 | int fdi_rx_iir_reg = (pipe == 0) ? FDI_RXA_IIR : FDI_RXB_IIR; | ||
1629 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | ||
1630 | u32 temp, i; | ||
1631 | |||
1632 | /* enable CPU FDI TX and PCH FDI RX */ | ||
1633 | temp = I915_READ(fdi_tx_reg); | ||
1634 | temp |= FDI_TX_ENABLE; | ||
1635 | temp &= ~(7 << 19); | ||
1636 | temp |= (intel_crtc->fdi_lanes - 1) << 19; | ||
1637 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1638 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
1639 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; | ||
1640 | /* SNB-B */ | ||
1641 | temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; | ||
1642 | I915_WRITE(fdi_tx_reg, temp); | ||
1643 | I915_READ(fdi_tx_reg); | ||
1644 | |||
1645 | temp = I915_READ(fdi_rx_reg); | ||
1646 | if (HAS_PCH_CPT(dev)) { | ||
1647 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | ||
1648 | temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; | ||
1649 | } else { | ||
1650 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1651 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
1652 | } | ||
1653 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | ||
1654 | I915_READ(fdi_rx_reg); | ||
1655 | udelay(150); | ||
1656 | |||
1657 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit | ||
1658 | for train result */ | ||
1659 | temp = I915_READ(fdi_rx_imr_reg); | ||
1660 | temp &= ~FDI_RX_SYMBOL_LOCK; | ||
1661 | temp &= ~FDI_RX_BIT_LOCK; | ||
1662 | I915_WRITE(fdi_rx_imr_reg, temp); | ||
1663 | I915_READ(fdi_rx_imr_reg); | ||
1664 | udelay(150); | ||
1665 | |||
1666 | for (i = 0; i < 4; i++ ) { | ||
1667 | temp = I915_READ(fdi_tx_reg); | ||
1668 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; | ||
1669 | temp |= snb_b_fdi_train_param[i]; | ||
1670 | I915_WRITE(fdi_tx_reg, temp); | ||
1671 | udelay(500); | ||
1672 | |||
1673 | temp = I915_READ(fdi_rx_iir_reg); | ||
1674 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | ||
1675 | |||
1676 | if (temp & FDI_RX_BIT_LOCK) { | ||
1677 | I915_WRITE(fdi_rx_iir_reg, | ||
1678 | temp | FDI_RX_BIT_LOCK); | ||
1679 | DRM_DEBUG_KMS("FDI train 1 done.\n"); | ||
1680 | break; | ||
1681 | } | ||
1682 | } | ||
1683 | if (i == 4) | ||
1684 | DRM_DEBUG_KMS("FDI train 1 fail!\n"); | ||
1685 | |||
1686 | /* Train 2 */ | ||
1687 | temp = I915_READ(fdi_tx_reg); | ||
1688 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1689 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1690 | if (IS_GEN6(dev)) { | ||
1691 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; | ||
1692 | /* SNB-B */ | ||
1693 | temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; | ||
1694 | } | ||
1695 | I915_WRITE(fdi_tx_reg, temp); | ||
1696 | |||
1697 | temp = I915_READ(fdi_rx_reg); | ||
1698 | if (HAS_PCH_CPT(dev)) { | ||
1699 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | ||
1700 | temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; | ||
1701 | } else { | ||
1702 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1703 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1704 | } | ||
1705 | I915_WRITE(fdi_rx_reg, temp); | ||
1706 | udelay(150); | ||
1707 | |||
1708 | for (i = 0; i < 4; i++ ) { | ||
1709 | temp = I915_READ(fdi_tx_reg); | ||
1710 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; | ||
1711 | temp |= snb_b_fdi_train_param[i]; | ||
1712 | I915_WRITE(fdi_tx_reg, temp); | ||
1713 | udelay(500); | ||
1714 | |||
1715 | temp = I915_READ(fdi_rx_iir_reg); | ||
1716 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | ||
1717 | |||
1718 | if (temp & FDI_RX_SYMBOL_LOCK) { | ||
1719 | I915_WRITE(fdi_rx_iir_reg, | ||
1720 | temp | FDI_RX_SYMBOL_LOCK); | ||
1721 | DRM_DEBUG_KMS("FDI train 2 done.\n"); | ||
1722 | break; | ||
1723 | } | ||
1724 | } | ||
1725 | if (i == 4) | ||
1726 | DRM_DEBUG_KMS("FDI train 2 fail!\n"); | ||
1727 | |||
1728 | DRM_DEBUG_KMS("FDI train done.\n"); | ||
1729 | } | ||
1730 | |||
1513 | static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | 1731 | static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) |
1514 | { | 1732 | { |
1515 | struct drm_device *dev = crtc->dev; | 1733 | struct drm_device *dev = crtc->dev; |
@@ -1523,8 +1741,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1523 | int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR; | 1741 | int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR; |
1524 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | 1742 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; |
1525 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | 1743 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; |
1526 | int fdi_rx_iir_reg = (pipe == 0) ? FDI_RXA_IIR : FDI_RXB_IIR; | ||
1527 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | ||
1528 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; | 1744 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; |
1529 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; | 1745 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; |
1530 | int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; | 1746 | int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; |
@@ -1541,8 +1757,9 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1541 | int trans_vtot_reg = (pipe == 0) ? TRANS_VTOTAL_A : TRANS_VTOTAL_B; | 1757 | int trans_vtot_reg = (pipe == 0) ? TRANS_VTOTAL_A : TRANS_VTOTAL_B; |
1542 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; | 1758 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; |
1543 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1759 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
1760 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | ||
1544 | u32 temp; | 1761 | u32 temp; |
1545 | int tries = 5, j, n; | 1762 | int n; |
1546 | u32 pipe_bpc; | 1763 | u32 pipe_bpc; |
1547 | 1764 | ||
1548 | temp = I915_READ(pipeconf_reg); | 1765 | temp = I915_READ(pipeconf_reg); |
@@ -1569,12 +1786,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1569 | /* enable eDP PLL */ | 1786 | /* enable eDP PLL */ |
1570 | ironlake_enable_pll_edp(crtc); | 1787 | ironlake_enable_pll_edp(crtc); |
1571 | } else { | 1788 | } else { |
1572 | /* enable PCH DPLL */ | ||
1573 | temp = I915_READ(pch_dpll_reg); | ||
1574 | if ((temp & DPLL_VCO_ENABLE) == 0) { | ||
1575 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); | ||
1576 | I915_READ(pch_dpll_reg); | ||
1577 | } | ||
1578 | 1789 | ||
1579 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1790 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1580 | temp = I915_READ(fdi_rx_reg); | 1791 | temp = I915_READ(fdi_rx_reg); |
@@ -1584,9 +1795,15 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1584 | */ | 1795 | */ |
1585 | temp &= ~(0x7 << 16); | 1796 | temp &= ~(0x7 << 16); |
1586 | temp |= (pipe_bpc << 11); | 1797 | temp |= (pipe_bpc << 11); |
1587 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE | | 1798 | temp &= ~(7 << 19); |
1588 | FDI_SEL_PCDCLK | | 1799 | temp |= (intel_crtc->fdi_lanes - 1) << 19; |
1589 | FDI_DP_PORT_WIDTH_X4); /* default 4 lanes */ | 1800 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); |
1801 | I915_READ(fdi_rx_reg); | ||
1802 | udelay(200); | ||
1803 | |||
1804 | /* Switch from Rawclk to PCDclk */ | ||
1805 | temp = I915_READ(fdi_rx_reg); | ||
1806 | I915_WRITE(fdi_rx_reg, temp | FDI_SEL_PCDCLK); | ||
1590 | I915_READ(fdi_rx_reg); | 1807 | I915_READ(fdi_rx_reg); |
1591 | udelay(200); | 1808 | udelay(200); |
1592 | 1809 | ||
@@ -1629,91 +1846,32 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1629 | } | 1846 | } |
1630 | 1847 | ||
1631 | if (!HAS_eDP) { | 1848 | if (!HAS_eDP) { |
1632 | /* enable CPU FDI TX and PCH FDI RX */ | 1849 | /* For PCH output, training FDI link */ |
1633 | temp = I915_READ(fdi_tx_reg); | 1850 | if (IS_GEN6(dev)) |
1634 | temp |= FDI_TX_ENABLE; | 1851 | gen6_fdi_link_train(crtc); |
1635 | temp |= FDI_DP_PORT_WIDTH_X4; /* default */ | 1852 | else |
1636 | temp &= ~FDI_LINK_TRAIN_NONE; | 1853 | ironlake_fdi_link_train(crtc); |
1637 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
1638 | I915_WRITE(fdi_tx_reg, temp); | ||
1639 | I915_READ(fdi_tx_reg); | ||
1640 | |||
1641 | temp = I915_READ(fdi_rx_reg); | ||
1642 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1643 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
1644 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | ||
1645 | I915_READ(fdi_rx_reg); | ||
1646 | |||
1647 | udelay(150); | ||
1648 | |||
1649 | /* Train FDI. */ | ||
1650 | /* umask FDI RX Interrupt symbol_lock and bit_lock bit | ||
1651 | for train result */ | ||
1652 | temp = I915_READ(fdi_rx_imr_reg); | ||
1653 | temp &= ~FDI_RX_SYMBOL_LOCK; | ||
1654 | temp &= ~FDI_RX_BIT_LOCK; | ||
1655 | I915_WRITE(fdi_rx_imr_reg, temp); | ||
1656 | I915_READ(fdi_rx_imr_reg); | ||
1657 | udelay(150); | ||
1658 | 1854 | ||
1659 | temp = I915_READ(fdi_rx_iir_reg); | 1855 | /* enable PCH DPLL */ |
1660 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | 1856 | temp = I915_READ(pch_dpll_reg); |
1661 | 1857 | if ((temp & DPLL_VCO_ENABLE) == 0) { | |
1662 | if ((temp & FDI_RX_BIT_LOCK) == 0) { | 1858 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); |
1663 | for (j = 0; j < tries; j++) { | 1859 | I915_READ(pch_dpll_reg); |
1664 | temp = I915_READ(fdi_rx_iir_reg); | ||
1665 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", | ||
1666 | temp); | ||
1667 | if (temp & FDI_RX_BIT_LOCK) | ||
1668 | break; | ||
1669 | udelay(200); | ||
1670 | } | ||
1671 | if (j != tries) | ||
1672 | I915_WRITE(fdi_rx_iir_reg, | ||
1673 | temp | FDI_RX_BIT_LOCK); | ||
1674 | else | ||
1675 | DRM_DEBUG_KMS("train 1 fail\n"); | ||
1676 | } else { | ||
1677 | I915_WRITE(fdi_rx_iir_reg, | ||
1678 | temp | FDI_RX_BIT_LOCK); | ||
1679 | DRM_DEBUG_KMS("train 1 ok 2!\n"); | ||
1680 | } | 1860 | } |
1681 | temp = I915_READ(fdi_tx_reg); | 1861 | udelay(200); |
1682 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1683 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1684 | I915_WRITE(fdi_tx_reg, temp); | ||
1685 | |||
1686 | temp = I915_READ(fdi_rx_reg); | ||
1687 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1688 | temp |= FDI_LINK_TRAIN_PATTERN_2; | ||
1689 | I915_WRITE(fdi_rx_reg, temp); | ||
1690 | |||
1691 | udelay(150); | ||
1692 | 1862 | ||
1693 | temp = I915_READ(fdi_rx_iir_reg); | 1863 | if (HAS_PCH_CPT(dev)) { |
1694 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | 1864 | /* Be sure PCH DPLL SEL is set */ |
1695 | 1865 | temp = I915_READ(PCH_DPLL_SEL); | |
1696 | if ((temp & FDI_RX_SYMBOL_LOCK) == 0) { | 1866 | if (trans_dpll_sel == 0 && |
1697 | for (j = 0; j < tries; j++) { | 1867 | (temp & TRANSA_DPLL_ENABLE) == 0) |
1698 | temp = I915_READ(fdi_rx_iir_reg); | 1868 | temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); |
1699 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", | 1869 | else if (trans_dpll_sel == 1 && |
1700 | temp); | 1870 | (temp & TRANSB_DPLL_ENABLE) == 0) |
1701 | if (temp & FDI_RX_SYMBOL_LOCK) | 1871 | temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); |
1702 | break; | 1872 | I915_WRITE(PCH_DPLL_SEL, temp); |
1703 | udelay(200); | 1873 | I915_READ(PCH_DPLL_SEL); |
1704 | } | ||
1705 | if (j != tries) { | ||
1706 | I915_WRITE(fdi_rx_iir_reg, | ||
1707 | temp | FDI_RX_SYMBOL_LOCK); | ||
1708 | DRM_DEBUG_KMS("train 2 ok 1!\n"); | ||
1709 | } else | ||
1710 | DRM_DEBUG_KMS("train 2 fail\n"); | ||
1711 | } else { | ||
1712 | I915_WRITE(fdi_rx_iir_reg, | ||
1713 | temp | FDI_RX_SYMBOL_LOCK); | ||
1714 | DRM_DEBUG_KMS("train 2 ok 2!\n"); | ||
1715 | } | 1874 | } |
1716 | DRM_DEBUG_KMS("train done\n"); | ||
1717 | 1875 | ||
1718 | /* set transcoder timing */ | 1876 | /* set transcoder timing */ |
1719 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); | 1877 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); |
@@ -1724,6 +1882,60 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1724 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); | 1882 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); |
1725 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); | 1883 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); |
1726 | 1884 | ||
1885 | /* enable normal train */ | ||
1886 | temp = I915_READ(fdi_tx_reg); | ||
1887 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1888 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | | ||
1889 | FDI_TX_ENHANCE_FRAME_ENABLE); | ||
1890 | I915_READ(fdi_tx_reg); | ||
1891 | |||
1892 | temp = I915_READ(fdi_rx_reg); | ||
1893 | if (HAS_PCH_CPT(dev)) { | ||
1894 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | ||
1895 | temp |= FDI_LINK_TRAIN_NORMAL_CPT; | ||
1896 | } else { | ||
1897 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1898 | temp |= FDI_LINK_TRAIN_NONE; | ||
1899 | } | ||
1900 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); | ||
1901 | I915_READ(fdi_rx_reg); | ||
1902 | |||
1903 | /* wait one idle pattern time */ | ||
1904 | udelay(100); | ||
1905 | |||
1906 | /* For PCH DP, enable TRANS_DP_CTL */ | ||
1907 | if (HAS_PCH_CPT(dev) && | ||
1908 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | ||
1909 | int trans_dp_ctl = (pipe == 0) ? TRANS_DP_CTL_A : TRANS_DP_CTL_B; | ||
1910 | int reg; | ||
1911 | |||
1912 | reg = I915_READ(trans_dp_ctl); | ||
1913 | reg &= ~TRANS_DP_PORT_SEL_MASK; | ||
1914 | reg = TRANS_DP_OUTPUT_ENABLE | | ||
1915 | TRANS_DP_ENH_FRAMING | | ||
1916 | TRANS_DP_VSYNC_ACTIVE_HIGH | | ||
1917 | TRANS_DP_HSYNC_ACTIVE_HIGH; | ||
1918 | |||
1919 | switch (intel_trans_dp_port_sel(crtc)) { | ||
1920 | case PCH_DP_B: | ||
1921 | reg |= TRANS_DP_PORT_SEL_B; | ||
1922 | break; | ||
1923 | case PCH_DP_C: | ||
1924 | reg |= TRANS_DP_PORT_SEL_C; | ||
1925 | break; | ||
1926 | case PCH_DP_D: | ||
1927 | reg |= TRANS_DP_PORT_SEL_D; | ||
1928 | break; | ||
1929 | default: | ||
1930 | DRM_DEBUG_KMS("Wrong PCH DP port return. Guess port B\n"); | ||
1931 | reg |= TRANS_DP_PORT_SEL_B; | ||
1932 | break; | ||
1933 | } | ||
1934 | |||
1935 | I915_WRITE(trans_dp_ctl, reg); | ||
1936 | POSTING_READ(trans_dp_ctl); | ||
1937 | } | ||
1938 | |||
1727 | /* enable PCH transcoder */ | 1939 | /* enable PCH transcoder */ |
1728 | temp = I915_READ(transconf_reg); | 1940 | temp = I915_READ(transconf_reg); |
1729 | /* | 1941 | /* |
@@ -1738,23 +1950,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1738 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 1950 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) |
1739 | ; | 1951 | ; |
1740 | 1952 | ||
1741 | /* enable normal */ | ||
1742 | |||
1743 | temp = I915_READ(fdi_tx_reg); | ||
1744 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1745 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | | ||
1746 | FDI_TX_ENHANCE_FRAME_ENABLE); | ||
1747 | I915_READ(fdi_tx_reg); | ||
1748 | |||
1749 | temp = I915_READ(fdi_rx_reg); | ||
1750 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
1751 | I915_WRITE(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE | | ||
1752 | FDI_RX_ENHANCE_FRAME_ENABLE); | ||
1753 | I915_READ(fdi_rx_reg); | ||
1754 | |||
1755 | /* wait one idle pattern time */ | ||
1756 | udelay(100); | ||
1757 | |||
1758 | } | 1953 | } |
1759 | 1954 | ||
1760 | intel_crtc_load_lut(crtc); | 1955 | intel_crtc_load_lut(crtc); |
@@ -1805,6 +2000,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1805 | I915_READ(pf_ctl_reg); | 2000 | I915_READ(pf_ctl_reg); |
1806 | } | 2001 | } |
1807 | I915_WRITE(pf_win_size, 0); | 2002 | I915_WRITE(pf_win_size, 0); |
2003 | POSTING_READ(pf_win_size); | ||
2004 | |||
1808 | 2005 | ||
1809 | /* disable CPU FDI tx and PCH FDI rx */ | 2006 | /* disable CPU FDI tx and PCH FDI rx */ |
1810 | temp = I915_READ(fdi_tx_reg); | 2007 | temp = I915_READ(fdi_tx_reg); |
@@ -1825,11 +2022,18 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1825 | temp &= ~FDI_LINK_TRAIN_NONE; | 2022 | temp &= ~FDI_LINK_TRAIN_NONE; |
1826 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 2023 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1827 | I915_WRITE(fdi_tx_reg, temp); | 2024 | I915_WRITE(fdi_tx_reg, temp); |
2025 | POSTING_READ(fdi_tx_reg); | ||
1828 | 2026 | ||
1829 | temp = I915_READ(fdi_rx_reg); | 2027 | temp = I915_READ(fdi_rx_reg); |
1830 | temp &= ~FDI_LINK_TRAIN_NONE; | 2028 | if (HAS_PCH_CPT(dev)) { |
1831 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 2029 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; |
2030 | temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; | ||
2031 | } else { | ||
2032 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
2033 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
2034 | } | ||
1832 | I915_WRITE(fdi_rx_reg, temp); | 2035 | I915_WRITE(fdi_rx_reg, temp); |
2036 | POSTING_READ(fdi_rx_reg); | ||
1833 | 2037 | ||
1834 | udelay(100); | 2038 | udelay(100); |
1835 | 2039 | ||
@@ -1859,6 +2063,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1859 | } | 2063 | } |
1860 | } | 2064 | } |
1861 | } | 2065 | } |
2066 | |||
1862 | temp = I915_READ(transconf_reg); | 2067 | temp = I915_READ(transconf_reg); |
1863 | /* BPC in transcoder is consistent with that in pipeconf */ | 2068 | /* BPC in transcoder is consistent with that in pipeconf */ |
1864 | temp &= ~PIPE_BPC_MASK; | 2069 | temp &= ~PIPE_BPC_MASK; |
@@ -1867,35 +2072,53 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1867 | I915_READ(transconf_reg); | 2072 | I915_READ(transconf_reg); |
1868 | udelay(100); | 2073 | udelay(100); |
1869 | 2074 | ||
2075 | if (HAS_PCH_CPT(dev)) { | ||
2076 | /* disable TRANS_DP_CTL */ | ||
2077 | int trans_dp_ctl = (pipe == 0) ? TRANS_DP_CTL_A : TRANS_DP_CTL_B; | ||
2078 | int reg; | ||
2079 | |||
2080 | reg = I915_READ(trans_dp_ctl); | ||
2081 | reg &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK); | ||
2082 | I915_WRITE(trans_dp_ctl, reg); | ||
2083 | POSTING_READ(trans_dp_ctl); | ||
2084 | |||
2085 | /* disable DPLL_SEL */ | ||
2086 | temp = I915_READ(PCH_DPLL_SEL); | ||
2087 | if (trans_dpll_sel == 0) | ||
2088 | temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL); | ||
2089 | else | ||
2090 | temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); | ||
2091 | I915_WRITE(PCH_DPLL_SEL, temp); | ||
2092 | I915_READ(PCH_DPLL_SEL); | ||
2093 | |||
2094 | } | ||
2095 | |||
1870 | /* disable PCH DPLL */ | 2096 | /* disable PCH DPLL */ |
1871 | temp = I915_READ(pch_dpll_reg); | 2097 | temp = I915_READ(pch_dpll_reg); |
1872 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2098 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); |
1873 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); | 2099 | I915_READ(pch_dpll_reg); |
1874 | I915_READ(pch_dpll_reg); | ||
1875 | } | ||
1876 | 2100 | ||
1877 | if (HAS_eDP) { | 2101 | if (HAS_eDP) { |
1878 | ironlake_disable_pll_edp(crtc); | 2102 | ironlake_disable_pll_edp(crtc); |
1879 | } | 2103 | } |
1880 | 2104 | ||
2105 | /* Switch from PCDclk to Rawclk */ | ||
1881 | temp = I915_READ(fdi_rx_reg); | 2106 | temp = I915_READ(fdi_rx_reg); |
1882 | temp &= ~FDI_SEL_PCDCLK; | 2107 | temp &= ~FDI_SEL_PCDCLK; |
1883 | I915_WRITE(fdi_rx_reg, temp); | 2108 | I915_WRITE(fdi_rx_reg, temp); |
1884 | I915_READ(fdi_rx_reg); | 2109 | I915_READ(fdi_rx_reg); |
1885 | 2110 | ||
2111 | /* Disable CPU FDI TX PLL */ | ||
2112 | temp = I915_READ(fdi_tx_reg); | ||
2113 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE); | ||
2114 | I915_READ(fdi_tx_reg); | ||
2115 | udelay(100); | ||
2116 | |||
1886 | temp = I915_READ(fdi_rx_reg); | 2117 | temp = I915_READ(fdi_rx_reg); |
1887 | temp &= ~FDI_RX_PLL_ENABLE; | 2118 | temp &= ~FDI_RX_PLL_ENABLE; |
1888 | I915_WRITE(fdi_rx_reg, temp); | 2119 | I915_WRITE(fdi_rx_reg, temp); |
1889 | I915_READ(fdi_rx_reg); | 2120 | I915_READ(fdi_rx_reg); |
1890 | 2121 | ||
1891 | /* Disable CPU FDI TX PLL */ | ||
1892 | temp = I915_READ(fdi_tx_reg); | ||
1893 | if ((temp & FDI_TX_PLL_ENABLE) != 0) { | ||
1894 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE); | ||
1895 | I915_READ(fdi_tx_reg); | ||
1896 | udelay(100); | ||
1897 | } | ||
1898 | |||
1899 | /* Wait for the clocks to turn off. */ | 2122 | /* Wait for the clocks to turn off. */ |
1900 | udelay(100); | 2123 | udelay(100); |
1901 | break; | 2124 | break; |
@@ -2331,6 +2554,30 @@ static struct intel_watermark_params i830_wm_info = { | |||
2331 | I830_FIFO_LINE_SIZE | 2554 | I830_FIFO_LINE_SIZE |
2332 | }; | 2555 | }; |
2333 | 2556 | ||
2557 | static struct intel_watermark_params ironlake_display_wm_info = { | ||
2558 | ILK_DISPLAY_FIFO, | ||
2559 | ILK_DISPLAY_MAXWM, | ||
2560 | ILK_DISPLAY_DFTWM, | ||
2561 | 2, | ||
2562 | ILK_FIFO_LINE_SIZE | ||
2563 | }; | ||
2564 | |||
2565 | static struct intel_watermark_params ironlake_display_srwm_info = { | ||
2566 | ILK_DISPLAY_SR_FIFO, | ||
2567 | ILK_DISPLAY_MAX_SRWM, | ||
2568 | ILK_DISPLAY_DFT_SRWM, | ||
2569 | 2, | ||
2570 | ILK_FIFO_LINE_SIZE | ||
2571 | }; | ||
2572 | |||
2573 | static struct intel_watermark_params ironlake_cursor_srwm_info = { | ||
2574 | ILK_CURSOR_SR_FIFO, | ||
2575 | ILK_CURSOR_MAX_SRWM, | ||
2576 | ILK_CURSOR_DFT_SRWM, | ||
2577 | 2, | ||
2578 | ILK_FIFO_LINE_SIZE | ||
2579 | }; | ||
2580 | |||
2334 | /** | 2581 | /** |
2335 | * intel_calculate_wm - calculate watermark level | 2582 | * intel_calculate_wm - calculate watermark level |
2336 | * @clock_in_khz: pixel clock | 2583 | * @clock_in_khz: pixel clock |
@@ -2449,66 +2696,6 @@ static void pineview_disable_cxsr(struct drm_device *dev) | |||
2449 | DRM_INFO("Big FIFO is disabled\n"); | 2696 | DRM_INFO("Big FIFO is disabled\n"); |
2450 | } | 2697 | } |
2451 | 2698 | ||
2452 | static void pineview_enable_cxsr(struct drm_device *dev, unsigned long clock, | ||
2453 | int pixel_size) | ||
2454 | { | ||
2455 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2456 | u32 reg; | ||
2457 | unsigned long wm; | ||
2458 | struct cxsr_latency *latency; | ||
2459 | |||
2460 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq, | ||
2461 | dev_priv->mem_freq); | ||
2462 | if (!latency) { | ||
2463 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | ||
2464 | pineview_disable_cxsr(dev); | ||
2465 | return; | ||
2466 | } | ||
2467 | |||
2468 | /* Display SR */ | ||
2469 | wm = intel_calculate_wm(clock, &pineview_display_wm, pixel_size, | ||
2470 | latency->display_sr); | ||
2471 | reg = I915_READ(DSPFW1); | ||
2472 | reg &= 0x7fffff; | ||
2473 | reg |= wm << 23; | ||
2474 | I915_WRITE(DSPFW1, reg); | ||
2475 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); | ||
2476 | |||
2477 | /* cursor SR */ | ||
2478 | wm = intel_calculate_wm(clock, &pineview_cursor_wm, pixel_size, | ||
2479 | latency->cursor_sr); | ||
2480 | reg = I915_READ(DSPFW3); | ||
2481 | reg &= ~(0x3f << 24); | ||
2482 | reg |= (wm & 0x3f) << 24; | ||
2483 | I915_WRITE(DSPFW3, reg); | ||
2484 | |||
2485 | /* Display HPLL off SR */ | ||
2486 | wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, | ||
2487 | latency->display_hpll_disable, I915_FIFO_LINE_SIZE); | ||
2488 | reg = I915_READ(DSPFW3); | ||
2489 | reg &= 0xfffffe00; | ||
2490 | reg |= wm & 0x1ff; | ||
2491 | I915_WRITE(DSPFW3, reg); | ||
2492 | |||
2493 | /* cursor HPLL off SR */ | ||
2494 | wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, pixel_size, | ||
2495 | latency->cursor_hpll_disable); | ||
2496 | reg = I915_READ(DSPFW3); | ||
2497 | reg &= ~(0x3f << 16); | ||
2498 | reg |= (wm & 0x3f) << 16; | ||
2499 | I915_WRITE(DSPFW3, reg); | ||
2500 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | ||
2501 | |||
2502 | /* activate cxsr */ | ||
2503 | reg = I915_READ(DSPFW3); | ||
2504 | reg |= PINEVIEW_SELF_REFRESH_EN; | ||
2505 | I915_WRITE(DSPFW3, reg); | ||
2506 | |||
2507 | DRM_INFO("Big FIFO is enabled\n"); | ||
2508 | |||
2509 | return; | ||
2510 | } | ||
2511 | |||
2512 | /* | 2699 | /* |
2513 | * Latency for FIFO fetches is dependent on several factors: | 2700 | * Latency for FIFO fetches is dependent on several factors: |
2514 | * - memory configuration (speed, channels) | 2701 | * - memory configuration (speed, channels) |
@@ -2593,6 +2780,71 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) | |||
2593 | return size; | 2780 | return size; |
2594 | } | 2781 | } |
2595 | 2782 | ||
2783 | static void pineview_update_wm(struct drm_device *dev, int planea_clock, | ||
2784 | int planeb_clock, int sr_hdisplay, int pixel_size) | ||
2785 | { | ||
2786 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2787 | u32 reg; | ||
2788 | unsigned long wm; | ||
2789 | struct cxsr_latency *latency; | ||
2790 | int sr_clock; | ||
2791 | |||
2792 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq, | ||
2793 | dev_priv->mem_freq); | ||
2794 | if (!latency) { | ||
2795 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | ||
2796 | pineview_disable_cxsr(dev); | ||
2797 | return; | ||
2798 | } | ||
2799 | |||
2800 | if (!planea_clock || !planeb_clock) { | ||
2801 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
2802 | |||
2803 | /* Display SR */ | ||
2804 | wm = intel_calculate_wm(sr_clock, &pineview_display_wm, | ||
2805 | pixel_size, latency->display_sr); | ||
2806 | reg = I915_READ(DSPFW1); | ||
2807 | reg &= ~DSPFW_SR_MASK; | ||
2808 | reg |= wm << DSPFW_SR_SHIFT; | ||
2809 | I915_WRITE(DSPFW1, reg); | ||
2810 | DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); | ||
2811 | |||
2812 | /* cursor SR */ | ||
2813 | wm = intel_calculate_wm(sr_clock, &pineview_cursor_wm, | ||
2814 | pixel_size, latency->cursor_sr); | ||
2815 | reg = I915_READ(DSPFW3); | ||
2816 | reg &= ~DSPFW_CURSOR_SR_MASK; | ||
2817 | reg |= (wm & 0x3f) << DSPFW_CURSOR_SR_SHIFT; | ||
2818 | I915_WRITE(DSPFW3, reg); | ||
2819 | |||
2820 | /* Display HPLL off SR */ | ||
2821 | wm = intel_calculate_wm(sr_clock, &pineview_display_hplloff_wm, | ||
2822 | pixel_size, latency->display_hpll_disable); | ||
2823 | reg = I915_READ(DSPFW3); | ||
2824 | reg &= ~DSPFW_HPLL_SR_MASK; | ||
2825 | reg |= wm & DSPFW_HPLL_SR_MASK; | ||
2826 | I915_WRITE(DSPFW3, reg); | ||
2827 | |||
2828 | /* cursor HPLL off SR */ | ||
2829 | wm = intel_calculate_wm(sr_clock, &pineview_cursor_hplloff_wm, | ||
2830 | pixel_size, latency->cursor_hpll_disable); | ||
2831 | reg = I915_READ(DSPFW3); | ||
2832 | reg &= ~DSPFW_HPLL_CURSOR_MASK; | ||
2833 | reg |= (wm & 0x3f) << DSPFW_HPLL_CURSOR_SHIFT; | ||
2834 | I915_WRITE(DSPFW3, reg); | ||
2835 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | ||
2836 | |||
2837 | /* activate cxsr */ | ||
2838 | reg = I915_READ(DSPFW3); | ||
2839 | reg |= PINEVIEW_SELF_REFRESH_EN; | ||
2840 | I915_WRITE(DSPFW3, reg); | ||
2841 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); | ||
2842 | } else { | ||
2843 | pineview_disable_cxsr(dev); | ||
2844 | DRM_DEBUG_KMS("Self-refresh is disabled\n"); | ||
2845 | } | ||
2846 | } | ||
2847 | |||
2596 | static void g4x_update_wm(struct drm_device *dev, int planea_clock, | 2848 | static void g4x_update_wm(struct drm_device *dev, int planea_clock, |
2597 | int planeb_clock, int sr_hdisplay, int pixel_size) | 2849 | int planeb_clock, int sr_hdisplay, int pixel_size) |
2598 | { | 2850 | { |
@@ -2813,6 +3065,108 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, | |||
2813 | I915_WRITE(FW_BLC, fwater_lo); | 3065 | I915_WRITE(FW_BLC, fwater_lo); |
2814 | } | 3066 | } |
2815 | 3067 | ||
3068 | #define ILK_LP0_PLANE_LATENCY 700 | ||
3069 | |||
3070 | static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | ||
3071 | int planeb_clock, int sr_hdisplay, int pixel_size) | ||
3072 | { | ||
3073 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3074 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | ||
3075 | int sr_wm, cursor_wm; | ||
3076 | unsigned long line_time_us; | ||
3077 | int sr_clock, entries_required; | ||
3078 | u32 reg_value; | ||
3079 | |||
3080 | /* Calculate and update the watermark for plane A */ | ||
3081 | if (planea_clock) { | ||
3082 | entries_required = ((planea_clock / 1000) * pixel_size * | ||
3083 | ILK_LP0_PLANE_LATENCY) / 1000; | ||
3084 | entries_required = DIV_ROUND_UP(entries_required, | ||
3085 | ironlake_display_wm_info.cacheline_size); | ||
3086 | planea_wm = entries_required + | ||
3087 | ironlake_display_wm_info.guard_size; | ||
3088 | |||
3089 | if (planea_wm > (int)ironlake_display_wm_info.max_wm) | ||
3090 | planea_wm = ironlake_display_wm_info.max_wm; | ||
3091 | |||
3092 | cursora_wm = 16; | ||
3093 | reg_value = I915_READ(WM0_PIPEA_ILK); | ||
3094 | reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
3095 | reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) | | ||
3096 | (cursora_wm & WM0_PIPE_CURSOR_MASK); | ||
3097 | I915_WRITE(WM0_PIPEA_ILK, reg_value); | ||
3098 | DRM_DEBUG_KMS("FIFO watermarks For pipe A - plane %d, " | ||
3099 | "cursor: %d\n", planea_wm, cursora_wm); | ||
3100 | } | ||
3101 | /* Calculate and update the watermark for plane B */ | ||
3102 | if (planeb_clock) { | ||
3103 | entries_required = ((planeb_clock / 1000) * pixel_size * | ||
3104 | ILK_LP0_PLANE_LATENCY) / 1000; | ||
3105 | entries_required = DIV_ROUND_UP(entries_required, | ||
3106 | ironlake_display_wm_info.cacheline_size); | ||
3107 | planeb_wm = entries_required + | ||
3108 | ironlake_display_wm_info.guard_size; | ||
3109 | |||
3110 | if (planeb_wm > (int)ironlake_display_wm_info.max_wm) | ||
3111 | planeb_wm = ironlake_display_wm_info.max_wm; | ||
3112 | |||
3113 | cursorb_wm = 16; | ||
3114 | reg_value = I915_READ(WM0_PIPEB_ILK); | ||
3115 | reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
3116 | reg_value |= (planeb_wm << WM0_PIPE_PLANE_SHIFT) | | ||
3117 | (cursorb_wm & WM0_PIPE_CURSOR_MASK); | ||
3118 | I915_WRITE(WM0_PIPEB_ILK, reg_value); | ||
3119 | DRM_DEBUG_KMS("FIFO watermarks For pipe B - plane %d, " | ||
3120 | "cursor: %d\n", planeb_wm, cursorb_wm); | ||
3121 | } | ||
3122 | |||
3123 | /* | ||
3124 | * Calculate and update the self-refresh watermark only when one | ||
3125 | * display plane is used. | ||
3126 | */ | ||
3127 | if (!planea_clock || !planeb_clock) { | ||
3128 | int line_count; | ||
3129 | /* Read the self-refresh latency. The unit is 0.5us */ | ||
3130 | int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK; | ||
3131 | |||
3132 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
3133 | line_time_us = ((sr_hdisplay * 1000) / sr_clock); | ||
3134 | |||
3135 | /* Use ns/us then divide to preserve precision */ | ||
3136 | line_count = ((ilk_sr_latency * 500) / line_time_us + 1000) | ||
3137 | / 1000; | ||
3138 | |||
3139 | /* calculate the self-refresh watermark for display plane */ | ||
3140 | entries_required = line_count * sr_hdisplay * pixel_size; | ||
3141 | entries_required = DIV_ROUND_UP(entries_required, | ||
3142 | ironlake_display_srwm_info.cacheline_size); | ||
3143 | sr_wm = entries_required + | ||
3144 | ironlake_display_srwm_info.guard_size; | ||
3145 | |||
3146 | /* calculate the self-refresh watermark for display cursor */ | ||
3147 | entries_required = line_count * pixel_size * 64; | ||
3148 | entries_required = DIV_ROUND_UP(entries_required, | ||
3149 | ironlake_cursor_srwm_info.cacheline_size); | ||
3150 | cursor_wm = entries_required + | ||
3151 | ironlake_cursor_srwm_info.guard_size; | ||
3152 | |||
3153 | /* configure watermark and enable self-refresh */ | ||
3154 | reg_value = I915_READ(WM1_LP_ILK); | ||
3155 | reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK | | ||
3156 | WM1_LP_CURSOR_MASK); | ||
3157 | reg_value |= WM1_LP_SR_EN | | ||
3158 | (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) | | ||
3159 | (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm; | ||
3160 | |||
3161 | I915_WRITE(WM1_LP_ILK, reg_value); | ||
3162 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d " | ||
3163 | "cursor %d\n", sr_wm, cursor_wm); | ||
3164 | |||
3165 | } else { | ||
3166 | /* Turn off self refresh if both pipes are enabled */ | ||
3167 | I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN); | ||
3168 | } | ||
3169 | } | ||
2816 | /** | 3170 | /** |
2817 | * intel_update_watermarks - update FIFO watermark values based on current modes | 3171 | * intel_update_watermarks - update FIFO watermark values based on current modes |
2818 | * | 3172 | * |
@@ -2882,12 +3236,6 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
2882 | if (enabled <= 0) | 3236 | if (enabled <= 0) |
2883 | return; | 3237 | return; |
2884 | 3238 | ||
2885 | /* Single plane configs can enable self refresh */ | ||
2886 | if (enabled == 1 && IS_PINEVIEW(dev)) | ||
2887 | pineview_enable_cxsr(dev, sr_clock, pixel_size); | ||
2888 | else if (IS_PINEVIEW(dev)) | ||
2889 | pineview_disable_cxsr(dev); | ||
2890 | |||
2891 | dev_priv->display.update_wm(dev, planea_clock, planeb_clock, | 3239 | dev_priv->display.update_wm(dev, planea_clock, planeb_clock, |
2892 | sr_hdisplay, pixel_size); | 3240 | sr_hdisplay, pixel_size); |
2893 | } | 3241 | } |
@@ -2924,7 +3272,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2924 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 3272 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
2925 | bool is_edp = false; | 3273 | bool is_edp = false; |
2926 | struct drm_mode_config *mode_config = &dev->mode_config; | 3274 | struct drm_mode_config *mode_config = &dev->mode_config; |
2927 | struct drm_connector *connector; | 3275 | struct drm_encoder *encoder; |
3276 | struct intel_encoder *intel_encoder = NULL; | ||
2928 | const intel_limit_t *limit; | 3277 | const intel_limit_t *limit; |
2929 | int ret; | 3278 | int ret; |
2930 | struct fdi_m_n m_n = {0}; | 3279 | struct fdi_m_n m_n = {0}; |
@@ -2935,6 +3284,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2935 | int pch_fp_reg = (pipe == 0) ? PCH_FPA0 : PCH_FPB0; | 3284 | int pch_fp_reg = (pipe == 0) ? PCH_FPA0 : PCH_FPB0; |
2936 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; | 3285 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; |
2937 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | 3286 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; |
3287 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | ||
3288 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | ||
2938 | int lvds_reg = LVDS; | 3289 | int lvds_reg = LVDS; |
2939 | u32 temp; | 3290 | u32 temp; |
2940 | int sdvo_pixel_multiply; | 3291 | int sdvo_pixel_multiply; |
@@ -2942,12 +3293,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2942 | 3293 | ||
2943 | drm_vblank_pre_modeset(dev, pipe); | 3294 | drm_vblank_pre_modeset(dev, pipe); |
2944 | 3295 | ||
2945 | list_for_each_entry(connector, &mode_config->connector_list, head) { | 3296 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
2946 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
2947 | 3297 | ||
2948 | if (!connector->encoder || connector->encoder->crtc != crtc) | 3298 | if (!encoder || encoder->crtc != crtc) |
2949 | continue; | 3299 | continue; |
2950 | 3300 | ||
3301 | intel_encoder = enc_to_intel_encoder(encoder); | ||
3302 | |||
2951 | switch (intel_encoder->type) { | 3303 | switch (intel_encoder->type) { |
2952 | case INTEL_OUTPUT_LVDS: | 3304 | case INTEL_OUTPUT_LVDS: |
2953 | is_lvds = true; | 3305 | is_lvds = true; |
@@ -3043,14 +3395,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3043 | 3395 | ||
3044 | /* FDI link */ | 3396 | /* FDI link */ |
3045 | if (HAS_PCH_SPLIT(dev)) { | 3397 | if (HAS_PCH_SPLIT(dev)) { |
3046 | int lane, link_bw, bpp; | 3398 | int lane = 0, link_bw, bpp; |
3047 | /* eDP doesn't require FDI link, so just set DP M/N | 3399 | /* eDP doesn't require FDI link, so just set DP M/N |
3048 | according to current link config */ | 3400 | according to current link config */ |
3049 | if (is_edp) { | 3401 | if (is_edp) { |
3050 | struct drm_connector *edp; | ||
3051 | target_clock = mode->clock; | 3402 | target_clock = mode->clock; |
3052 | edp = intel_pipe_get_connector(crtc); | 3403 | intel_edp_link_config(intel_encoder, |
3053 | intel_edp_link_config(to_intel_encoder(edp), | ||
3054 | &lane, &link_bw); | 3404 | &lane, &link_bw); |
3055 | } else { | 3405 | } else { |
3056 | /* DP over FDI requires target mode clock | 3406 | /* DP over FDI requires target mode clock |
@@ -3059,7 +3409,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3059 | target_clock = mode->clock; | 3409 | target_clock = mode->clock; |
3060 | else | 3410 | else |
3061 | target_clock = adjusted_mode->clock; | 3411 | target_clock = adjusted_mode->clock; |
3062 | lane = 4; | ||
3063 | link_bw = 270000; | 3412 | link_bw = 270000; |
3064 | } | 3413 | } |
3065 | 3414 | ||
@@ -3111,6 +3460,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3111 | bpp = 24; | 3460 | bpp = 24; |
3112 | } | 3461 | } |
3113 | 3462 | ||
3463 | if (!lane) { | ||
3464 | /* | ||
3465 | * Account for spread spectrum to avoid | ||
3466 | * oversubscribing the link. Max center spread | ||
3467 | * is 2.5%; use 5% for safety's sake. | ||
3468 | */ | ||
3469 | u32 bps = target_clock * bpp * 21 / 20; | ||
3470 | lane = bps / (link_bw * 8) + 1; | ||
3471 | } | ||
3472 | |||
3473 | intel_crtc->fdi_lanes = lane; | ||
3474 | |||
3114 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); | 3475 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); |
3115 | } | 3476 | } |
3116 | 3477 | ||
@@ -3265,11 +3626,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3265 | pipeconf &= ~PIPEACONF_DOUBLE_WIDE; | 3626 | pipeconf &= ~PIPEACONF_DOUBLE_WIDE; |
3266 | } | 3627 | } |
3267 | 3628 | ||
3268 | dspcntr |= DISPLAY_PLANE_ENABLE; | ||
3269 | pipeconf |= PIPEACONF_ENABLE; | ||
3270 | dpll |= DPLL_VCO_ENABLE; | ||
3271 | |||
3272 | |||
3273 | /* Disable the panel fitter if it was on our pipe */ | 3629 | /* Disable the panel fitter if it was on our pipe */ |
3274 | if (!HAS_PCH_SPLIT(dev) && intel_panel_fitter_pipe(dev) == pipe) | 3630 | if (!HAS_PCH_SPLIT(dev) && intel_panel_fitter_pipe(dev) == pipe) |
3275 | I915_WRITE(PFIT_CONTROL, 0); | 3631 | I915_WRITE(PFIT_CONTROL, 0); |
@@ -3292,6 +3648,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3292 | udelay(150); | 3648 | udelay(150); |
3293 | } | 3649 | } |
3294 | 3650 | ||
3651 | /* enable transcoder DPLL */ | ||
3652 | if (HAS_PCH_CPT(dev)) { | ||
3653 | temp = I915_READ(PCH_DPLL_SEL); | ||
3654 | if (trans_dpll_sel == 0) | ||
3655 | temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); | ||
3656 | else | ||
3657 | temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); | ||
3658 | I915_WRITE(PCH_DPLL_SEL, temp); | ||
3659 | I915_READ(PCH_DPLL_SEL); | ||
3660 | udelay(150); | ||
3661 | } | ||
3662 | |||
3295 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 3663 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
3296 | * This is an exception to the general rule that mode_set doesn't turn | 3664 | * This is an exception to the general rule that mode_set doesn't turn |
3297 | * things on. | 3665 | * things on. |
@@ -3303,7 +3671,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3303 | lvds_reg = PCH_LVDS; | 3671 | lvds_reg = PCH_LVDS; |
3304 | 3672 | ||
3305 | lvds = I915_READ(lvds_reg); | 3673 | lvds = I915_READ(lvds_reg); |
3306 | lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; | 3674 | lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; |
3675 | if (pipe == 1) { | ||
3676 | if (HAS_PCH_CPT(dev)) | ||
3677 | lvds |= PORT_TRANS_B_SEL_CPT; | ||
3678 | else | ||
3679 | lvds |= LVDS_PIPEB_SELECT; | ||
3680 | } else { | ||
3681 | if (HAS_PCH_CPT(dev)) | ||
3682 | lvds &= ~PORT_TRANS_SEL_MASK; | ||
3683 | else | ||
3684 | lvds &= ~LVDS_PIPEB_SELECT; | ||
3685 | } | ||
3307 | /* set the corresponsding LVDS_BORDER bit */ | 3686 | /* set the corresponsding LVDS_BORDER bit */ |
3308 | lvds |= dev_priv->lvds_border_bits; | 3687 | lvds |= dev_priv->lvds_border_bits; |
3309 | /* Set the B0-B3 data pairs corresponding to whether we're going to | 3688 | /* Set the B0-B3 data pairs corresponding to whether we're going to |
@@ -3321,14 +3700,16 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3321 | /* set the dithering flag */ | 3700 | /* set the dithering flag */ |
3322 | if (IS_I965G(dev)) { | 3701 | if (IS_I965G(dev)) { |
3323 | if (dev_priv->lvds_dither) { | 3702 | if (dev_priv->lvds_dither) { |
3324 | if (HAS_PCH_SPLIT(dev)) | 3703 | if (HAS_PCH_SPLIT(dev)) { |
3325 | pipeconf |= PIPE_ENABLE_DITHER; | 3704 | pipeconf |= PIPE_ENABLE_DITHER; |
3326 | else | 3705 | pipeconf |= PIPE_DITHER_TYPE_ST01; |
3706 | } else | ||
3327 | lvds |= LVDS_ENABLE_DITHER; | 3707 | lvds |= LVDS_ENABLE_DITHER; |
3328 | } else { | 3708 | } else { |
3329 | if (HAS_PCH_SPLIT(dev)) | 3709 | if (HAS_PCH_SPLIT(dev)) { |
3330 | pipeconf &= ~PIPE_ENABLE_DITHER; | 3710 | pipeconf &= ~PIPE_ENABLE_DITHER; |
3331 | else | 3711 | pipeconf &= ~PIPE_DITHER_TYPE_MASK; |
3712 | } else | ||
3332 | lvds &= ~LVDS_ENABLE_DITHER; | 3713 | lvds &= ~LVDS_ENABLE_DITHER; |
3333 | } | 3714 | } |
3334 | } | 3715 | } |
@@ -3337,6 +3718,20 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3337 | } | 3718 | } |
3338 | if (is_dp) | 3719 | if (is_dp) |
3339 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | 3720 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
3721 | else if (HAS_PCH_SPLIT(dev)) { | ||
3722 | /* For non-DP output, clear any trans DP clock recovery setting.*/ | ||
3723 | if (pipe == 0) { | ||
3724 | I915_WRITE(TRANSA_DATA_M1, 0); | ||
3725 | I915_WRITE(TRANSA_DATA_N1, 0); | ||
3726 | I915_WRITE(TRANSA_DP_LINK_M1, 0); | ||
3727 | I915_WRITE(TRANSA_DP_LINK_N1, 0); | ||
3728 | } else { | ||
3729 | I915_WRITE(TRANSB_DATA_M1, 0); | ||
3730 | I915_WRITE(TRANSB_DATA_N1, 0); | ||
3731 | I915_WRITE(TRANSB_DP_LINK_M1, 0); | ||
3732 | I915_WRITE(TRANSB_DP_LINK_N1, 0); | ||
3733 | } | ||
3734 | } | ||
3340 | 3735 | ||
3341 | if (!is_edp) { | 3736 | if (!is_edp) { |
3342 | I915_WRITE(fp_reg, fp); | 3737 | I915_WRITE(fp_reg, fp); |
@@ -3411,6 +3806,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3411 | /* enable FDI RX PLL too */ | 3806 | /* enable FDI RX PLL too */ |
3412 | temp = I915_READ(fdi_rx_reg); | 3807 | temp = I915_READ(fdi_rx_reg); |
3413 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | 3808 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); |
3809 | I915_READ(fdi_rx_reg); | ||
3810 | udelay(200); | ||
3811 | |||
3812 | /* enable FDI TX PLL too */ | ||
3813 | temp = I915_READ(fdi_tx_reg); | ||
3814 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | ||
3815 | I915_READ(fdi_tx_reg); | ||
3816 | |||
3817 | /* enable FDI RX PCDCLK */ | ||
3818 | temp = I915_READ(fdi_rx_reg); | ||
3819 | I915_WRITE(fdi_rx_reg, temp | FDI_SEL_PCDCLK); | ||
3820 | I915_READ(fdi_rx_reg); | ||
3414 | udelay(200); | 3821 | udelay(200); |
3415 | } | 3822 | } |
3416 | } | 3823 | } |
@@ -3671,6 +4078,7 @@ static struct drm_display_mode load_detect_mode = { | |||
3671 | }; | 4078 | }; |
3672 | 4079 | ||
3673 | struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 4080 | struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
4081 | struct drm_connector *connector, | ||
3674 | struct drm_display_mode *mode, | 4082 | struct drm_display_mode *mode, |
3675 | int *dpms_mode) | 4083 | int *dpms_mode) |
3676 | { | 4084 | { |
@@ -3729,7 +4137,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
3729 | } | 4137 | } |
3730 | 4138 | ||
3731 | encoder->crtc = crtc; | 4139 | encoder->crtc = crtc; |
3732 | intel_encoder->base.encoder = encoder; | 4140 | connector->encoder = encoder; |
3733 | intel_encoder->load_detect_temp = true; | 4141 | intel_encoder->load_detect_temp = true; |
3734 | 4142 | ||
3735 | intel_crtc = to_intel_crtc(crtc); | 4143 | intel_crtc = to_intel_crtc(crtc); |
@@ -3755,7 +4163,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
3755 | return crtc; | 4163 | return crtc; |
3756 | } | 4164 | } |
3757 | 4165 | ||
3758 | void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode) | 4166 | void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, |
4167 | struct drm_connector *connector, int dpms_mode) | ||
3759 | { | 4168 | { |
3760 | struct drm_encoder *encoder = &intel_encoder->enc; | 4169 | struct drm_encoder *encoder = &intel_encoder->enc; |
3761 | struct drm_device *dev = encoder->dev; | 4170 | struct drm_device *dev = encoder->dev; |
@@ -3765,7 +4174,7 @@ void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpm | |||
3765 | 4174 | ||
3766 | if (intel_encoder->load_detect_temp) { | 4175 | if (intel_encoder->load_detect_temp) { |
3767 | encoder->crtc = NULL; | 4176 | encoder->crtc = NULL; |
3768 | intel_encoder->base.encoder = NULL; | 4177 | connector->encoder = NULL; |
3769 | intel_encoder->load_detect_temp = false; | 4178 | intel_encoder->load_detect_temp = false; |
3770 | crtc->enabled = drm_helper_crtc_in_use(crtc); | 4179 | crtc->enabled = drm_helper_crtc_in_use(crtc); |
3771 | drm_helper_disable_unused_functions(dev); | 4180 | drm_helper_disable_unused_functions(dev); |
@@ -4392,14 +4801,14 @@ struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) | |||
4392 | return crtc; | 4801 | return crtc; |
4393 | } | 4802 | } |
4394 | 4803 | ||
4395 | static int intel_connector_clones(struct drm_device *dev, int type_mask) | 4804 | static int intel_encoder_clones(struct drm_device *dev, int type_mask) |
4396 | { | 4805 | { |
4397 | int index_mask = 0; | 4806 | int index_mask = 0; |
4398 | struct drm_connector *connector; | 4807 | struct drm_encoder *encoder; |
4399 | int entry = 0; | 4808 | int entry = 0; |
4400 | 4809 | ||
4401 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 4810 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
4402 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 4811 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
4403 | if (type_mask & intel_encoder->clone_mask) | 4812 | if (type_mask & intel_encoder->clone_mask) |
4404 | index_mask |= (1 << entry); | 4813 | index_mask |= (1 << entry); |
4405 | entry++; | 4814 | entry++; |
@@ -4411,7 +4820,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) | |||
4411 | static void intel_setup_outputs(struct drm_device *dev) | 4820 | static void intel_setup_outputs(struct drm_device *dev) |
4412 | { | 4821 | { |
4413 | struct drm_i915_private *dev_priv = dev->dev_private; | 4822 | struct drm_i915_private *dev_priv = dev->dev_private; |
4414 | struct drm_connector *connector; | 4823 | struct drm_encoder *encoder; |
4415 | 4824 | ||
4416 | intel_crt_init(dev); | 4825 | intel_crt_init(dev); |
4417 | 4826 | ||
@@ -4426,9 +4835,8 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
4426 | intel_dp_init(dev, DP_A); | 4835 | intel_dp_init(dev, DP_A); |
4427 | 4836 | ||
4428 | if (I915_READ(HDMIB) & PORT_DETECTED) { | 4837 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
4429 | /* check SDVOB */ | 4838 | /* PCH SDVOB multiplex with HDMIB */ |
4430 | /* found = intel_sdvo_init(dev, HDMIB); */ | 4839 | found = intel_sdvo_init(dev, PCH_SDVOB); |
4431 | found = 0; | ||
4432 | if (!found) | 4840 | if (!found) |
4433 | intel_hdmi_init(dev, HDMIB); | 4841 | intel_hdmi_init(dev, HDMIB); |
4434 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) | 4842 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) |
@@ -4494,12 +4902,11 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
4494 | if (SUPPORTS_TV(dev)) | 4902 | if (SUPPORTS_TV(dev)) |
4495 | intel_tv_init(dev); | 4903 | intel_tv_init(dev); |
4496 | 4904 | ||
4497 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 4905 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
4498 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 4906 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
4499 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
4500 | 4907 | ||
4501 | encoder->possible_crtcs = intel_encoder->crtc_mask; | 4908 | encoder->possible_crtcs = intel_encoder->crtc_mask; |
4502 | encoder->possible_clones = intel_connector_clones(dev, | 4909 | encoder->possible_clones = intel_encoder_clones(dev, |
4503 | intel_encoder->clone_mask); | 4910 | intel_encoder->clone_mask); |
4504 | } | 4911 | } |
4505 | } | 4912 | } |
@@ -4507,10 +4914,6 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
4507 | static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) | 4914 | static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) |
4508 | { | 4915 | { |
4509 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 4916 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
4510 | struct drm_device *dev = fb->dev; | ||
4511 | |||
4512 | if (fb->fbdev) | ||
4513 | intelfb_remove(dev, fb); | ||
4514 | 4917 | ||
4515 | drm_framebuffer_cleanup(fb); | 4918 | drm_framebuffer_cleanup(fb); |
4516 | drm_gem_object_unreference_unlocked(intel_fb->obj); | 4919 | drm_gem_object_unreference_unlocked(intel_fb->obj); |
@@ -4533,18 +4936,13 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = { | |||
4533 | .create_handle = intel_user_framebuffer_create_handle, | 4936 | .create_handle = intel_user_framebuffer_create_handle, |
4534 | }; | 4937 | }; |
4535 | 4938 | ||
4536 | int intel_framebuffer_create(struct drm_device *dev, | 4939 | int intel_framebuffer_init(struct drm_device *dev, |
4537 | struct drm_mode_fb_cmd *mode_cmd, | 4940 | struct intel_framebuffer *intel_fb, |
4538 | struct drm_framebuffer **fb, | 4941 | struct drm_mode_fb_cmd *mode_cmd, |
4539 | struct drm_gem_object *obj) | 4942 | struct drm_gem_object *obj) |
4540 | { | 4943 | { |
4541 | struct intel_framebuffer *intel_fb; | ||
4542 | int ret; | 4944 | int ret; |
4543 | 4945 | ||
4544 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); | ||
4545 | if (!intel_fb) | ||
4546 | return -ENOMEM; | ||
4547 | |||
4548 | ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); | 4946 | ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); |
4549 | if (ret) { | 4947 | if (ret) { |
4550 | DRM_ERROR("framebuffer init failed %d\n", ret); | 4948 | DRM_ERROR("framebuffer init failed %d\n", ret); |
@@ -4552,40 +4950,41 @@ int intel_framebuffer_create(struct drm_device *dev, | |||
4552 | } | 4950 | } |
4553 | 4951 | ||
4554 | drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd); | 4952 | drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd); |
4555 | |||
4556 | intel_fb->obj = obj; | 4953 | intel_fb->obj = obj; |
4557 | |||
4558 | *fb = &intel_fb->base; | ||
4559 | |||
4560 | return 0; | 4954 | return 0; |
4561 | } | 4955 | } |
4562 | 4956 | ||
4563 | |||
4564 | static struct drm_framebuffer * | 4957 | static struct drm_framebuffer * |
4565 | intel_user_framebuffer_create(struct drm_device *dev, | 4958 | intel_user_framebuffer_create(struct drm_device *dev, |
4566 | struct drm_file *filp, | 4959 | struct drm_file *filp, |
4567 | struct drm_mode_fb_cmd *mode_cmd) | 4960 | struct drm_mode_fb_cmd *mode_cmd) |
4568 | { | 4961 | { |
4569 | struct drm_gem_object *obj; | 4962 | struct drm_gem_object *obj; |
4570 | struct drm_framebuffer *fb; | 4963 | struct intel_framebuffer *intel_fb; |
4571 | int ret; | 4964 | int ret; |
4572 | 4965 | ||
4573 | obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle); | 4966 | obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle); |
4574 | if (!obj) | 4967 | if (!obj) |
4575 | return NULL; | 4968 | return NULL; |
4576 | 4969 | ||
4577 | ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj); | 4970 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); |
4971 | if (!intel_fb) | ||
4972 | return NULL; | ||
4973 | |||
4974 | ret = intel_framebuffer_init(dev, intel_fb, | ||
4975 | mode_cmd, obj); | ||
4578 | if (ret) { | 4976 | if (ret) { |
4579 | drm_gem_object_unreference_unlocked(obj); | 4977 | drm_gem_object_unreference_unlocked(obj); |
4978 | kfree(intel_fb); | ||
4580 | return NULL; | 4979 | return NULL; |
4581 | } | 4980 | } |
4582 | 4981 | ||
4583 | return fb; | 4982 | return &intel_fb->base; |
4584 | } | 4983 | } |
4585 | 4984 | ||
4586 | static const struct drm_mode_config_funcs intel_mode_funcs = { | 4985 | static const struct drm_mode_config_funcs intel_mode_funcs = { |
4587 | .fb_create = intel_user_framebuffer_create, | 4986 | .fb_create = intel_user_framebuffer_create, |
4588 | .fb_changed = intelfb_probe, | 4987 | .output_poll_changed = intel_fb_output_poll_changed, |
4589 | }; | 4988 | }; |
4590 | 4989 | ||
4591 | static struct drm_gem_object * | 4990 | static struct drm_gem_object * |
@@ -4594,7 +4993,7 @@ intel_alloc_power_context(struct drm_device *dev) | |||
4594 | struct drm_gem_object *pwrctx; | 4993 | struct drm_gem_object *pwrctx; |
4595 | int ret; | 4994 | int ret; |
4596 | 4995 | ||
4597 | pwrctx = drm_gem_object_alloc(dev, 4096); | 4996 | pwrctx = i915_gem_alloc_object(dev, 4096); |
4598 | if (!pwrctx) { | 4997 | if (!pwrctx) { |
4599 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | 4998 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); |
4600 | return NULL; | 4999 | return NULL; |
@@ -4732,6 +5131,25 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
4732 | } | 5131 | } |
4733 | 5132 | ||
4734 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | 5133 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); |
5134 | |||
5135 | /* | ||
5136 | * According to the spec the following bits should be set in | ||
5137 | * order to enable memory self-refresh | ||
5138 | * The bit 22/21 of 0x42004 | ||
5139 | * The bit 5 of 0x42020 | ||
5140 | * The bit 15 of 0x45000 | ||
5141 | */ | ||
5142 | if (IS_IRONLAKE(dev)) { | ||
5143 | I915_WRITE(ILK_DISPLAY_CHICKEN2, | ||
5144 | (I915_READ(ILK_DISPLAY_CHICKEN2) | | ||
5145 | ILK_DPARB_GATE | ILK_VSDPFD_FULL)); | ||
5146 | I915_WRITE(ILK_DSPCLK_GATE, | ||
5147 | (I915_READ(ILK_DSPCLK_GATE) | | ||
5148 | ILK_DPARB_CLK_GATE)); | ||
5149 | I915_WRITE(DISP_ARB_CTL, | ||
5150 | (I915_READ(DISP_ARB_CTL) | | ||
5151 | DISP_FBC_WM_DIS)); | ||
5152 | } | ||
4735 | return; | 5153 | return; |
4736 | } else if (IS_G4X(dev)) { | 5154 | } else if (IS_G4X(dev)) { |
4737 | uint32_t dspclk_gate; | 5155 | uint32_t dspclk_gate; |
@@ -4809,8 +5227,7 @@ static void intel_init_display(struct drm_device *dev) | |||
4809 | else | 5227 | else |
4810 | dev_priv->display.dpms = i9xx_crtc_dpms; | 5228 | dev_priv->display.dpms = i9xx_crtc_dpms; |
4811 | 5229 | ||
4812 | /* Only mobile has FBC, leave pointers NULL for other chips */ | 5230 | if (I915_HAS_FBC(dev)) { |
4813 | if (IS_MOBILE(dev)) { | ||
4814 | if (IS_GM45(dev)) { | 5231 | if (IS_GM45(dev)) { |
4815 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; | 5232 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; |
4816 | dev_priv->display.enable_fbc = g4x_enable_fbc; | 5233 | dev_priv->display.enable_fbc = g4x_enable_fbc; |
@@ -4847,23 +5264,46 @@ static void intel_init_display(struct drm_device *dev) | |||
4847 | i830_get_display_clock_speed; | 5264 | i830_get_display_clock_speed; |
4848 | 5265 | ||
4849 | /* For FIFO watermark updates */ | 5266 | /* For FIFO watermark updates */ |
4850 | if (HAS_PCH_SPLIT(dev)) | 5267 | if (HAS_PCH_SPLIT(dev)) { |
4851 | dev_priv->display.update_wm = NULL; | 5268 | if (IS_IRONLAKE(dev)) { |
4852 | else if (IS_G4X(dev)) | 5269 | if (I915_READ(MLTR_ILK) & ILK_SRLT_MASK) |
5270 | dev_priv->display.update_wm = ironlake_update_wm; | ||
5271 | else { | ||
5272 | DRM_DEBUG_KMS("Failed to get proper latency. " | ||
5273 | "Disable CxSR\n"); | ||
5274 | dev_priv->display.update_wm = NULL; | ||
5275 | } | ||
5276 | } else | ||
5277 | dev_priv->display.update_wm = NULL; | ||
5278 | } else if (IS_PINEVIEW(dev)) { | ||
5279 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), | ||
5280 | dev_priv->fsb_freq, | ||
5281 | dev_priv->mem_freq)) { | ||
5282 | DRM_INFO("failed to find known CxSR latency " | ||
5283 | "(found fsb freq %d, mem freq %d), " | ||
5284 | "disabling CxSR\n", | ||
5285 | dev_priv->fsb_freq, dev_priv->mem_freq); | ||
5286 | /* Disable CxSR and never update its watermark again */ | ||
5287 | pineview_disable_cxsr(dev); | ||
5288 | dev_priv->display.update_wm = NULL; | ||
5289 | } else | ||
5290 | dev_priv->display.update_wm = pineview_update_wm; | ||
5291 | } else if (IS_G4X(dev)) | ||
4853 | dev_priv->display.update_wm = g4x_update_wm; | 5292 | dev_priv->display.update_wm = g4x_update_wm; |
4854 | else if (IS_I965G(dev)) | 5293 | else if (IS_I965G(dev)) |
4855 | dev_priv->display.update_wm = i965_update_wm; | 5294 | dev_priv->display.update_wm = i965_update_wm; |
4856 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) { | 5295 | else if (IS_I9XX(dev)) { |
4857 | dev_priv->display.update_wm = i9xx_update_wm; | 5296 | dev_priv->display.update_wm = i9xx_update_wm; |
4858 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; | 5297 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; |
5298 | } else if (IS_I85X(dev)) { | ||
5299 | dev_priv->display.update_wm = i9xx_update_wm; | ||
5300 | dev_priv->display.get_fifo_size = i85x_get_fifo_size; | ||
4859 | } else { | 5301 | } else { |
4860 | if (IS_I85X(dev)) | 5302 | dev_priv->display.update_wm = i830_update_wm; |
4861 | dev_priv->display.get_fifo_size = i85x_get_fifo_size; | 5303 | if (IS_845G(dev)) |
4862 | else if (IS_845G(dev)) | ||
4863 | dev_priv->display.get_fifo_size = i845_get_fifo_size; | 5304 | dev_priv->display.get_fifo_size = i845_get_fifo_size; |
4864 | else | 5305 | else |
4865 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | 5306 | dev_priv->display.get_fifo_size = i830_get_fifo_size; |
4866 | dev_priv->display.update_wm = i830_update_wm; | ||
4867 | } | 5307 | } |
4868 | } | 5308 | } |
4869 | 5309 | ||
@@ -4922,13 +5362,6 @@ void intel_modeset_init(struct drm_device *dev) | |||
4922 | (unsigned long)dev); | 5362 | (unsigned long)dev); |
4923 | 5363 | ||
4924 | intel_setup_overlay(dev); | 5364 | intel_setup_overlay(dev); |
4925 | |||
4926 | if (IS_PINEVIEW(dev) && !intel_get_cxsr_latency(IS_PINEVIEW_G(dev), | ||
4927 | dev_priv->fsb_freq, | ||
4928 | dev_priv->mem_freq)) | ||
4929 | DRM_INFO("failed to find known CxSR latency " | ||
4930 | "(found fsb freq %d, mem freq %d), disabling CxSR\n", | ||
4931 | dev_priv->fsb_freq, dev_priv->mem_freq); | ||
4932 | } | 5365 | } |
4933 | 5366 | ||
4934 | void intel_modeset_cleanup(struct drm_device *dev) | 5367 | void intel_modeset_cleanup(struct drm_device *dev) |
@@ -4939,6 +5372,9 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
4939 | 5372 | ||
4940 | mutex_lock(&dev->struct_mutex); | 5373 | mutex_lock(&dev->struct_mutex); |
4941 | 5374 | ||
5375 | drm_kms_helper_poll_fini(dev); | ||
5376 | intel_fbdev_fini(dev); | ||
5377 | |||
4942 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 5378 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
4943 | /* Skip inactive CRTCs */ | 5379 | /* Skip inactive CRTCs */ |
4944 | if (!crtc->fb) | 5380 | if (!crtc->fb) |
@@ -4973,14 +5409,29 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
4973 | } | 5409 | } |
4974 | 5410 | ||
4975 | 5411 | ||
4976 | /* current intel driver doesn't take advantage of encoders | 5412 | /* |
4977 | always give back the encoder for the connector | 5413 | * Return which encoder is currently attached for connector. |
4978 | */ | 5414 | */ |
4979 | struct drm_encoder *intel_best_encoder(struct drm_connector *connector) | 5415 | struct drm_encoder *intel_attached_encoder (struct drm_connector *connector) |
4980 | { | 5416 | { |
4981 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 5417 | struct drm_mode_object *obj; |
5418 | struct drm_encoder *encoder; | ||
5419 | int i; | ||
4982 | 5420 | ||
4983 | return &intel_encoder->enc; | 5421 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
5422 | if (connector->encoder_ids[i] == 0) | ||
5423 | break; | ||
5424 | |||
5425 | obj = drm_mode_object_find(connector->dev, | ||
5426 | connector->encoder_ids[i], | ||
5427 | DRM_MODE_OBJECT_ENCODER); | ||
5428 | if (!obj) | ||
5429 | continue; | ||
5430 | |||
5431 | encoder = obj_to_encoder(obj); | ||
5432 | return encoder; | ||
5433 | } | ||
5434 | return NULL; | ||
4984 | } | 5435 | } |
4985 | 5436 | ||
4986 | /* | 5437 | /* |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 77e40cfcf216..6b1c9a27c27a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -48,8 +48,6 @@ struct intel_dp_priv { | |||
48 | uint32_t output_reg; | 48 | uint32_t output_reg; |
49 | uint32_t DP; | 49 | uint32_t DP; |
50 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | 50 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; |
51 | uint32_t save_DP; | ||
52 | uint8_t save_link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
53 | bool has_audio; | 51 | bool has_audio; |
54 | int dpms_mode; | 52 | int dpms_mode; |
55 | uint8_t link_bw; | 53 | uint8_t link_bw; |
@@ -141,7 +139,8 @@ static int | |||
141 | intel_dp_mode_valid(struct drm_connector *connector, | 139 | intel_dp_mode_valid(struct drm_connector *connector, |
142 | struct drm_display_mode *mode) | 140 | struct drm_display_mode *mode) |
143 | { | 141 | { |
144 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 142 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
143 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
145 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); | 144 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); |
146 | int max_lanes = intel_dp_max_lane_count(intel_encoder); | 145 | int max_lanes = intel_dp_max_lane_count(intel_encoder); |
147 | 146 | ||
@@ -215,7 +214,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
215 | { | 214 | { |
216 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 215 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
217 | uint32_t output_reg = dp_priv->output_reg; | 216 | uint32_t output_reg = dp_priv->output_reg; |
218 | struct drm_device *dev = intel_encoder->base.dev; | 217 | struct drm_device *dev = intel_encoder->enc.dev; |
219 | struct drm_i915_private *dev_priv = dev->dev_private; | 218 | struct drm_i915_private *dev_priv = dev->dev_private; |
220 | uint32_t ch_ctl = output_reg + 0x10; | 219 | uint32_t ch_ctl = output_reg + 0x10; |
221 | uint32_t ch_data = ch_ctl + 4; | 220 | uint32_t ch_data = ch_ctl + 4; |
@@ -224,19 +223,27 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
224 | uint32_t ctl; | 223 | uint32_t ctl; |
225 | uint32_t status; | 224 | uint32_t status; |
226 | uint32_t aux_clock_divider; | 225 | uint32_t aux_clock_divider; |
227 | int try; | 226 | int try, precharge; |
228 | 227 | ||
229 | /* The clock divider is based off the hrawclk, | 228 | /* The clock divider is based off the hrawclk, |
230 | * and would like to run at 2MHz. So, take the | 229 | * and would like to run at 2MHz. So, take the |
231 | * hrawclk value and divide by 2 and use that | 230 | * hrawclk value and divide by 2 and use that |
232 | */ | 231 | */ |
233 | if (IS_eDP(intel_encoder)) | 232 | if (IS_eDP(intel_encoder)) { |
234 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ | 233 | if (IS_GEN6(dev)) |
235 | else if (HAS_PCH_SPLIT(dev)) | 234 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ |
235 | else | ||
236 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ | ||
237 | } else if (HAS_PCH_SPLIT(dev)) | ||
236 | aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ | 238 | aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ |
237 | else | 239 | else |
238 | aux_clock_divider = intel_hrawclk(dev) / 2; | 240 | aux_clock_divider = intel_hrawclk(dev) / 2; |
239 | 241 | ||
242 | if (IS_GEN6(dev)) | ||
243 | precharge = 3; | ||
244 | else | ||
245 | precharge = 5; | ||
246 | |||
240 | /* Must try at least 3 times according to DP spec */ | 247 | /* Must try at least 3 times according to DP spec */ |
241 | for (try = 0; try < 5; try++) { | 248 | for (try = 0; try < 5; try++) { |
242 | /* Load the send data into the aux channel data registers */ | 249 | /* Load the send data into the aux channel data registers */ |
@@ -249,7 +256,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
249 | ctl = (DP_AUX_CH_CTL_SEND_BUSY | | 256 | ctl = (DP_AUX_CH_CTL_SEND_BUSY | |
250 | DP_AUX_CH_CTL_TIME_OUT_400us | | 257 | DP_AUX_CH_CTL_TIME_OUT_400us | |
251 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | 258 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | |
252 | (5 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | 259 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | |
253 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | 260 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | |
254 | DP_AUX_CH_CTL_DONE | | 261 | DP_AUX_CH_CTL_DONE | |
255 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | 262 | DP_AUX_CH_CTL_TIME_OUT_ERROR | |
@@ -465,7 +472,8 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
465 | } | 472 | } |
466 | 473 | ||
467 | static int | 474 | static int |
468 | intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name) | 475 | intel_dp_i2c_init(struct intel_encoder *intel_encoder, |
476 | struct intel_connector *intel_connector, const char *name) | ||
469 | { | 477 | { |
470 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 478 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
471 | 479 | ||
@@ -480,7 +488,7 @@ intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name) | |||
480 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); | 488 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); |
481 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; | 489 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; |
482 | dp_priv->adapter.algo_data = &dp_priv->algo; | 490 | dp_priv->adapter.algo_data = &dp_priv->algo; |
483 | dp_priv->adapter.dev.parent = &intel_encoder->base.kdev; | 491 | dp_priv->adapter.dev.parent = &intel_connector->base.kdev; |
484 | 492 | ||
485 | return i2c_dp_aux_add_bus(&dp_priv->adapter); | 493 | return i2c_dp_aux_add_bus(&dp_priv->adapter); |
486 | } | 494 | } |
@@ -555,7 +563,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
555 | { | 563 | { |
556 | struct drm_device *dev = crtc->dev; | 564 | struct drm_device *dev = crtc->dev; |
557 | struct drm_mode_config *mode_config = &dev->mode_config; | 565 | struct drm_mode_config *mode_config = &dev->mode_config; |
558 | struct drm_connector *connector; | 566 | struct drm_encoder *encoder; |
559 | struct drm_i915_private *dev_priv = dev->dev_private; | 567 | struct drm_i915_private *dev_priv = dev->dev_private; |
560 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 568 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
561 | int lane_count = 4; | 569 | int lane_count = 4; |
@@ -564,13 +572,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
564 | /* | 572 | /* |
565 | * Find the lane count in the intel_encoder private | 573 | * Find the lane count in the intel_encoder private |
566 | */ | 574 | */ |
567 | list_for_each_entry(connector, &mode_config->connector_list, head) { | 575 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
568 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 576 | struct intel_encoder *intel_encoder; |
569 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 577 | struct intel_dp_priv *dp_priv; |
570 | 578 | ||
571 | if (!connector->encoder || connector->encoder->crtc != crtc) | 579 | if (!encoder || encoder->crtc != crtc) |
572 | continue; | 580 | continue; |
573 | 581 | ||
582 | intel_encoder = enc_to_intel_encoder(encoder); | ||
583 | dp_priv = intel_encoder->dev_priv; | ||
584 | |||
574 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 585 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { |
575 | lane_count = dp_priv->lane_count; | 586 | lane_count = dp_priv->lane_count; |
576 | break; | 587 | break; |
@@ -626,16 +637,24 @@ static void | |||
626 | intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | 637 | intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, |
627 | struct drm_display_mode *adjusted_mode) | 638 | struct drm_display_mode *adjusted_mode) |
628 | { | 639 | { |
640 | struct drm_device *dev = encoder->dev; | ||
629 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 641 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
630 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 642 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
631 | struct drm_crtc *crtc = intel_encoder->enc.crtc; | 643 | struct drm_crtc *crtc = intel_encoder->enc.crtc; |
632 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 644 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
633 | 645 | ||
634 | dp_priv->DP = (DP_LINK_TRAIN_OFF | | 646 | dp_priv->DP = (DP_VOLTAGE_0_4 | |
635 | DP_VOLTAGE_0_4 | | 647 | DP_PRE_EMPHASIS_0); |
636 | DP_PRE_EMPHASIS_0 | | 648 | |
637 | DP_SYNC_VS_HIGH | | 649 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
638 | DP_SYNC_HS_HIGH); | 650 | dp_priv->DP |= DP_SYNC_HS_HIGH; |
651 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | ||
652 | dp_priv->DP |= DP_SYNC_VS_HIGH; | ||
653 | |||
654 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | ||
655 | dp_priv->DP |= DP_LINK_TRAIN_OFF_CPT; | ||
656 | else | ||
657 | dp_priv->DP |= DP_LINK_TRAIN_OFF; | ||
639 | 658 | ||
640 | switch (dp_priv->lane_count) { | 659 | switch (dp_priv->lane_count) { |
641 | case 1: | 660 | case 1: |
@@ -664,7 +683,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
664 | dp_priv->DP |= DP_ENHANCED_FRAMING; | 683 | dp_priv->DP |= DP_ENHANCED_FRAMING; |
665 | } | 684 | } |
666 | 685 | ||
667 | if (intel_crtc->pipe == 1) | 686 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ |
687 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) | ||
668 | dp_priv->DP |= DP_PIPEB_SELECT; | 688 | dp_priv->DP |= DP_PIPEB_SELECT; |
669 | 689 | ||
670 | if (IS_eDP(intel_encoder)) { | 690 | if (IS_eDP(intel_encoder)) { |
@@ -704,7 +724,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
704 | { | 724 | { |
705 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 725 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
706 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 726 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
707 | struct drm_device *dev = intel_encoder->base.dev; | 727 | struct drm_device *dev = encoder->dev; |
708 | struct drm_i915_private *dev_priv = dev->dev_private; | 728 | struct drm_i915_private *dev_priv = dev->dev_private; |
709 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 729 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); |
710 | 730 | ||
@@ -749,20 +769,6 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | |||
749 | return link_status[r - DP_LANE0_1_STATUS]; | 769 | return link_status[r - DP_LANE0_1_STATUS]; |
750 | } | 770 | } |
751 | 771 | ||
752 | static void | ||
753 | intel_dp_save(struct drm_connector *connector) | ||
754 | { | ||
755 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
756 | struct drm_device *dev = intel_encoder->base.dev; | ||
757 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
758 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
759 | |||
760 | dp_priv->save_DP = I915_READ(dp_priv->output_reg); | ||
761 | intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET, | ||
762 | dp_priv->save_link_configuration, | ||
763 | sizeof (dp_priv->save_link_configuration)); | ||
764 | } | ||
765 | |||
766 | static uint8_t | 772 | static uint8_t |
767 | intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | 773 | intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], |
768 | int lane) | 774 | int lane) |
@@ -892,6 +898,25 @@ intel_dp_signal_levels(uint8_t train_set, int lane_count) | |||
892 | return signal_levels; | 898 | return signal_levels; |
893 | } | 899 | } |
894 | 900 | ||
901 | /* Gen6's DP voltage swing and pre-emphasis control */ | ||
902 | static uint32_t | ||
903 | intel_gen6_edp_signal_levels(uint8_t train_set) | ||
904 | { | ||
905 | switch (train_set & (DP_TRAIN_VOLTAGE_SWING_MASK|DP_TRAIN_PRE_EMPHASIS_MASK)) { | ||
906 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0: | ||
907 | return EDP_LINK_TRAIN_400MV_0DB_SNB_B; | ||
908 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6: | ||
909 | return EDP_LINK_TRAIN_400MV_6DB_SNB_B; | ||
910 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5: | ||
911 | return EDP_LINK_TRAIN_600MV_3_5DB_SNB_B; | ||
912 | case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0: | ||
913 | return EDP_LINK_TRAIN_800MV_0DB_SNB_B; | ||
914 | default: | ||
915 | DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level\n"); | ||
916 | return EDP_LINK_TRAIN_400MV_0DB_SNB_B; | ||
917 | } | ||
918 | } | ||
919 | |||
895 | static uint8_t | 920 | static uint8_t |
896 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | 921 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], |
897 | int lane) | 922 | int lane) |
@@ -948,7 +973,7 @@ intel_dp_set_link_train(struct intel_encoder *intel_encoder, | |||
948 | uint8_t train_set[4], | 973 | uint8_t train_set[4], |
949 | bool first) | 974 | bool first) |
950 | { | 975 | { |
951 | struct drm_device *dev = intel_encoder->base.dev; | 976 | struct drm_device *dev = intel_encoder->enc.dev; |
952 | struct drm_i915_private *dev_priv = dev->dev_private; | 977 | struct drm_i915_private *dev_priv = dev->dev_private; |
953 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 978 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
954 | int ret; | 979 | int ret; |
@@ -974,7 +999,7 @@ static void | |||
974 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 999 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, |
975 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) | 1000 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) |
976 | { | 1001 | { |
977 | struct drm_device *dev = intel_encoder->base.dev; | 1002 | struct drm_device *dev = intel_encoder->enc.dev; |
978 | struct drm_i915_private *dev_priv = dev->dev_private; | 1003 | struct drm_i915_private *dev_priv = dev->dev_private; |
979 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1004 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
980 | uint8_t train_set[4]; | 1005 | uint8_t train_set[4]; |
@@ -985,23 +1010,38 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
985 | bool channel_eq = false; | 1010 | bool channel_eq = false; |
986 | bool first = true; | 1011 | bool first = true; |
987 | int tries; | 1012 | int tries; |
1013 | u32 reg; | ||
988 | 1014 | ||
989 | /* Write the link configuration data */ | 1015 | /* Write the link configuration data */ |
990 | intel_dp_aux_native_write(intel_encoder, 0x100, | 1016 | intel_dp_aux_native_write(intel_encoder, DP_LINK_BW_SET, |
991 | link_configuration, DP_LINK_CONFIGURATION_SIZE); | 1017 | link_configuration, DP_LINK_CONFIGURATION_SIZE); |
992 | 1018 | ||
993 | DP |= DP_PORT_EN; | 1019 | DP |= DP_PORT_EN; |
994 | DP &= ~DP_LINK_TRAIN_MASK; | 1020 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) |
1021 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | ||
1022 | else | ||
1023 | DP &= ~DP_LINK_TRAIN_MASK; | ||
995 | memset(train_set, 0, 4); | 1024 | memset(train_set, 0, 4); |
996 | voltage = 0xff; | 1025 | voltage = 0xff; |
997 | tries = 0; | 1026 | tries = 0; |
998 | clock_recovery = false; | 1027 | clock_recovery = false; |
999 | for (;;) { | 1028 | for (;;) { |
1000 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1029 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
1001 | uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1030 | uint32_t signal_levels; |
1002 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1031 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { |
1032 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | ||
1033 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | ||
1034 | } else { | ||
1035 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | ||
1036 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | ||
1037 | } | ||
1003 | 1038 | ||
1004 | if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1, | 1039 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) |
1040 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; | ||
1041 | else | ||
1042 | reg = DP | DP_LINK_TRAIN_PAT_1; | ||
1043 | |||
1044 | if (!intel_dp_set_link_train(intel_encoder, reg, | ||
1005 | DP_TRAINING_PATTERN_1, train_set, first)) | 1045 | DP_TRAINING_PATTERN_1, train_set, first)) |
1006 | break; | 1046 | break; |
1007 | first = false; | 1047 | first = false; |
@@ -1041,11 +1081,23 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1041 | channel_eq = false; | 1081 | channel_eq = false; |
1042 | for (;;) { | 1082 | for (;;) { |
1043 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1083 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
1044 | uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1084 | uint32_t signal_levels; |
1045 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1085 | |
1086 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | ||
1087 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | ||
1088 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | ||
1089 | } else { | ||
1090 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | ||
1091 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | ||
1092 | } | ||
1093 | |||
1094 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | ||
1095 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; | ||
1096 | else | ||
1097 | reg = DP | DP_LINK_TRAIN_PAT_2; | ||
1046 | 1098 | ||
1047 | /* channel eq pattern */ | 1099 | /* channel eq pattern */ |
1048 | if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2, | 1100 | if (!intel_dp_set_link_train(intel_encoder, reg, |
1049 | DP_TRAINING_PATTERN_2, train_set, | 1101 | DP_TRAINING_PATTERN_2, train_set, |
1050 | false)) | 1102 | false)) |
1051 | break; | 1103 | break; |
@@ -1068,7 +1120,12 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1068 | ++tries; | 1120 | ++tries; |
1069 | } | 1121 | } |
1070 | 1122 | ||
1071 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); | 1123 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) |
1124 | reg = DP | DP_LINK_TRAIN_OFF_CPT; | ||
1125 | else | ||
1126 | reg = DP | DP_LINK_TRAIN_OFF; | ||
1127 | |||
1128 | I915_WRITE(dp_priv->output_reg, reg); | ||
1072 | POSTING_READ(dp_priv->output_reg); | 1129 | POSTING_READ(dp_priv->output_reg); |
1073 | intel_dp_aux_native_write_1(intel_encoder, | 1130 | intel_dp_aux_native_write_1(intel_encoder, |
1074 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | 1131 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); |
@@ -1077,7 +1134,7 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1077 | static void | 1134 | static void |
1078 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | 1135 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) |
1079 | { | 1136 | { |
1080 | struct drm_device *dev = intel_encoder->base.dev; | 1137 | struct drm_device *dev = intel_encoder->enc.dev; |
1081 | struct drm_i915_private *dev_priv = dev->dev_private; | 1138 | struct drm_i915_private *dev_priv = dev->dev_private; |
1082 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1139 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1083 | 1140 | ||
@@ -1090,9 +1147,15 @@ intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | |||
1090 | udelay(100); | 1147 | udelay(100); |
1091 | } | 1148 | } |
1092 | 1149 | ||
1093 | DP &= ~DP_LINK_TRAIN_MASK; | 1150 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) { |
1094 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | 1151 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1095 | POSTING_READ(dp_priv->output_reg); | 1152 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); |
1153 | POSTING_READ(dp_priv->output_reg); | ||
1154 | } else { | ||
1155 | DP &= ~DP_LINK_TRAIN_MASK; | ||
1156 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | ||
1157 | POSTING_READ(dp_priv->output_reg); | ||
1158 | } | ||
1096 | 1159 | ||
1097 | udelay(17000); | 1160 | udelay(17000); |
1098 | 1161 | ||
@@ -1102,18 +1165,6 @@ intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | |||
1102 | POSTING_READ(dp_priv->output_reg); | 1165 | POSTING_READ(dp_priv->output_reg); |
1103 | } | 1166 | } |
1104 | 1167 | ||
1105 | static void | ||
1106 | intel_dp_restore(struct drm_connector *connector) | ||
1107 | { | ||
1108 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
1109 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1110 | |||
1111 | if (dp_priv->save_DP & DP_PORT_EN) | ||
1112 | intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration); | ||
1113 | else | ||
1114 | intel_dp_link_down(intel_encoder, dp_priv->save_DP); | ||
1115 | } | ||
1116 | |||
1117 | /* | 1168 | /* |
1118 | * According to DP spec | 1169 | * According to DP spec |
1119 | * 5.1.2: | 1170 | * 5.1.2: |
@@ -1144,7 +1195,8 @@ intel_dp_check_link_status(struct intel_encoder *intel_encoder) | |||
1144 | static enum drm_connector_status | 1195 | static enum drm_connector_status |
1145 | ironlake_dp_detect(struct drm_connector *connector) | 1196 | ironlake_dp_detect(struct drm_connector *connector) |
1146 | { | 1197 | { |
1147 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1198 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1199 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1148 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1200 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1149 | enum drm_connector_status status; | 1201 | enum drm_connector_status status; |
1150 | 1202 | ||
@@ -1168,8 +1220,9 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1168 | static enum drm_connector_status | 1220 | static enum drm_connector_status |
1169 | intel_dp_detect(struct drm_connector *connector) | 1221 | intel_dp_detect(struct drm_connector *connector) |
1170 | { | 1222 | { |
1171 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1223 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1172 | struct drm_device *dev = intel_encoder->base.dev; | 1224 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1225 | struct drm_device *dev = intel_encoder->enc.dev; | ||
1173 | struct drm_i915_private *dev_priv = dev->dev_private; | 1226 | struct drm_i915_private *dev_priv = dev->dev_private; |
1174 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1227 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1175 | uint32_t temp, bit; | 1228 | uint32_t temp, bit; |
@@ -1180,16 +1233,6 @@ intel_dp_detect(struct drm_connector *connector) | |||
1180 | if (HAS_PCH_SPLIT(dev)) | 1233 | if (HAS_PCH_SPLIT(dev)) |
1181 | return ironlake_dp_detect(connector); | 1234 | return ironlake_dp_detect(connector); |
1182 | 1235 | ||
1183 | temp = I915_READ(PORT_HOTPLUG_EN); | ||
1184 | |||
1185 | I915_WRITE(PORT_HOTPLUG_EN, | ||
1186 | temp | | ||
1187 | DPB_HOTPLUG_INT_EN | | ||
1188 | DPC_HOTPLUG_INT_EN | | ||
1189 | DPD_HOTPLUG_INT_EN); | ||
1190 | |||
1191 | POSTING_READ(PORT_HOTPLUG_EN); | ||
1192 | |||
1193 | switch (dp_priv->output_reg) { | 1236 | switch (dp_priv->output_reg) { |
1194 | case DP_B: | 1237 | case DP_B: |
1195 | bit = DPB_HOTPLUG_INT_STATUS; | 1238 | bit = DPB_HOTPLUG_INT_STATUS; |
@@ -1222,15 +1265,16 @@ intel_dp_detect(struct drm_connector *connector) | |||
1222 | 1265 | ||
1223 | static int intel_dp_get_modes(struct drm_connector *connector) | 1266 | static int intel_dp_get_modes(struct drm_connector *connector) |
1224 | { | 1267 | { |
1225 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1268 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1226 | struct drm_device *dev = intel_encoder->base.dev; | 1269 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1270 | struct drm_device *dev = intel_encoder->enc.dev; | ||
1227 | struct drm_i915_private *dev_priv = dev->dev_private; | 1271 | struct drm_i915_private *dev_priv = dev->dev_private; |
1228 | int ret; | 1272 | int ret; |
1229 | 1273 | ||
1230 | /* We should parse the EDID data and find out if it has an audio sink | 1274 | /* We should parse the EDID data and find out if it has an audio sink |
1231 | */ | 1275 | */ |
1232 | 1276 | ||
1233 | ret = intel_ddc_get_modes(intel_encoder); | 1277 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
1234 | if (ret) | 1278 | if (ret) |
1235 | return ret; | 1279 | return ret; |
1236 | 1280 | ||
@@ -1249,13 +1293,9 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
1249 | static void | 1293 | static void |
1250 | intel_dp_destroy (struct drm_connector *connector) | 1294 | intel_dp_destroy (struct drm_connector *connector) |
1251 | { | 1295 | { |
1252 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
1253 | |||
1254 | if (intel_encoder->i2c_bus) | ||
1255 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
1256 | drm_sysfs_connector_remove(connector); | 1296 | drm_sysfs_connector_remove(connector); |
1257 | drm_connector_cleanup(connector); | 1297 | drm_connector_cleanup(connector); |
1258 | kfree(intel_encoder); | 1298 | kfree(connector); |
1259 | } | 1299 | } |
1260 | 1300 | ||
1261 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | 1301 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
@@ -1268,8 +1308,6 @@ static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | |||
1268 | 1308 | ||
1269 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | 1309 | static const struct drm_connector_funcs intel_dp_connector_funcs = { |
1270 | .dpms = drm_helper_connector_dpms, | 1310 | .dpms = drm_helper_connector_dpms, |
1271 | .save = intel_dp_save, | ||
1272 | .restore = intel_dp_restore, | ||
1273 | .detect = intel_dp_detect, | 1311 | .detect = intel_dp_detect, |
1274 | .fill_modes = drm_helper_probe_single_connector_modes, | 1312 | .fill_modes = drm_helper_probe_single_connector_modes, |
1275 | .destroy = intel_dp_destroy, | 1313 | .destroy = intel_dp_destroy, |
@@ -1278,12 +1316,17 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { | |||
1278 | static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { | 1316 | static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { |
1279 | .get_modes = intel_dp_get_modes, | 1317 | .get_modes = intel_dp_get_modes, |
1280 | .mode_valid = intel_dp_mode_valid, | 1318 | .mode_valid = intel_dp_mode_valid, |
1281 | .best_encoder = intel_best_encoder, | 1319 | .best_encoder = intel_attached_encoder, |
1282 | }; | 1320 | }; |
1283 | 1321 | ||
1284 | static void intel_dp_enc_destroy(struct drm_encoder *encoder) | 1322 | static void intel_dp_enc_destroy(struct drm_encoder *encoder) |
1285 | { | 1323 | { |
1324 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1325 | |||
1326 | if (intel_encoder->i2c_bus) | ||
1327 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
1286 | drm_encoder_cleanup(encoder); | 1328 | drm_encoder_cleanup(encoder); |
1329 | kfree(intel_encoder); | ||
1287 | } | 1330 | } |
1288 | 1331 | ||
1289 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { | 1332 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { |
@@ -1299,12 +1342,35 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder) | |||
1299 | intel_dp_check_link_status(intel_encoder); | 1342 | intel_dp_check_link_status(intel_encoder); |
1300 | } | 1343 | } |
1301 | 1344 | ||
1345 | /* Return which DP Port should be selected for Transcoder DP control */ | ||
1346 | int | ||
1347 | intel_trans_dp_port_sel (struct drm_crtc *crtc) | ||
1348 | { | ||
1349 | struct drm_device *dev = crtc->dev; | ||
1350 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
1351 | struct drm_encoder *encoder; | ||
1352 | struct intel_encoder *intel_encoder = NULL; | ||
1353 | |||
1354 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | ||
1355 | if (!encoder || encoder->crtc != crtc) | ||
1356 | continue; | ||
1357 | |||
1358 | intel_encoder = enc_to_intel_encoder(encoder); | ||
1359 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | ||
1360 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1361 | return dp_priv->output_reg; | ||
1362 | } | ||
1363 | } | ||
1364 | return -1; | ||
1365 | } | ||
1366 | |||
1302 | void | 1367 | void |
1303 | intel_dp_init(struct drm_device *dev, int output_reg) | 1368 | intel_dp_init(struct drm_device *dev, int output_reg) |
1304 | { | 1369 | { |
1305 | struct drm_i915_private *dev_priv = dev->dev_private; | 1370 | struct drm_i915_private *dev_priv = dev->dev_private; |
1306 | struct drm_connector *connector; | 1371 | struct drm_connector *connector; |
1307 | struct intel_encoder *intel_encoder; | 1372 | struct intel_encoder *intel_encoder; |
1373 | struct intel_connector *intel_connector; | ||
1308 | struct intel_dp_priv *dp_priv; | 1374 | struct intel_dp_priv *dp_priv; |
1309 | const char *name = NULL; | 1375 | const char *name = NULL; |
1310 | 1376 | ||
@@ -1313,13 +1379,21 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1313 | if (!intel_encoder) | 1379 | if (!intel_encoder) |
1314 | return; | 1380 | return; |
1315 | 1381 | ||
1382 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | ||
1383 | if (!intel_connector) { | ||
1384 | kfree(intel_encoder); | ||
1385 | return; | ||
1386 | } | ||
1387 | |||
1316 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); | 1388 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); |
1317 | 1389 | ||
1318 | connector = &intel_encoder->base; | 1390 | connector = &intel_connector->base; |
1319 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, | 1391 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, |
1320 | DRM_MODE_CONNECTOR_DisplayPort); | 1392 | DRM_MODE_CONNECTOR_DisplayPort); |
1321 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); | 1393 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); |
1322 | 1394 | ||
1395 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
1396 | |||
1323 | if (output_reg == DP_A) | 1397 | if (output_reg == DP_A) |
1324 | intel_encoder->type = INTEL_OUTPUT_EDP; | 1398 | intel_encoder->type = INTEL_OUTPUT_EDP; |
1325 | else | 1399 | else |
@@ -1349,7 +1423,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1349 | DRM_MODE_ENCODER_TMDS); | 1423 | DRM_MODE_ENCODER_TMDS); |
1350 | drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs); | 1424 | drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs); |
1351 | 1425 | ||
1352 | drm_mode_connector_attach_encoder(&intel_encoder->base, | 1426 | drm_mode_connector_attach_encoder(&intel_connector->base, |
1353 | &intel_encoder->enc); | 1427 | &intel_encoder->enc); |
1354 | drm_sysfs_connector_add(connector); | 1428 | drm_sysfs_connector_add(connector); |
1355 | 1429 | ||
@@ -1378,7 +1452,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1378 | break; | 1452 | break; |
1379 | } | 1453 | } |
1380 | 1454 | ||
1381 | intel_dp_i2c_init(intel_encoder, name); | 1455 | intel_dp_i2c_init(intel_encoder, intel_connector, name); |
1382 | 1456 | ||
1383 | intel_encoder->ddc_bus = &dp_priv->adapter; | 1457 | intel_encoder->ddc_bus = &dp_priv->adapter; |
1384 | intel_encoder->hot_plug = intel_dp_hot_plug; | 1458 | intel_encoder->hot_plug = intel_dp_hot_plug; |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e30253755f12..df931f787665 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -96,8 +96,6 @@ struct intel_framebuffer { | |||
96 | 96 | ||
97 | 97 | ||
98 | struct intel_encoder { | 98 | struct intel_encoder { |
99 | struct drm_connector base; | ||
100 | |||
101 | struct drm_encoder enc; | 99 | struct drm_encoder enc; |
102 | int type; | 100 | int type; |
103 | struct i2c_adapter *i2c_bus; | 101 | struct i2c_adapter *i2c_bus; |
@@ -110,6 +108,11 @@ struct intel_encoder { | |||
110 | int clone_mask; | 108 | int clone_mask; |
111 | }; | 109 | }; |
112 | 110 | ||
111 | struct intel_connector { | ||
112 | struct drm_connector base; | ||
113 | void *dev_priv; | ||
114 | }; | ||
115 | |||
113 | struct intel_crtc; | 116 | struct intel_crtc; |
114 | struct intel_overlay { | 117 | struct intel_overlay { |
115 | struct drm_device *dev; | 118 | struct drm_device *dev; |
@@ -149,17 +152,18 @@ struct intel_crtc { | |||
149 | bool lowfreq_avail; | 152 | bool lowfreq_avail; |
150 | struct intel_overlay *overlay; | 153 | struct intel_overlay *overlay; |
151 | struct intel_unpin_work *unpin_work; | 154 | struct intel_unpin_work *unpin_work; |
155 | int fdi_lanes; | ||
152 | }; | 156 | }; |
153 | 157 | ||
154 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 158 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
155 | #define to_intel_encoder(x) container_of(x, struct intel_encoder, base) | 159 | #define to_intel_connector(x) container_of(x, struct intel_connector, base) |
156 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) | 160 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) |
157 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 161 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
158 | 162 | ||
159 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | 163 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
160 | const char *name); | 164 | const char *name); |
161 | void intel_i2c_destroy(struct i2c_adapter *adapter); | 165 | void intel_i2c_destroy(struct i2c_adapter *adapter); |
162 | int intel_ddc_get_modes(struct intel_encoder *intel_encoder); | 166 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); |
163 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder); | 167 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder); |
164 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); | 168 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); |
165 | void intel_i2c_reset_gmbus(struct drm_device *dev); | 169 | void intel_i2c_reset_gmbus(struct drm_device *dev); |
@@ -183,7 +187,7 @@ extern void intel_crtc_load_lut(struct drm_crtc *crtc); | |||
183 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 187 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
184 | extern void intel_encoder_commit (struct drm_encoder *encoder); | 188 | extern void intel_encoder_commit (struct drm_encoder *encoder); |
185 | 189 | ||
186 | extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector); | 190 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); |
187 | 191 | ||
188 | extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | 192 | extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, |
189 | struct drm_crtc *crtc); | 193 | struct drm_crtc *crtc); |
@@ -192,17 +196,16 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | |||
192 | extern void intel_wait_for_vblank(struct drm_device *dev); | 196 | extern void intel_wait_for_vblank(struct drm_device *dev); |
193 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 197 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
194 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 198 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
199 | struct drm_connector *connector, | ||
195 | struct drm_display_mode *mode, | 200 | struct drm_display_mode *mode, |
196 | int *dpms_mode); | 201 | int *dpms_mode); |
197 | extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, | 202 | extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, |
203 | struct drm_connector *connector, | ||
198 | int dpms_mode); | 204 | int dpms_mode); |
199 | 205 | ||
200 | extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); | 206 | extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); |
201 | extern int intel_sdvo_supports_hotplug(struct drm_connector *connector); | 207 | extern int intel_sdvo_supports_hotplug(struct drm_connector *connector); |
202 | extern void intel_sdvo_set_hotplug(struct drm_connector *connector, int enable); | 208 | extern void intel_sdvo_set_hotplug(struct drm_connector *connector, int enable); |
203 | extern int intelfb_probe(struct drm_device *dev); | ||
204 | extern int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); | ||
205 | extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc); | ||
206 | extern void intelfb_restore(void); | 209 | extern void intelfb_restore(void); |
207 | extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | 210 | extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, |
208 | u16 blue, int regno); | 211 | u16 blue, int regno); |
@@ -212,10 +215,12 @@ extern void intel_init_clock_gating(struct drm_device *dev); | |||
212 | extern void ironlake_enable_drps(struct drm_device *dev); | 215 | extern void ironlake_enable_drps(struct drm_device *dev); |
213 | extern void ironlake_disable_drps(struct drm_device *dev); | 216 | extern void ironlake_disable_drps(struct drm_device *dev); |
214 | 217 | ||
215 | extern int intel_framebuffer_create(struct drm_device *dev, | 218 | extern int intel_framebuffer_init(struct drm_device *dev, |
216 | struct drm_mode_fb_cmd *mode_cmd, | 219 | struct intel_framebuffer *ifb, |
217 | struct drm_framebuffer **fb, | 220 | struct drm_mode_fb_cmd *mode_cmd, |
218 | struct drm_gem_object *obj); | 221 | struct drm_gem_object *obj); |
222 | extern int intel_fbdev_init(struct drm_device *dev); | ||
223 | extern void intel_fbdev_fini(struct drm_device *dev); | ||
219 | 224 | ||
220 | extern void intel_prepare_page_flip(struct drm_device *dev, int plane); | 225 | extern void intel_prepare_page_flip(struct drm_device *dev, int plane); |
221 | extern void intel_finish_page_flip(struct drm_device *dev, int pipe); | 226 | extern void intel_finish_page_flip(struct drm_device *dev, int pipe); |
@@ -229,4 +234,6 @@ extern int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
229 | struct drm_file *file_priv); | 234 | struct drm_file *file_priv); |
230 | extern int intel_overlay_attrs(struct drm_device *dev, void *data, | 235 | extern int intel_overlay_attrs(struct drm_device *dev, void *data, |
231 | struct drm_file *file_priv); | 236 | struct drm_file *file_priv); |
237 | |||
238 | extern void intel_fb_output_poll_changed(struct drm_device *dev); | ||
232 | #endif /* __INTEL_DRV_H__ */ | 239 | #endif /* __INTEL_DRV_H__ */ |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index ebf213c96b9c..227feca7cf8d 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -96,39 +96,11 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | |||
96 | } | 96 | } |
97 | } | 97 | } |
98 | 98 | ||
99 | static void intel_dvo_save(struct drm_connector *connector) | ||
100 | { | ||
101 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
102 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
103 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
104 | |||
105 | /* Each output should probably just save the registers it touches, | ||
106 | * but for now, use more overkill. | ||
107 | */ | ||
108 | dev_priv->saveDVOA = I915_READ(DVOA); | ||
109 | dev_priv->saveDVOB = I915_READ(DVOB); | ||
110 | dev_priv->saveDVOC = I915_READ(DVOC); | ||
111 | |||
112 | dvo->dev_ops->save(dvo); | ||
113 | } | ||
114 | |||
115 | static void intel_dvo_restore(struct drm_connector *connector) | ||
116 | { | ||
117 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
118 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
119 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
120 | |||
121 | dvo->dev_ops->restore(dvo); | ||
122 | |||
123 | I915_WRITE(DVOA, dev_priv->saveDVOA); | ||
124 | I915_WRITE(DVOB, dev_priv->saveDVOB); | ||
125 | I915_WRITE(DVOC, dev_priv->saveDVOC); | ||
126 | } | ||
127 | |||
128 | static int intel_dvo_mode_valid(struct drm_connector *connector, | 99 | static int intel_dvo_mode_valid(struct drm_connector *connector, |
129 | struct drm_display_mode *mode) | 100 | struct drm_display_mode *mode) |
130 | { | 101 | { |
131 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 102 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
103 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
132 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 104 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
133 | 105 | ||
134 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 106 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
@@ -241,7 +213,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
241 | */ | 213 | */ |
242 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 214 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) |
243 | { | 215 | { |
244 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 216 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
217 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
245 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 218 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
246 | 219 | ||
247 | return dvo->dev_ops->detect(dvo); | 220 | return dvo->dev_ops->detect(dvo); |
@@ -249,7 +222,8 @@ static enum drm_connector_status intel_dvo_detect(struct drm_connector *connecto | |||
249 | 222 | ||
250 | static int intel_dvo_get_modes(struct drm_connector *connector) | 223 | static int intel_dvo_get_modes(struct drm_connector *connector) |
251 | { | 224 | { |
252 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 225 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
226 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
253 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 227 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
254 | 228 | ||
255 | /* We should probably have an i2c driver get_modes function for those | 229 | /* We should probably have an i2c driver get_modes function for those |
@@ -257,7 +231,7 @@ static int intel_dvo_get_modes(struct drm_connector *connector) | |||
257 | * (TV-out, for example), but for now with just TMDS and LVDS, | 231 | * (TV-out, for example), but for now with just TMDS and LVDS, |
258 | * that's not the case. | 232 | * that's not the case. |
259 | */ | 233 | */ |
260 | intel_ddc_get_modes(intel_encoder); | 234 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
261 | if (!list_empty(&connector->probed_modes)) | 235 | if (!list_empty(&connector->probed_modes)) |
262 | return 1; | 236 | return 1; |
263 | 237 | ||
@@ -275,38 +249,10 @@ static int intel_dvo_get_modes(struct drm_connector *connector) | |||
275 | 249 | ||
276 | static void intel_dvo_destroy (struct drm_connector *connector) | 250 | static void intel_dvo_destroy (struct drm_connector *connector) |
277 | { | 251 | { |
278 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
279 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
280 | |||
281 | if (dvo) { | ||
282 | if (dvo->dev_ops->destroy) | ||
283 | dvo->dev_ops->destroy(dvo); | ||
284 | if (dvo->panel_fixed_mode) | ||
285 | kfree(dvo->panel_fixed_mode); | ||
286 | /* no need, in i830_dvoices[] now */ | ||
287 | //kfree(dvo); | ||
288 | } | ||
289 | if (intel_encoder->i2c_bus) | ||
290 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
291 | if (intel_encoder->ddc_bus) | ||
292 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
293 | drm_sysfs_connector_remove(connector); | 252 | drm_sysfs_connector_remove(connector); |
294 | drm_connector_cleanup(connector); | 253 | drm_connector_cleanup(connector); |
295 | kfree(intel_encoder); | 254 | kfree(connector); |
296 | } | ||
297 | |||
298 | #ifdef RANDR_GET_CRTC_INTERFACE | ||
299 | static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector) | ||
300 | { | ||
301 | struct drm_device *dev = connector->dev; | ||
302 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
303 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
304 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
305 | int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT); | ||
306 | |||
307 | return intel_pipe_to_crtc(pScrn, pipe); | ||
308 | } | 255 | } |
309 | #endif | ||
310 | 256 | ||
311 | static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { | 257 | static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { |
312 | .dpms = intel_dvo_dpms, | 258 | .dpms = intel_dvo_dpms, |
@@ -318,8 +264,6 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { | |||
318 | 264 | ||
319 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { | 265 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
320 | .dpms = drm_helper_connector_dpms, | 266 | .dpms = drm_helper_connector_dpms, |
321 | .save = intel_dvo_save, | ||
322 | .restore = intel_dvo_restore, | ||
323 | .detect = intel_dvo_detect, | 267 | .detect = intel_dvo_detect, |
324 | .destroy = intel_dvo_destroy, | 268 | .destroy = intel_dvo_destroy, |
325 | .fill_modes = drm_helper_probe_single_connector_modes, | 269 | .fill_modes = drm_helper_probe_single_connector_modes, |
@@ -328,12 +272,26 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = { | |||
328 | static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { | 272 | static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { |
329 | .mode_valid = intel_dvo_mode_valid, | 273 | .mode_valid = intel_dvo_mode_valid, |
330 | .get_modes = intel_dvo_get_modes, | 274 | .get_modes = intel_dvo_get_modes, |
331 | .best_encoder = intel_best_encoder, | 275 | .best_encoder = intel_attached_encoder, |
332 | }; | 276 | }; |
333 | 277 | ||
334 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) | 278 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) |
335 | { | 279 | { |
280 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
281 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
282 | |||
283 | if (dvo) { | ||
284 | if (dvo->dev_ops->destroy) | ||
285 | dvo->dev_ops->destroy(dvo); | ||
286 | if (dvo->panel_fixed_mode) | ||
287 | kfree(dvo->panel_fixed_mode); | ||
288 | } | ||
289 | if (intel_encoder->i2c_bus) | ||
290 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
291 | if (intel_encoder->ddc_bus) | ||
292 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
336 | drm_encoder_cleanup(encoder); | 293 | drm_encoder_cleanup(encoder); |
294 | kfree(intel_encoder); | ||
337 | } | 295 | } |
338 | 296 | ||
339 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | 297 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { |
@@ -352,7 +310,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
352 | { | 310 | { |
353 | struct drm_device *dev = connector->dev; | 311 | struct drm_device *dev = connector->dev; |
354 | struct drm_i915_private *dev_priv = dev->dev_private; | 312 | struct drm_i915_private *dev_priv = dev->dev_private; |
355 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 313 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
314 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
356 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 315 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
357 | uint32_t dvo_reg = dvo->dvo_reg; | 316 | uint32_t dvo_reg = dvo->dvo_reg; |
358 | uint32_t dvo_val = I915_READ(dvo_reg); | 317 | uint32_t dvo_val = I915_READ(dvo_reg); |
@@ -384,6 +343,7 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
384 | void intel_dvo_init(struct drm_device *dev) | 343 | void intel_dvo_init(struct drm_device *dev) |
385 | { | 344 | { |
386 | struct intel_encoder *intel_encoder; | 345 | struct intel_encoder *intel_encoder; |
346 | struct intel_connector *intel_connector; | ||
387 | struct intel_dvo_device *dvo; | 347 | struct intel_dvo_device *dvo; |
388 | struct i2c_adapter *i2cbus = NULL; | 348 | struct i2c_adapter *i2cbus = NULL; |
389 | int ret = 0; | 349 | int ret = 0; |
@@ -393,6 +353,12 @@ void intel_dvo_init(struct drm_device *dev) | |||
393 | if (!intel_encoder) | 353 | if (!intel_encoder) |
394 | return; | 354 | return; |
395 | 355 | ||
356 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | ||
357 | if (!intel_connector) { | ||
358 | kfree(intel_encoder); | ||
359 | return; | ||
360 | } | ||
361 | |||
396 | /* Set up the DDC bus */ | 362 | /* Set up the DDC bus */ |
397 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); | 363 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); |
398 | if (!intel_encoder->ddc_bus) | 364 | if (!intel_encoder->ddc_bus) |
@@ -400,7 +366,7 @@ void intel_dvo_init(struct drm_device *dev) | |||
400 | 366 | ||
401 | /* Now, try to find a controller */ | 367 | /* Now, try to find a controller */ |
402 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 368 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
403 | struct drm_connector *connector = &intel_encoder->base; | 369 | struct drm_connector *connector = &intel_connector->base; |
404 | int gpio; | 370 | int gpio; |
405 | 371 | ||
406 | dvo = &intel_dvo_devices[i]; | 372 | dvo = &intel_dvo_devices[i]; |
@@ -471,7 +437,7 @@ void intel_dvo_init(struct drm_device *dev) | |||
471 | drm_encoder_helper_add(&intel_encoder->enc, | 437 | drm_encoder_helper_add(&intel_encoder->enc, |
472 | &intel_dvo_helper_funcs); | 438 | &intel_dvo_helper_funcs); |
473 | 439 | ||
474 | drm_mode_connector_attach_encoder(&intel_encoder->base, | 440 | drm_mode_connector_attach_encoder(&intel_connector->base, |
475 | &intel_encoder->enc); | 441 | &intel_encoder->enc); |
476 | if (dvo->type == INTEL_DVO_CHIP_LVDS) { | 442 | if (dvo->type == INTEL_DVO_CHIP_LVDS) { |
477 | /* For our LVDS chipsets, we should hopefully be able | 443 | /* For our LVDS chipsets, we should hopefully be able |
@@ -496,4 +462,5 @@ void intel_dvo_init(struct drm_device *dev) | |||
496 | intel_i2c_destroy(i2cbus); | 462 | intel_i2c_destroy(i2cbus); |
497 | free_intel: | 463 | free_intel: |
498 | kfree(intel_encoder); | 464 | kfree(intel_encoder); |
465 | kfree(intel_connector); | ||
499 | } | 466 | } |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 8a0b3bcdc7b1..6f53cf7fbc50 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -44,9 +44,10 @@ | |||
44 | #include "i915_drm.h" | 44 | #include "i915_drm.h" |
45 | #include "i915_drv.h" | 45 | #include "i915_drv.h" |
46 | 46 | ||
47 | struct intelfb_par { | 47 | struct intel_fbdev { |
48 | struct drm_fb_helper helper; | 48 | struct drm_fb_helper helper; |
49 | struct intel_framebuffer *intel_fb; | 49 | struct intel_framebuffer ifb; |
50 | struct list_head fbdev_list; | ||
50 | struct drm_display_mode *our_mode; | 51 | struct drm_display_mode *our_mode; |
51 | }; | 52 | }; |
52 | 53 | ||
@@ -54,7 +55,6 @@ static struct fb_ops intelfb_ops = { | |||
54 | .owner = THIS_MODULE, | 55 | .owner = THIS_MODULE, |
55 | .fb_check_var = drm_fb_helper_check_var, | 56 | .fb_check_var = drm_fb_helper_check_var, |
56 | .fb_set_par = drm_fb_helper_set_par, | 57 | .fb_set_par = drm_fb_helper_set_par, |
57 | .fb_setcolreg = drm_fb_helper_setcolreg, | ||
58 | .fb_fillrect = cfb_fillrect, | 58 | .fb_fillrect = cfb_fillrect, |
59 | .fb_copyarea = cfb_copyarea, | 59 | .fb_copyarea = cfb_copyarea, |
60 | .fb_imageblit = cfb_imageblit, | 60 | .fb_imageblit = cfb_imageblit, |
@@ -63,62 +63,12 @@ static struct fb_ops intelfb_ops = { | |||
63 | .fb_setcmap = drm_fb_helper_setcmap, | 63 | .fb_setcmap = drm_fb_helper_setcmap, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static struct drm_fb_helper_funcs intel_fb_helper_funcs = { | 66 | static int intelfb_create(struct intel_fbdev *ifbdev, |
67 | .gamma_set = intel_crtc_fb_gamma_set, | 67 | struct drm_fb_helper_surface_size *sizes) |
68 | .gamma_get = intel_crtc_fb_gamma_get, | ||
69 | }; | ||
70 | |||
71 | |||
72 | /** | ||
73 | * Currently it is assumed that the old framebuffer is reused. | ||
74 | * | ||
75 | * LOCKING | ||
76 | * caller should hold the mode config lock. | ||
77 | * | ||
78 | */ | ||
79 | int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc) | ||
80 | { | ||
81 | struct fb_info *info; | ||
82 | struct drm_framebuffer *fb; | ||
83 | struct drm_display_mode *mode = crtc->desired_mode; | ||
84 | |||
85 | fb = crtc->fb; | ||
86 | if (!fb) | ||
87 | return 1; | ||
88 | |||
89 | info = fb->fbdev; | ||
90 | if (!info) | ||
91 | return 1; | ||
92 | |||
93 | if (!mode) | ||
94 | return 1; | ||
95 | |||
96 | info->var.xres = mode->hdisplay; | ||
97 | info->var.right_margin = mode->hsync_start - mode->hdisplay; | ||
98 | info->var.hsync_len = mode->hsync_end - mode->hsync_start; | ||
99 | info->var.left_margin = mode->htotal - mode->hsync_end; | ||
100 | info->var.yres = mode->vdisplay; | ||
101 | info->var.lower_margin = mode->vsync_start - mode->vdisplay; | ||
102 | info->var.vsync_len = mode->vsync_end - mode->vsync_start; | ||
103 | info->var.upper_margin = mode->vtotal - mode->vsync_end; | ||
104 | info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100; | ||
105 | /* avoid overflow */ | ||
106 | info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh; | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | EXPORT_SYMBOL(intelfb_resize); | ||
111 | |||
112 | static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | ||
113 | uint32_t fb_height, uint32_t surface_width, | ||
114 | uint32_t surface_height, | ||
115 | uint32_t surface_depth, uint32_t surface_bpp, | ||
116 | struct drm_framebuffer **fb_p) | ||
117 | { | 68 | { |
69 | struct drm_device *dev = ifbdev->helper.dev; | ||
118 | struct fb_info *info; | 70 | struct fb_info *info; |
119 | struct intelfb_par *par; | ||
120 | struct drm_framebuffer *fb; | 71 | struct drm_framebuffer *fb; |
121 | struct intel_framebuffer *intel_fb; | ||
122 | struct drm_mode_fb_cmd mode_cmd; | 72 | struct drm_mode_fb_cmd mode_cmd; |
123 | struct drm_gem_object *fbo = NULL; | 73 | struct drm_gem_object *fbo = NULL; |
124 | struct drm_i915_gem_object *obj_priv; | 74 | struct drm_i915_gem_object *obj_priv; |
@@ -126,19 +76,19 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
126 | int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1; | 76 | int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1; |
127 | 77 | ||
128 | /* we don't do packed 24bpp */ | 78 | /* we don't do packed 24bpp */ |
129 | if (surface_bpp == 24) | 79 | if (sizes->surface_bpp == 24) |
130 | surface_bpp = 32; | 80 | sizes->surface_bpp = 32; |
131 | 81 | ||
132 | mode_cmd.width = surface_width; | 82 | mode_cmd.width = sizes->surface_width; |
133 | mode_cmd.height = surface_height; | 83 | mode_cmd.height = sizes->surface_height; |
134 | 84 | ||
135 | mode_cmd.bpp = surface_bpp; | 85 | mode_cmd.bpp = sizes->surface_bpp; |
136 | mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); | 86 | mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); |
137 | mode_cmd.depth = surface_depth; | 87 | mode_cmd.depth = sizes->surface_depth; |
138 | 88 | ||
139 | size = mode_cmd.pitch * mode_cmd.height; | 89 | size = mode_cmd.pitch * mode_cmd.height; |
140 | size = ALIGN(size, PAGE_SIZE); | 90 | size = ALIGN(size, PAGE_SIZE); |
141 | fbo = drm_gem_object_alloc(dev, size); | 91 | fbo = i915_gem_alloc_object(dev, size); |
142 | if (!fbo) { | 92 | if (!fbo) { |
143 | DRM_ERROR("failed to allocate framebuffer\n"); | 93 | DRM_ERROR("failed to allocate framebuffer\n"); |
144 | ret = -ENOMEM; | 94 | ret = -ENOMEM; |
@@ -157,45 +107,37 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
157 | /* Flush everything out, we'll be doing GTT only from now on */ | 107 | /* Flush everything out, we'll be doing GTT only from now on */ |
158 | i915_gem_object_set_to_gtt_domain(fbo, 1); | 108 | i915_gem_object_set_to_gtt_domain(fbo, 1); |
159 | 109 | ||
160 | ret = intel_framebuffer_create(dev, &mode_cmd, &fb, fbo); | 110 | info = framebuffer_alloc(0, device); |
161 | if (ret) { | ||
162 | DRM_ERROR("failed to allocate fb.\n"); | ||
163 | goto out_unpin; | ||
164 | } | ||
165 | |||
166 | list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); | ||
167 | |||
168 | intel_fb = to_intel_framebuffer(fb); | ||
169 | *fb_p = fb; | ||
170 | |||
171 | info = framebuffer_alloc(sizeof(struct intelfb_par), device); | ||
172 | if (!info) { | 111 | if (!info) { |
173 | ret = -ENOMEM; | 112 | ret = -ENOMEM; |
174 | goto out_unpin; | 113 | goto out_unpin; |
175 | } | 114 | } |
176 | 115 | ||
177 | par = info->par; | 116 | info->par = ifbdev; |
178 | 117 | ||
179 | par->helper.funcs = &intel_fb_helper_funcs; | 118 | intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, fbo); |
180 | par->helper.dev = dev; | 119 | |
181 | ret = drm_fb_helper_init_crtc_count(&par->helper, 2, | 120 | fb = &ifbdev->ifb.base; |
182 | INTELFB_CONN_LIMIT); | 121 | |
183 | if (ret) | 122 | ifbdev->helper.fb = fb; |
184 | goto out_unref; | 123 | ifbdev->helper.fbdev = info; |
185 | 124 | ||
186 | strcpy(info->fix.id, "inteldrmfb"); | 125 | strcpy(info->fix.id, "inteldrmfb"); |
187 | 126 | ||
188 | info->flags = FBINFO_DEFAULT; | 127 | info->flags = FBINFO_DEFAULT; |
189 | |||
190 | info->fbops = &intelfb_ops; | 128 | info->fbops = &intelfb_ops; |
191 | 129 | ||
192 | |||
193 | /* setup aperture base/size for vesafb takeover */ | 130 | /* setup aperture base/size for vesafb takeover */ |
194 | info->aperture_base = dev->mode_config.fb_base; | 131 | info->apertures = alloc_apertures(1); |
132 | if (!info->apertures) { | ||
133 | ret = -ENOMEM; | ||
134 | goto out_unpin; | ||
135 | } | ||
136 | info->apertures->ranges[0].base = dev->mode_config.fb_base; | ||
195 | if (IS_I9XX(dev)) | 137 | if (IS_I9XX(dev)) |
196 | info->aperture_size = pci_resource_len(dev->pdev, 2); | 138 | info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 2); |
197 | else | 139 | else |
198 | info->aperture_size = pci_resource_len(dev->pdev, 0); | 140 | info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); |
199 | 141 | ||
200 | info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; | 142 | info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; |
201 | info->fix.smem_len = size; | 143 | info->fix.smem_len = size; |
@@ -208,12 +150,18 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
208 | ret = -ENOSPC; | 150 | ret = -ENOSPC; |
209 | goto out_unpin; | 151 | goto out_unpin; |
210 | } | 152 | } |
153 | |||
154 | ret = fb_alloc_cmap(&info->cmap, 256, 0); | ||
155 | if (ret) { | ||
156 | ret = -ENOMEM; | ||
157 | goto out_unpin; | ||
158 | } | ||
211 | info->screen_size = size; | 159 | info->screen_size = size; |
212 | 160 | ||
213 | // memset(info->screen_base, 0, size); | 161 | // memset(info->screen_base, 0, size); |
214 | 162 | ||
215 | drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); | 163 | drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); |
216 | drm_fb_helper_fill_var(info, fb, fb_width, fb_height); | 164 | drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); |
217 | 165 | ||
218 | /* FIXME: we really shouldn't expose mmio space at all */ | 166 | /* FIXME: we really shouldn't expose mmio space at all */ |
219 | info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar); | 167 | info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar); |
@@ -225,14 +173,10 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
225 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | 173 | info->pixmap.flags = FB_PIXMAP_SYSTEM; |
226 | info->pixmap.scan_align = 1; | 174 | info->pixmap.scan_align = 1; |
227 | 175 | ||
228 | fb->fbdev = info; | ||
229 | |||
230 | par->intel_fb = intel_fb; | ||
231 | |||
232 | /* To allow resizeing without swapping buffers */ | ||
233 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", | 176 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", |
234 | intel_fb->base.width, intel_fb->base.height, | 177 | fb->width, fb->height, |
235 | obj_priv->gtt_offset, fbo); | 178 | obj_priv->gtt_offset, fbo); |
179 | |||
236 | 180 | ||
237 | mutex_unlock(&dev->struct_mutex); | 181 | mutex_unlock(&dev->struct_mutex); |
238 | vga_switcheroo_client_fb_set(dev->pdev, info); | 182 | vga_switcheroo_client_fb_set(dev->pdev, info); |
@@ -247,35 +191,86 @@ out: | |||
247 | return ret; | 191 | return ret; |
248 | } | 192 | } |
249 | 193 | ||
250 | int intelfb_probe(struct drm_device *dev) | 194 | static int intel_fb_find_or_create_single(struct drm_fb_helper *helper, |
195 | struct drm_fb_helper_surface_size *sizes) | ||
251 | { | 196 | { |
197 | struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper; | ||
198 | int new_fb = 0; | ||
252 | int ret; | 199 | int ret; |
253 | 200 | ||
254 | DRM_DEBUG_KMS("\n"); | 201 | if (!helper->fb) { |
255 | ret = drm_fb_helper_single_fb_probe(dev, 32, intelfb_create); | 202 | ret = intelfb_create(ifbdev, sizes); |
256 | return ret; | 203 | if (ret) |
204 | return ret; | ||
205 | new_fb = 1; | ||
206 | } | ||
207 | return new_fb; | ||
257 | } | 208 | } |
258 | EXPORT_SYMBOL(intelfb_probe); | ||
259 | 209 | ||
260 | int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) | 210 | static struct drm_fb_helper_funcs intel_fb_helper_funcs = { |
211 | .gamma_set = intel_crtc_fb_gamma_set, | ||
212 | .gamma_get = intel_crtc_fb_gamma_get, | ||
213 | .fb_probe = intel_fb_find_or_create_single, | ||
214 | }; | ||
215 | |||
216 | int intel_fbdev_destroy(struct drm_device *dev, | ||
217 | struct intel_fbdev *ifbdev) | ||
261 | { | 218 | { |
262 | struct fb_info *info; | 219 | struct fb_info *info; |
220 | struct intel_framebuffer *ifb = &ifbdev->ifb; | ||
263 | 221 | ||
264 | if (!fb) | 222 | if (ifbdev->helper.fbdev) { |
265 | return -EINVAL; | 223 | info = ifbdev->helper.fbdev; |
266 | |||
267 | info = fb->fbdev; | ||
268 | |||
269 | if (info) { | ||
270 | struct intelfb_par *par = info->par; | ||
271 | unregister_framebuffer(info); | 224 | unregister_framebuffer(info); |
272 | iounmap(info->screen_base); | 225 | iounmap(info->screen_base); |
273 | if (info->par) | 226 | if (info->cmap.len) |
274 | drm_fb_helper_free(&par->helper); | 227 | fb_dealloc_cmap(&info->cmap); |
275 | framebuffer_release(info); | 228 | framebuffer_release(info); |
276 | } | 229 | } |
277 | 230 | ||
231 | drm_fb_helper_fini(&ifbdev->helper); | ||
232 | |||
233 | drm_framebuffer_cleanup(&ifb->base); | ||
234 | if (ifb->obj) | ||
235 | drm_gem_object_unreference_unlocked(ifb->obj); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | int intel_fbdev_init(struct drm_device *dev) | ||
241 | { | ||
242 | struct intel_fbdev *ifbdev; | ||
243 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
244 | |||
245 | ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL); | ||
246 | if (!ifbdev) | ||
247 | return -ENOMEM; | ||
248 | |||
249 | dev_priv->fbdev = ifbdev; | ||
250 | ifbdev->helper.funcs = &intel_fb_helper_funcs; | ||
251 | |||
252 | drm_fb_helper_init(dev, &ifbdev->helper, 2, | ||
253 | INTELFB_CONN_LIMIT); | ||
254 | |||
255 | drm_fb_helper_single_add_all_connectors(&ifbdev->helper); | ||
256 | drm_fb_helper_initial_config(&ifbdev->helper, 32); | ||
278 | return 0; | 257 | return 0; |
279 | } | 258 | } |
280 | EXPORT_SYMBOL(intelfb_remove); | 259 | |
260 | void intel_fbdev_fini(struct drm_device *dev) | ||
261 | { | ||
262 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
263 | if (!dev_priv->fbdev) | ||
264 | return; | ||
265 | |||
266 | intel_fbdev_destroy(dev, dev_priv->fbdev); | ||
267 | kfree(dev_priv->fbdev); | ||
268 | dev_priv->fbdev = NULL; | ||
269 | } | ||
281 | MODULE_LICENSE("GPL and additional rights"); | 270 | MODULE_LICENSE("GPL and additional rights"); |
271 | |||
272 | void intel_fb_output_poll_changed(struct drm_device *dev) | ||
273 | { | ||
274 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
275 | drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); | ||
276 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 48cade0cf7b1..65727f0a79a3 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -39,7 +39,6 @@ | |||
39 | 39 | ||
40 | struct intel_hdmi_priv { | 40 | struct intel_hdmi_priv { |
41 | u32 sdvox_reg; | 41 | u32 sdvox_reg; |
42 | u32 save_SDVOX; | ||
43 | bool has_hdmi_sink; | 42 | bool has_hdmi_sink; |
44 | }; | 43 | }; |
45 | 44 | ||
@@ -63,8 +62,12 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
63 | if (hdmi_priv->has_hdmi_sink) | 62 | if (hdmi_priv->has_hdmi_sink) |
64 | sdvox |= SDVO_AUDIO_ENABLE; | 63 | sdvox |= SDVO_AUDIO_ENABLE; |
65 | 64 | ||
66 | if (intel_crtc->pipe == 1) | 65 | if (intel_crtc->pipe == 1) { |
67 | sdvox |= SDVO_PIPE_B_SELECT; | 66 | if (HAS_PCH_CPT(dev)) |
67 | sdvox |= PORT_TRANS_B_SEL_CPT; | ||
68 | else | ||
69 | sdvox |= SDVO_PIPE_B_SELECT; | ||
70 | } | ||
68 | 71 | ||
69 | I915_WRITE(hdmi_priv->sdvox_reg, sdvox); | 72 | I915_WRITE(hdmi_priv->sdvox_reg, sdvox); |
70 | POSTING_READ(hdmi_priv->sdvox_reg); | 73 | POSTING_READ(hdmi_priv->sdvox_reg); |
@@ -106,27 +109,6 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
106 | } | 109 | } |
107 | } | 110 | } |
108 | 111 | ||
109 | static void intel_hdmi_save(struct drm_connector *connector) | ||
110 | { | ||
111 | struct drm_device *dev = connector->dev; | ||
112 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
113 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
114 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
115 | |||
116 | hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg); | ||
117 | } | ||
118 | |||
119 | static void intel_hdmi_restore(struct drm_connector *connector) | ||
120 | { | ||
121 | struct drm_device *dev = connector->dev; | ||
122 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
123 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
124 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
125 | |||
126 | I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX); | ||
127 | POSTING_READ(hdmi_priv->sdvox_reg); | ||
128 | } | ||
129 | |||
130 | static int intel_hdmi_mode_valid(struct drm_connector *connector, | 112 | static int intel_hdmi_mode_valid(struct drm_connector *connector, |
131 | struct drm_display_mode *mode) | 113 | struct drm_display_mode *mode) |
132 | { | 114 | { |
@@ -151,13 +133,14 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
151 | static enum drm_connector_status | 133 | static enum drm_connector_status |
152 | intel_hdmi_detect(struct drm_connector *connector) | 134 | intel_hdmi_detect(struct drm_connector *connector) |
153 | { | 135 | { |
154 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 136 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
137 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
155 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | 138 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; |
156 | struct edid *edid = NULL; | 139 | struct edid *edid = NULL; |
157 | enum drm_connector_status status = connector_status_disconnected; | 140 | enum drm_connector_status status = connector_status_disconnected; |
158 | 141 | ||
159 | hdmi_priv->has_hdmi_sink = false; | 142 | hdmi_priv->has_hdmi_sink = false; |
160 | edid = drm_get_edid(&intel_encoder->base, | 143 | edid = drm_get_edid(connector, |
161 | intel_encoder->ddc_bus); | 144 | intel_encoder->ddc_bus); |
162 | 145 | ||
163 | if (edid) { | 146 | if (edid) { |
@@ -165,7 +148,7 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
165 | status = connector_status_connected; | 148 | status = connector_status_connected; |
166 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | 149 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); |
167 | } | 150 | } |
168 | intel_encoder->base.display_info.raw_edid = NULL; | 151 | connector->display_info.raw_edid = NULL; |
169 | kfree(edid); | 152 | kfree(edid); |
170 | } | 153 | } |
171 | 154 | ||
@@ -174,24 +157,21 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
174 | 157 | ||
175 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 158 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
176 | { | 159 | { |
177 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 160 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
161 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
178 | 162 | ||
179 | /* We should parse the EDID data and find out if it's an HDMI sink so | 163 | /* We should parse the EDID data and find out if it's an HDMI sink so |
180 | * we can send audio to it. | 164 | * we can send audio to it. |
181 | */ | 165 | */ |
182 | 166 | ||
183 | return intel_ddc_get_modes(intel_encoder); | 167 | return intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
184 | } | 168 | } |
185 | 169 | ||
186 | static void intel_hdmi_destroy(struct drm_connector *connector) | 170 | static void intel_hdmi_destroy(struct drm_connector *connector) |
187 | { | 171 | { |
188 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
189 | |||
190 | if (intel_encoder->i2c_bus) | ||
191 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
192 | drm_sysfs_connector_remove(connector); | 172 | drm_sysfs_connector_remove(connector); |
193 | drm_connector_cleanup(connector); | 173 | drm_connector_cleanup(connector); |
194 | kfree(intel_encoder); | 174 | kfree(connector); |
195 | } | 175 | } |
196 | 176 | ||
197 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { | 177 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { |
@@ -204,8 +184,6 @@ static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { | |||
204 | 184 | ||
205 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | 185 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
206 | .dpms = drm_helper_connector_dpms, | 186 | .dpms = drm_helper_connector_dpms, |
207 | .save = intel_hdmi_save, | ||
208 | .restore = intel_hdmi_restore, | ||
209 | .detect = intel_hdmi_detect, | 187 | .detect = intel_hdmi_detect, |
210 | .fill_modes = drm_helper_probe_single_connector_modes, | 188 | .fill_modes = drm_helper_probe_single_connector_modes, |
211 | .destroy = intel_hdmi_destroy, | 189 | .destroy = intel_hdmi_destroy, |
@@ -214,12 +192,17 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | |||
214 | static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { | 192 | static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { |
215 | .get_modes = intel_hdmi_get_modes, | 193 | .get_modes = intel_hdmi_get_modes, |
216 | .mode_valid = intel_hdmi_mode_valid, | 194 | .mode_valid = intel_hdmi_mode_valid, |
217 | .best_encoder = intel_best_encoder, | 195 | .best_encoder = intel_attached_encoder, |
218 | }; | 196 | }; |
219 | 197 | ||
220 | static void intel_hdmi_enc_destroy(struct drm_encoder *encoder) | 198 | static void intel_hdmi_enc_destroy(struct drm_encoder *encoder) |
221 | { | 199 | { |
200 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
201 | |||
202 | if (intel_encoder->i2c_bus) | ||
203 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
222 | drm_encoder_cleanup(encoder); | 204 | drm_encoder_cleanup(encoder); |
205 | kfree(intel_encoder); | ||
223 | } | 206 | } |
224 | 207 | ||
225 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { | 208 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { |
@@ -231,21 +214,30 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
231 | struct drm_i915_private *dev_priv = dev->dev_private; | 214 | struct drm_i915_private *dev_priv = dev->dev_private; |
232 | struct drm_connector *connector; | 215 | struct drm_connector *connector; |
233 | struct intel_encoder *intel_encoder; | 216 | struct intel_encoder *intel_encoder; |
217 | struct intel_connector *intel_connector; | ||
234 | struct intel_hdmi_priv *hdmi_priv; | 218 | struct intel_hdmi_priv *hdmi_priv; |
235 | 219 | ||
236 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 220 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + |
237 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); | 221 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); |
238 | if (!intel_encoder) | 222 | if (!intel_encoder) |
239 | return; | 223 | return; |
224 | |||
225 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | ||
226 | if (!intel_connector) { | ||
227 | kfree(intel_encoder); | ||
228 | return; | ||
229 | } | ||
230 | |||
240 | hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); | 231 | hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); |
241 | 232 | ||
242 | connector = &intel_encoder->base; | 233 | connector = &intel_connector->base; |
243 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, | 234 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, |
244 | DRM_MODE_CONNECTOR_HDMIA); | 235 | DRM_MODE_CONNECTOR_HDMIA); |
245 | drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); | 236 | drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); |
246 | 237 | ||
247 | intel_encoder->type = INTEL_OUTPUT_HDMI; | 238 | intel_encoder->type = INTEL_OUTPUT_HDMI; |
248 | 239 | ||
240 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
249 | connector->interlace_allowed = 0; | 241 | connector->interlace_allowed = 0; |
250 | connector->doublescan_allowed = 0; | 242 | connector->doublescan_allowed = 0; |
251 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 243 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
@@ -285,7 +277,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
285 | DRM_MODE_ENCODER_TMDS); | 277 | DRM_MODE_ENCODER_TMDS); |
286 | drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs); | 278 | drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs); |
287 | 279 | ||
288 | drm_mode_connector_attach_encoder(&intel_encoder->base, | 280 | drm_mode_connector_attach_encoder(&intel_connector->base, |
289 | &intel_encoder->enc); | 281 | &intel_encoder->enc); |
290 | drm_sysfs_connector_add(connector); | 282 | drm_sysfs_connector_add(connector); |
291 | 283 | ||
@@ -303,6 +295,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
303 | err_connector: | 295 | err_connector: |
304 | drm_connector_cleanup(connector); | 296 | drm_connector_cleanup(connector); |
305 | kfree(intel_encoder); | 297 | kfree(intel_encoder); |
298 | kfree(intel_connector); | ||
306 | 299 | ||
307 | return; | 300 | return; |
308 | } | 301 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b66806a37d37..6a1accd83aec 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -139,75 +139,6 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
139 | /* XXX: We never power down the LVDS pairs. */ | 139 | /* XXX: We never power down the LVDS pairs. */ |
140 | } | 140 | } |
141 | 141 | ||
142 | static void intel_lvds_save(struct drm_connector *connector) | ||
143 | { | ||
144 | struct drm_device *dev = connector->dev; | ||
145 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
146 | u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg; | ||
147 | u32 pwm_ctl_reg; | ||
148 | |||
149 | if (HAS_PCH_SPLIT(dev)) { | ||
150 | pp_on_reg = PCH_PP_ON_DELAYS; | ||
151 | pp_off_reg = PCH_PP_OFF_DELAYS; | ||
152 | pp_ctl_reg = PCH_PP_CONTROL; | ||
153 | pp_div_reg = PCH_PP_DIVISOR; | ||
154 | pwm_ctl_reg = BLC_PWM_CPU_CTL; | ||
155 | } else { | ||
156 | pp_on_reg = PP_ON_DELAYS; | ||
157 | pp_off_reg = PP_OFF_DELAYS; | ||
158 | pp_ctl_reg = PP_CONTROL; | ||
159 | pp_div_reg = PP_DIVISOR; | ||
160 | pwm_ctl_reg = BLC_PWM_CTL; | ||
161 | } | ||
162 | |||
163 | dev_priv->savePP_ON = I915_READ(pp_on_reg); | ||
164 | dev_priv->savePP_OFF = I915_READ(pp_off_reg); | ||
165 | dev_priv->savePP_CONTROL = I915_READ(pp_ctl_reg); | ||
166 | dev_priv->savePP_DIVISOR = I915_READ(pp_div_reg); | ||
167 | dev_priv->saveBLC_PWM_CTL = I915_READ(pwm_ctl_reg); | ||
168 | dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & | ||
169 | BACKLIGHT_DUTY_CYCLE_MASK); | ||
170 | |||
171 | /* | ||
172 | * If the light is off at server startup, just make it full brightness | ||
173 | */ | ||
174 | if (dev_priv->backlight_duty_cycle == 0) | ||
175 | dev_priv->backlight_duty_cycle = | ||
176 | intel_lvds_get_max_backlight(dev); | ||
177 | } | ||
178 | |||
179 | static void intel_lvds_restore(struct drm_connector *connector) | ||
180 | { | ||
181 | struct drm_device *dev = connector->dev; | ||
182 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
183 | u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg; | ||
184 | u32 pwm_ctl_reg; | ||
185 | |||
186 | if (HAS_PCH_SPLIT(dev)) { | ||
187 | pp_on_reg = PCH_PP_ON_DELAYS; | ||
188 | pp_off_reg = PCH_PP_OFF_DELAYS; | ||
189 | pp_ctl_reg = PCH_PP_CONTROL; | ||
190 | pp_div_reg = PCH_PP_DIVISOR; | ||
191 | pwm_ctl_reg = BLC_PWM_CPU_CTL; | ||
192 | } else { | ||
193 | pp_on_reg = PP_ON_DELAYS; | ||
194 | pp_off_reg = PP_OFF_DELAYS; | ||
195 | pp_ctl_reg = PP_CONTROL; | ||
196 | pp_div_reg = PP_DIVISOR; | ||
197 | pwm_ctl_reg = BLC_PWM_CTL; | ||
198 | } | ||
199 | |||
200 | I915_WRITE(pwm_ctl_reg, dev_priv->saveBLC_PWM_CTL); | ||
201 | I915_WRITE(pp_on_reg, dev_priv->savePP_ON); | ||
202 | I915_WRITE(pp_off_reg, dev_priv->savePP_OFF); | ||
203 | I915_WRITE(pp_div_reg, dev_priv->savePP_DIVISOR); | ||
204 | I915_WRITE(pp_ctl_reg, dev_priv->savePP_CONTROL); | ||
205 | if (dev_priv->savePP_CONTROL & POWER_TARGET_ON) | ||
206 | intel_lvds_set_power(dev, true); | ||
207 | else | ||
208 | intel_lvds_set_power(dev, false); | ||
209 | } | ||
210 | |||
211 | static int intel_lvds_mode_valid(struct drm_connector *connector, | 142 | static int intel_lvds_mode_valid(struct drm_connector *connector, |
212 | struct drm_display_mode *mode) | 143 | struct drm_display_mode *mode) |
213 | { | 144 | { |
@@ -635,12 +566,13 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect | |||
635 | static int intel_lvds_get_modes(struct drm_connector *connector) | 566 | static int intel_lvds_get_modes(struct drm_connector *connector) |
636 | { | 567 | { |
637 | struct drm_device *dev = connector->dev; | 568 | struct drm_device *dev = connector->dev; |
638 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 569 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
570 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
639 | struct drm_i915_private *dev_priv = dev->dev_private; | 571 | struct drm_i915_private *dev_priv = dev->dev_private; |
640 | int ret = 0; | 572 | int ret = 0; |
641 | 573 | ||
642 | if (dev_priv->lvds_edid_good) { | 574 | if (dev_priv->lvds_edid_good) { |
643 | ret = intel_ddc_get_modes(intel_encoder); | 575 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
644 | 576 | ||
645 | if (ret) | 577 | if (ret) |
646 | return ret; | 578 | return ret; |
@@ -717,11 +649,8 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
717 | static void intel_lvds_destroy(struct drm_connector *connector) | 649 | static void intel_lvds_destroy(struct drm_connector *connector) |
718 | { | 650 | { |
719 | struct drm_device *dev = connector->dev; | 651 | struct drm_device *dev = connector->dev; |
720 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
721 | struct drm_i915_private *dev_priv = dev->dev_private; | 652 | struct drm_i915_private *dev_priv = dev->dev_private; |
722 | 653 | ||
723 | if (intel_encoder->ddc_bus) | ||
724 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
725 | if (dev_priv->lid_notifier.notifier_call) | 654 | if (dev_priv->lid_notifier.notifier_call) |
726 | acpi_lid_notifier_unregister(&dev_priv->lid_notifier); | 655 | acpi_lid_notifier_unregister(&dev_priv->lid_notifier); |
727 | drm_sysfs_connector_remove(connector); | 656 | drm_sysfs_connector_remove(connector); |
@@ -734,13 +663,14 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
734 | uint64_t value) | 663 | uint64_t value) |
735 | { | 664 | { |
736 | struct drm_device *dev = connector->dev; | 665 | struct drm_device *dev = connector->dev; |
737 | struct intel_encoder *intel_encoder = | ||
738 | to_intel_encoder(connector); | ||
739 | 666 | ||
740 | if (property == dev->mode_config.scaling_mode_property && | 667 | if (property == dev->mode_config.scaling_mode_property && |
741 | connector->encoder) { | 668 | connector->encoder) { |
742 | struct drm_crtc *crtc = connector->encoder->crtc; | 669 | struct drm_crtc *crtc = connector->encoder->crtc; |
670 | struct drm_encoder *encoder = connector->encoder; | ||
671 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
743 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | 672 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; |
673 | |||
744 | if (value == DRM_MODE_SCALE_NONE) { | 674 | if (value == DRM_MODE_SCALE_NONE) { |
745 | DRM_DEBUG_KMS("no scaling not supported\n"); | 675 | DRM_DEBUG_KMS("no scaling not supported\n"); |
746 | return 0; | 676 | return 0; |
@@ -774,13 +704,11 @@ static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { | |||
774 | static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { | 704 | static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { |
775 | .get_modes = intel_lvds_get_modes, | 705 | .get_modes = intel_lvds_get_modes, |
776 | .mode_valid = intel_lvds_mode_valid, | 706 | .mode_valid = intel_lvds_mode_valid, |
777 | .best_encoder = intel_best_encoder, | 707 | .best_encoder = intel_attached_encoder, |
778 | }; | 708 | }; |
779 | 709 | ||
780 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { | 710 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
781 | .dpms = drm_helper_connector_dpms, | 711 | .dpms = drm_helper_connector_dpms, |
782 | .save = intel_lvds_save, | ||
783 | .restore = intel_lvds_restore, | ||
784 | .detect = intel_lvds_detect, | 712 | .detect = intel_lvds_detect, |
785 | .fill_modes = drm_helper_probe_single_connector_modes, | 713 | .fill_modes = drm_helper_probe_single_connector_modes, |
786 | .set_property = intel_lvds_set_property, | 714 | .set_property = intel_lvds_set_property, |
@@ -790,7 +718,12 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { | |||
790 | 718 | ||
791 | static void intel_lvds_enc_destroy(struct drm_encoder *encoder) | 719 | static void intel_lvds_enc_destroy(struct drm_encoder *encoder) |
792 | { | 720 | { |
721 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
722 | |||
723 | if (intel_encoder->ddc_bus) | ||
724 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
793 | drm_encoder_cleanup(encoder); | 725 | drm_encoder_cleanup(encoder); |
726 | kfree(intel_encoder); | ||
794 | } | 727 | } |
795 | 728 | ||
796 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { | 729 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { |
@@ -979,6 +912,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
979 | { | 912 | { |
980 | struct drm_i915_private *dev_priv = dev->dev_private; | 913 | struct drm_i915_private *dev_priv = dev->dev_private; |
981 | struct intel_encoder *intel_encoder; | 914 | struct intel_encoder *intel_encoder; |
915 | struct intel_connector *intel_connector; | ||
982 | struct drm_connector *connector; | 916 | struct drm_connector *connector; |
983 | struct drm_encoder *encoder; | 917 | struct drm_encoder *encoder; |
984 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 918 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
@@ -1012,19 +946,27 @@ void intel_lvds_init(struct drm_device *dev) | |||
1012 | return; | 946 | return; |
1013 | } | 947 | } |
1014 | 948 | ||
1015 | connector = &intel_encoder->base; | 949 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
950 | if (!intel_connector) { | ||
951 | kfree(intel_encoder); | ||
952 | return; | ||
953 | } | ||
954 | |||
955 | connector = &intel_connector->base; | ||
1016 | encoder = &intel_encoder->enc; | 956 | encoder = &intel_encoder->enc; |
1017 | drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs, | 957 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, |
1018 | DRM_MODE_CONNECTOR_LVDS); | 958 | DRM_MODE_CONNECTOR_LVDS); |
1019 | 959 | ||
1020 | drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs, | 960 | drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs, |
1021 | DRM_MODE_ENCODER_LVDS); | 961 | DRM_MODE_ENCODER_LVDS); |
1022 | 962 | ||
1023 | drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); | 963 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); |
1024 | intel_encoder->type = INTEL_OUTPUT_LVDS; | 964 | intel_encoder->type = INTEL_OUTPUT_LVDS; |
1025 | 965 | ||
1026 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | 966 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); |
1027 | intel_encoder->crtc_mask = (1 << 1); | 967 | intel_encoder->crtc_mask = (1 << 1); |
968 | if (IS_I965G(dev)) | ||
969 | intel_encoder->crtc_mask |= (1 << 0); | ||
1028 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); | 970 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); |
1029 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); | 971 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); |
1030 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 972 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
@@ -1039,7 +981,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
1039 | * the initial panel fitting mode will be FULL_SCREEN. | 981 | * the initial panel fitting mode will be FULL_SCREEN. |
1040 | */ | 982 | */ |
1041 | 983 | ||
1042 | drm_connector_attach_property(&intel_encoder->base, | 984 | drm_connector_attach_property(&intel_connector->base, |
1043 | dev->mode_config.scaling_mode_property, | 985 | dev->mode_config.scaling_mode_property, |
1044 | DRM_MODE_SCALE_FULLSCREEN); | 986 | DRM_MODE_SCALE_FULLSCREEN); |
1045 | lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; | 987 | lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; |
@@ -1067,7 +1009,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
1067 | */ | 1009 | */ |
1068 | dev_priv->lvds_edid_good = true; | 1010 | dev_priv->lvds_edid_good = true; |
1069 | 1011 | ||
1070 | if (!intel_ddc_get_modes(intel_encoder)) | 1012 | if (!intel_ddc_get_modes(connector, intel_encoder->ddc_bus)) |
1071 | dev_priv->lvds_edid_good = false; | 1013 | dev_priv->lvds_edid_good = false; |
1072 | 1014 | ||
1073 | list_for_each_entry(scan, &connector->probed_modes, head) { | 1015 | list_for_each_entry(scan, &connector->probed_modes, head) { |
@@ -1151,4 +1093,5 @@ failed: | |||
1151 | drm_connector_cleanup(connector); | 1093 | drm_connector_cleanup(connector); |
1152 | drm_encoder_cleanup(encoder); | 1094 | drm_encoder_cleanup(encoder); |
1153 | kfree(intel_encoder); | 1095 | kfree(intel_encoder); |
1096 | kfree(intel_connector); | ||
1154 | } | 1097 | } |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 8e5c83b2d120..4b1fd3d9c73c 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -54,9 +54,9 @@ bool intel_ddc_probe(struct intel_encoder *intel_encoder) | |||
54 | } | 54 | } |
55 | }; | 55 | }; |
56 | 56 | ||
57 | intel_i2c_quirk_set(intel_encoder->base.dev, true); | 57 | intel_i2c_quirk_set(intel_encoder->enc.dev, true); |
58 | ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2); | 58 | ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2); |
59 | intel_i2c_quirk_set(intel_encoder->base.dev, false); | 59 | intel_i2c_quirk_set(intel_encoder->enc.dev, false); |
60 | if (ret == 2) | 60 | if (ret == 2) |
61 | return true; | 61 | return true; |
62 | 62 | ||
@@ -66,22 +66,23 @@ bool intel_ddc_probe(struct intel_encoder *intel_encoder) | |||
66 | /** | 66 | /** |
67 | * intel_ddc_get_modes - get modelist from monitor | 67 | * intel_ddc_get_modes - get modelist from monitor |
68 | * @connector: DRM connector device to use | 68 | * @connector: DRM connector device to use |
69 | * @adapter: i2c adapter | ||
69 | * | 70 | * |
70 | * Fetch the EDID information from @connector using the DDC bus. | 71 | * Fetch the EDID information from @connector using the DDC bus. |
71 | */ | 72 | */ |
72 | int intel_ddc_get_modes(struct intel_encoder *intel_encoder) | 73 | int intel_ddc_get_modes(struct drm_connector *connector, |
74 | struct i2c_adapter *adapter) | ||
73 | { | 75 | { |
74 | struct edid *edid; | 76 | struct edid *edid; |
75 | int ret = 0; | 77 | int ret = 0; |
76 | 78 | ||
77 | intel_i2c_quirk_set(intel_encoder->base.dev, true); | 79 | intel_i2c_quirk_set(connector->dev, true); |
78 | edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus); | 80 | edid = drm_get_edid(connector, adapter); |
79 | intel_i2c_quirk_set(intel_encoder->base.dev, false); | 81 | intel_i2c_quirk_set(connector->dev, false); |
80 | if (edid) { | 82 | if (edid) { |
81 | drm_mode_connector_update_edid_property(&intel_encoder->base, | 83 | drm_mode_connector_update_edid_property(connector, edid); |
82 | edid); | 84 | ret = drm_add_edid_modes(connector, edid); |
83 | ret = drm_add_edid_modes(&intel_encoder->base, edid); | 85 | connector->display_info.raw_edid = NULL; |
84 | intel_encoder->base.display_info.raw_edid = NULL; | ||
85 | kfree(edid); | 86 | kfree(edid); |
86 | } | 87 | } |
87 | 88 | ||
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 6d524a1fc271..b0e17b06eb6e 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -373,7 +373,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay) | |||
373 | 373 | ||
374 | /* never have the overlay hw on without showing a frame */ | 374 | /* never have the overlay hw on without showing a frame */ |
375 | BUG_ON(!overlay->vid_bo); | 375 | BUG_ON(!overlay->vid_bo); |
376 | obj = overlay->vid_bo->obj; | 376 | obj = &overlay->vid_bo->base; |
377 | 377 | ||
378 | i915_gem_object_unpin(obj); | 378 | i915_gem_object_unpin(obj); |
379 | drm_gem_object_unreference(obj); | 379 | drm_gem_object_unreference(obj); |
@@ -411,7 +411,7 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, | |||
411 | 411 | ||
412 | switch (overlay->hw_wedged) { | 412 | switch (overlay->hw_wedged) { |
413 | case RELEASE_OLD_VID: | 413 | case RELEASE_OLD_VID: |
414 | obj = overlay->old_vid_bo->obj; | 414 | obj = &overlay->old_vid_bo->base; |
415 | i915_gem_object_unpin(obj); | 415 | i915_gem_object_unpin(obj); |
416 | drm_gem_object_unreference(obj); | 416 | drm_gem_object_unreference(obj); |
417 | overlay->old_vid_bo = NULL; | 417 | overlay->old_vid_bo = NULL; |
@@ -467,7 +467,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) | |||
467 | if (ret != 0) | 467 | if (ret != 0) |
468 | return ret; | 468 | return ret; |
469 | 469 | ||
470 | obj = overlay->old_vid_bo->obj; | 470 | obj = &overlay->old_vid_bo->base; |
471 | i915_gem_object_unpin(obj); | 471 | i915_gem_object_unpin(obj); |
472 | drm_gem_object_unreference(obj); | 472 | drm_gem_object_unreference(obj); |
473 | overlay->old_vid_bo = NULL; | 473 | overlay->old_vid_bo = NULL; |
@@ -1341,7 +1341,7 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1341 | return; | 1341 | return; |
1342 | overlay->dev = dev; | 1342 | overlay->dev = dev; |
1343 | 1343 | ||
1344 | reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE); | 1344 | reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); |
1345 | if (!reg_bo) | 1345 | if (!reg_bo) |
1346 | goto out_free; | 1346 | goto out_free; |
1347 | overlay->reg_bo = to_intel_bo(reg_bo); | 1347 | overlay->reg_bo = to_intel_bo(reg_bo); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 87d953664cb0..aba72c489a2f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -36,7 +36,18 @@ | |||
36 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
37 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
38 | #include "intel_sdvo_regs.h" | 38 | #include "intel_sdvo_regs.h" |
39 | #include <linux/dmi.h> | 39 | |
40 | #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) | ||
41 | #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) | ||
42 | #define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1) | ||
43 | #define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0) | ||
44 | |||
45 | #define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\ | ||
46 | SDVO_TV_MASK) | ||
47 | |||
48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) | ||
49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | ||
50 | |||
40 | 51 | ||
41 | static char *tv_format_names[] = { | 52 | static char *tv_format_names[] = { |
42 | "NTSC_M" , "NTSC_J" , "NTSC_443", | 53 | "NTSC_M" , "NTSC_J" , "NTSC_443", |
@@ -86,12 +97,6 @@ struct intel_sdvo_priv { | |||
86 | /* This is for current tv format name */ | 97 | /* This is for current tv format name */ |
87 | char *tv_format_name; | 98 | char *tv_format_name; |
88 | 99 | ||
89 | /* This contains all current supported TV format */ | ||
90 | char *tv_format_supported[TV_FORMAT_NUM]; | ||
91 | int format_supported_num; | ||
92 | struct drm_property *tv_format_property; | ||
93 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
94 | |||
95 | /** | 100 | /** |
96 | * This is set if we treat the device as HDMI, instead of DVI. | 101 | * This is set if we treat the device as HDMI, instead of DVI. |
97 | */ | 102 | */ |
@@ -112,12 +117,6 @@ struct intel_sdvo_priv { | |||
112 | */ | 117 | */ |
113 | struct drm_display_mode *sdvo_lvds_fixed_mode; | 118 | struct drm_display_mode *sdvo_lvds_fixed_mode; |
114 | 119 | ||
115 | /** | ||
116 | * Returned SDTV resolutions allowed for the current format, if the | ||
117 | * device reported it. | ||
118 | */ | ||
119 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | ||
120 | |||
121 | /* | 120 | /* |
122 | * supported encoding mode, used to determine whether HDMI is | 121 | * supported encoding mode, used to determine whether HDMI is |
123 | * supported | 122 | * supported |
@@ -130,11 +129,24 @@ struct intel_sdvo_priv { | |||
130 | /* Mac mini hack -- use the same DDC as the analog connector */ | 129 | /* Mac mini hack -- use the same DDC as the analog connector */ |
131 | struct i2c_adapter *analog_ddc_bus; | 130 | struct i2c_adapter *analog_ddc_bus; |
132 | 131 | ||
133 | int save_sdvo_mult; | 132 | }; |
134 | u16 save_active_outputs; | 133 | |
135 | struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; | 134 | struct intel_sdvo_connector { |
136 | struct intel_sdvo_dtd save_output_dtd[16]; | 135 | /* Mark the type of connector */ |
137 | u32 save_SDVOX; | 136 | uint16_t output_flag; |
137 | |||
138 | /* This contains all current supported TV format */ | ||
139 | char *tv_format_supported[TV_FORMAT_NUM]; | ||
140 | int format_supported_num; | ||
141 | struct drm_property *tv_format_property; | ||
142 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
143 | |||
144 | /** | ||
145 | * Returned SDTV resolutions allowed for the current format, if the | ||
146 | * device reported it. | ||
147 | */ | ||
148 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | ||
149 | |||
138 | /* add the property for the SDVO-TV */ | 150 | /* add the property for the SDVO-TV */ |
139 | struct drm_property *left_property; | 151 | struct drm_property *left_property; |
140 | struct drm_property *right_property; | 152 | struct drm_property *right_property; |
@@ -162,7 +174,12 @@ struct intel_sdvo_priv { | |||
162 | }; | 174 | }; |
163 | 175 | ||
164 | static bool | 176 | static bool |
165 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags); | 177 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, |
178 | uint16_t flags); | ||
179 | static void | ||
180 | intel_sdvo_tv_create_property(struct drm_connector *connector, int type); | ||
181 | static void | ||
182 | intel_sdvo_create_enhance_property(struct drm_connector *connector); | ||
166 | 183 | ||
167 | /** | 184 | /** |
168 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 185 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
@@ -171,12 +188,18 @@ intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags); | |||
171 | */ | 188 | */ |
172 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | 189 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) |
173 | { | 190 | { |
174 | struct drm_device *dev = intel_encoder->base.dev; | 191 | struct drm_device *dev = intel_encoder->enc.dev; |
175 | struct drm_i915_private *dev_priv = dev->dev_private; | 192 | struct drm_i915_private *dev_priv = dev->dev_private; |
176 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 193 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
177 | u32 bval = val, cval = val; | 194 | u32 bval = val, cval = val; |
178 | int i; | 195 | int i; |
179 | 196 | ||
197 | if (sdvo_priv->sdvo_reg == PCH_SDVOB) { | ||
198 | I915_WRITE(sdvo_priv->sdvo_reg, val); | ||
199 | I915_READ(sdvo_priv->sdvo_reg); | ||
200 | return; | ||
201 | } | ||
202 | |||
180 | if (sdvo_priv->sdvo_reg == SDVOB) { | 203 | if (sdvo_priv->sdvo_reg == SDVOB) { |
181 | cval = I915_READ(SDVOC); | 204 | cval = I915_READ(SDVOC); |
182 | } else { | 205 | } else { |
@@ -353,7 +376,8 @@ static const struct _sdvo_cmd_name { | |||
353 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), | 376 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), |
354 | }; | 377 | }; |
355 | 378 | ||
356 | #define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC") | 379 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) |
380 | #define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC") | ||
357 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) | 381 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) |
358 | 382 | ||
359 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | 383 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, |
@@ -563,17 +587,6 @@ static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, b | |||
563 | return true; | 587 | return true; |
564 | } | 588 | } |
565 | 589 | ||
566 | static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder, | ||
567 | u16 *outputs) | ||
568 | { | ||
569 | u8 status; | ||
570 | |||
571 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); | ||
572 | status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs)); | ||
573 | |||
574 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
575 | } | ||
576 | |||
577 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, | 590 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, |
578 | u16 outputs) | 591 | u16 outputs) |
579 | { | 592 | { |
@@ -646,40 +659,6 @@ static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, | |||
646 | return (status == SDVO_CMD_STATUS_SUCCESS); | 659 | return (status == SDVO_CMD_STATUS_SUCCESS); |
647 | } | 660 | } |
648 | 661 | ||
649 | static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd, | ||
650 | struct intel_sdvo_dtd *dtd) | ||
651 | { | ||
652 | u8 status; | ||
653 | |||
654 | intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0); | ||
655 | status = intel_sdvo_read_response(intel_encoder, &dtd->part1, | ||
656 | sizeof(dtd->part1)); | ||
657 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
658 | return false; | ||
659 | |||
660 | intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0); | ||
661 | status = intel_sdvo_read_response(intel_encoder, &dtd->part2, | ||
662 | sizeof(dtd->part2)); | ||
663 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
664 | return false; | ||
665 | |||
666 | return true; | ||
667 | } | ||
668 | |||
669 | static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder, | ||
670 | struct intel_sdvo_dtd *dtd) | ||
671 | { | ||
672 | return intel_sdvo_get_timing(intel_encoder, | ||
673 | SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); | ||
674 | } | ||
675 | |||
676 | static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder, | ||
677 | struct intel_sdvo_dtd *dtd) | ||
678 | { | ||
679 | return intel_sdvo_get_timing(intel_encoder, | ||
680 | SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd); | ||
681 | } | ||
682 | |||
683 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, | 662 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, |
684 | struct intel_sdvo_dtd *dtd) | 663 | struct intel_sdvo_dtd *dtd) |
685 | { | 664 | { |
@@ -767,23 +746,6 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_en | |||
767 | return false; | 746 | return false; |
768 | } | 747 | } |
769 | 748 | ||
770 | static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder) | ||
771 | { | ||
772 | u8 response, status; | ||
773 | |||
774 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); | ||
775 | status = intel_sdvo_read_response(intel_encoder, &response, 1); | ||
776 | |||
777 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
778 | DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n"); | ||
779 | return SDVO_CLOCK_RATE_MULT_1X; | ||
780 | } else { | ||
781 | DRM_DEBUG_KMS("Current clock rate multiplier: %d\n", response); | ||
782 | } | ||
783 | |||
784 | return response; | ||
785 | } | ||
786 | |||
787 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) | 749 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) |
788 | { | 750 | { |
789 | u8 status; | 751 | u8 status; |
@@ -1071,7 +1033,7 @@ static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) | |||
1071 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? | 1033 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? |
1072 | sizeof(format) : sizeof(format_map)); | 1034 | sizeof(format) : sizeof(format_map)); |
1073 | 1035 | ||
1074 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map, | 1036 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format, |
1075 | sizeof(format)); | 1037 | sizeof(format)); |
1076 | 1038 | ||
1077 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 1039 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
@@ -1101,7 +1063,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1101 | /* Set output timings */ | 1063 | /* Set output timings */ |
1102 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1064 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1103 | intel_sdvo_set_target_output(intel_encoder, | 1065 | intel_sdvo_set_target_output(intel_encoder, |
1104 | dev_priv->controlled_output); | 1066 | dev_priv->attached_output); |
1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | 1067 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); |
1106 | 1068 | ||
1107 | /* Set the input timing to the screen. Assume always input 0. */ | 1069 | /* Set the input timing to the screen. Assume always input 0. */ |
@@ -1139,7 +1101,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1139 | dev_priv->sdvo_lvds_fixed_mode); | 1101 | dev_priv->sdvo_lvds_fixed_mode); |
1140 | 1102 | ||
1141 | intel_sdvo_set_target_output(intel_encoder, | 1103 | intel_sdvo_set_target_output(intel_encoder, |
1142 | dev_priv->controlled_output); | 1104 | dev_priv->attached_output); |
1143 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | 1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); |
1144 | 1106 | ||
1145 | /* Set the input timing to the screen. Assume always input 0. */ | 1107 | /* Set the input timing to the screen. Assume always input 0. */ |
@@ -1204,7 +1166,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1204 | * channel on the motherboard. In a two-input device, the first input | 1166 | * channel on the motherboard. In a two-input device, the first input |
1205 | * will be SDVOB and the second SDVOC. | 1167 | * will be SDVOB and the second SDVOC. |
1206 | */ | 1168 | */ |
1207 | in_out.in0 = sdvo_priv->controlled_output; | 1169 | in_out.in0 = sdvo_priv->attached_output; |
1208 | in_out.in1 = 0; | 1170 | in_out.in1 = 0; |
1209 | 1171 | ||
1210 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, | 1172 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, |
@@ -1230,7 +1192,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1230 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { | 1192 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1231 | /* Set the output timing to the screen */ | 1193 | /* Set the output timing to the screen */ |
1232 | intel_sdvo_set_target_output(intel_encoder, | 1194 | intel_sdvo_set_target_output(intel_encoder, |
1233 | sdvo_priv->controlled_output); | 1195 | sdvo_priv->attached_output); |
1234 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); | 1196 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); |
1235 | } | 1197 | } |
1236 | 1198 | ||
@@ -1352,107 +1314,16 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1352 | 1314 | ||
1353 | if (0) | 1315 | if (0) |
1354 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1316 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); |
1355 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output); | 1317 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->attached_output); |
1356 | } | 1318 | } |
1357 | return; | 1319 | return; |
1358 | } | 1320 | } |
1359 | 1321 | ||
1360 | static void intel_sdvo_save(struct drm_connector *connector) | ||
1361 | { | ||
1362 | struct drm_device *dev = connector->dev; | ||
1363 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1364 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
1365 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1366 | int o; | ||
1367 | |||
1368 | sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder); | ||
1369 | intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs); | ||
1370 | |||
1371 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { | ||
1372 | intel_sdvo_set_target_input(intel_encoder, true, false); | ||
1373 | intel_sdvo_get_input_timing(intel_encoder, | ||
1374 | &sdvo_priv->save_input_dtd_1); | ||
1375 | } | ||
1376 | |||
1377 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { | ||
1378 | intel_sdvo_set_target_input(intel_encoder, false, true); | ||
1379 | intel_sdvo_get_input_timing(intel_encoder, | ||
1380 | &sdvo_priv->save_input_dtd_2); | ||
1381 | } | ||
1382 | |||
1383 | for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) | ||
1384 | { | ||
1385 | u16 this_output = (1 << o); | ||
1386 | if (sdvo_priv->caps.output_flags & this_output) | ||
1387 | { | ||
1388 | intel_sdvo_set_target_output(intel_encoder, this_output); | ||
1389 | intel_sdvo_get_output_timing(intel_encoder, | ||
1390 | &sdvo_priv->save_output_dtd[o]); | ||
1391 | } | ||
1392 | } | ||
1393 | if (sdvo_priv->is_tv) { | ||
1394 | /* XXX: Save TV format/enhancements. */ | ||
1395 | } | ||
1396 | |||
1397 | sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg); | ||
1398 | } | ||
1399 | |||
1400 | static void intel_sdvo_restore(struct drm_connector *connector) | ||
1401 | { | ||
1402 | struct drm_device *dev = connector->dev; | ||
1403 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
1404 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1405 | int o; | ||
1406 | int i; | ||
1407 | bool input1, input2; | ||
1408 | u8 status; | ||
1409 | |||
1410 | intel_sdvo_set_active_outputs(intel_encoder, 0); | ||
1411 | |||
1412 | for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) | ||
1413 | { | ||
1414 | u16 this_output = (1 << o); | ||
1415 | if (sdvo_priv->caps.output_flags & this_output) { | ||
1416 | intel_sdvo_set_target_output(intel_encoder, this_output); | ||
1417 | intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]); | ||
1418 | } | ||
1419 | } | ||
1420 | |||
1421 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { | ||
1422 | intel_sdvo_set_target_input(intel_encoder, true, false); | ||
1423 | intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1); | ||
1424 | } | ||
1425 | |||
1426 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { | ||
1427 | intel_sdvo_set_target_input(intel_encoder, false, true); | ||
1428 | intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2); | ||
1429 | } | ||
1430 | |||
1431 | intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult); | ||
1432 | |||
1433 | if (sdvo_priv->is_tv) { | ||
1434 | /* XXX: Restore TV format/enhancements. */ | ||
1435 | } | ||
1436 | |||
1437 | intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX); | ||
1438 | |||
1439 | if (sdvo_priv->save_SDVOX & SDVO_ENABLE) | ||
1440 | { | ||
1441 | for (i = 0; i < 2; i++) | ||
1442 | intel_wait_for_vblank(dev); | ||
1443 | status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2); | ||
1444 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) | ||
1445 | DRM_DEBUG_KMS("First %s output reported failure to " | ||
1446 | "sync\n", SDVO_NAME(sdvo_priv)); | ||
1447 | } | ||
1448 | |||
1449 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs); | ||
1450 | } | ||
1451 | |||
1452 | static int intel_sdvo_mode_valid(struct drm_connector *connector, | 1322 | static int intel_sdvo_mode_valid(struct drm_connector *connector, |
1453 | struct drm_display_mode *mode) | 1323 | struct drm_display_mode *mode) |
1454 | { | 1324 | { |
1455 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1325 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1326 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1456 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1327 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1457 | 1328 | ||
1458 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1329 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
@@ -1490,6 +1361,8 @@ static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, str | |||
1490 | return true; | 1361 | return true; |
1491 | } | 1362 | } |
1492 | 1363 | ||
1364 | /* No use! */ | ||
1365 | #if 0 | ||
1493 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) | 1366 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) |
1494 | { | 1367 | { |
1495 | struct drm_connector *connector = NULL; | 1368 | struct drm_connector *connector = NULL; |
@@ -1560,6 +1433,7 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | |||
1560 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1433 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
1561 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1434 | intel_sdvo_read_response(intel_encoder, &response, 2); |
1562 | } | 1435 | } |
1436 | #endif | ||
1563 | 1437 | ||
1564 | static bool | 1438 | static bool |
1565 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) | 1439 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) |
@@ -1598,12 +1472,17 @@ static struct drm_connector * | |||
1598 | intel_find_analog_connector(struct drm_device *dev) | 1472 | intel_find_analog_connector(struct drm_device *dev) |
1599 | { | 1473 | { |
1600 | struct drm_connector *connector; | 1474 | struct drm_connector *connector; |
1475 | struct drm_encoder *encoder; | ||
1601 | struct intel_encoder *intel_encoder; | 1476 | struct intel_encoder *intel_encoder; |
1602 | 1477 | ||
1603 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1478 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1604 | intel_encoder = to_intel_encoder(connector); | 1479 | intel_encoder = enc_to_intel_encoder(encoder); |
1605 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) | 1480 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { |
1606 | return connector; | 1481 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1482 | if (connector && encoder == intel_attached_encoder(connector)) | ||
1483 | return connector; | ||
1484 | } | ||
1485 | } | ||
1607 | } | 1486 | } |
1608 | return NULL; | 1487 | return NULL; |
1609 | } | 1488 | } |
@@ -1625,15 +1504,17 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1625 | } | 1504 | } |
1626 | 1505 | ||
1627 | enum drm_connector_status | 1506 | enum drm_connector_status |
1628 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | 1507 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) |
1629 | { | 1508 | { |
1630 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1509 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1510 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1631 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1511 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1512 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1513 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1632 | enum drm_connector_status status = connector_status_connected; | 1514 | enum drm_connector_status status = connector_status_connected; |
1633 | struct edid *edid = NULL; | 1515 | struct edid *edid = NULL; |
1634 | 1516 | ||
1635 | edid = drm_get_edid(&intel_encoder->base, | 1517 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); |
1636 | intel_encoder->ddc_bus); | ||
1637 | 1518 | ||
1638 | /* This is only applied to SDVO cards with multiple outputs */ | 1519 | /* This is only applied to SDVO cards with multiple outputs */ |
1639 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { | 1520 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { |
@@ -1646,8 +1527,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1646 | */ | 1527 | */ |
1647 | while(temp_ddc > 1) { | 1528 | while(temp_ddc > 1) { |
1648 | sdvo_priv->ddc_bus = temp_ddc; | 1529 | sdvo_priv->ddc_bus = temp_ddc; |
1649 | edid = drm_get_edid(&intel_encoder->base, | 1530 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); |
1650 | intel_encoder->ddc_bus); | ||
1651 | if (edid) { | 1531 | if (edid) { |
1652 | /* | 1532 | /* |
1653 | * When we can get the EDID, maybe it is the | 1533 | * When we can get the EDID, maybe it is the |
@@ -1664,28 +1544,25 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1664 | /* when there is no edid and no monitor is connected with VGA | 1544 | /* when there is no edid and no monitor is connected with VGA |
1665 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1545 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
1666 | */ | 1546 | */ |
1667 | if (edid == NULL && | 1547 | if (edid == NULL && sdvo_priv->analog_ddc_bus && |
1668 | sdvo_priv->analog_ddc_bus && | 1548 | !intel_analog_is_connected(connector->dev)) |
1669 | !intel_analog_is_connected(intel_encoder->base.dev)) | 1549 | edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus); |
1670 | edid = drm_get_edid(&intel_encoder->base, | 1550 | |
1671 | sdvo_priv->analog_ddc_bus); | ||
1672 | if (edid != NULL) { | 1551 | if (edid != NULL) { |
1673 | /* Don't report the output as connected if it's a DVI-I | 1552 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); |
1674 | * connector with a non-digital EDID coming out. | 1553 | bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK); |
1675 | */ | ||
1676 | if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1677 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
1678 | sdvo_priv->is_hdmi = | ||
1679 | drm_detect_hdmi_monitor(edid); | ||
1680 | else | ||
1681 | status = connector_status_disconnected; | ||
1682 | } | ||
1683 | 1554 | ||
1684 | kfree(edid); | 1555 | /* DDC bus is shared, match EDID to connector type */ |
1685 | intel_encoder->base.display_info.raw_edid = NULL; | 1556 | if (is_digital && need_digital) |
1557 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | ||
1558 | else if (is_digital != need_digital) | ||
1559 | status = connector_status_disconnected; | ||
1686 | 1560 | ||
1687 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1561 | connector->display_info.raw_edid = NULL; |
1562 | } else | ||
1688 | status = connector_status_disconnected; | 1563 | status = connector_status_disconnected; |
1564 | |||
1565 | kfree(edid); | ||
1689 | 1566 | ||
1690 | return status; | 1567 | return status; |
1691 | } | 1568 | } |
@@ -1694,8 +1571,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1694 | { | 1571 | { |
1695 | uint16_t response; | 1572 | uint16_t response; |
1696 | u8 status; | 1573 | u8 status; |
1697 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1574 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1575 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1576 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1698 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1577 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1578 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1579 | enum drm_connector_status ret; | ||
1699 | 1580 | ||
1700 | intel_sdvo_write_cmd(intel_encoder, | 1581 | intel_sdvo_write_cmd(intel_encoder, |
1701 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1582 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); |
@@ -1713,24 +1594,41 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1713 | if (response == 0) | 1594 | if (response == 0) |
1714 | return connector_status_disconnected; | 1595 | return connector_status_disconnected; |
1715 | 1596 | ||
1716 | if (intel_sdvo_multifunc_encoder(intel_encoder) && | 1597 | sdvo_priv->attached_output = response; |
1717 | sdvo_priv->attached_output != response) { | 1598 | |
1718 | if (sdvo_priv->controlled_output != response && | 1599 | if ((sdvo_connector->output_flag & response) == 0) |
1719 | intel_sdvo_output_setup(intel_encoder, response) != true) | 1600 | ret = connector_status_disconnected; |
1720 | return connector_status_unknown; | 1601 | else if (response & SDVO_TMDS_MASK) |
1721 | sdvo_priv->attached_output = response; | 1602 | ret = intel_sdvo_hdmi_sink_detect(connector); |
1603 | else | ||
1604 | ret = connector_status_connected; | ||
1605 | |||
1606 | /* May update encoder flag for like clock for SDVO TV, etc.*/ | ||
1607 | if (ret == connector_status_connected) { | ||
1608 | sdvo_priv->is_tv = false; | ||
1609 | sdvo_priv->is_lvds = false; | ||
1610 | intel_encoder->needs_tv_clock = false; | ||
1611 | |||
1612 | if (response & SDVO_TV_MASK) { | ||
1613 | sdvo_priv->is_tv = true; | ||
1614 | intel_encoder->needs_tv_clock = true; | ||
1615 | } | ||
1616 | if (response & SDVO_LVDS_MASK) | ||
1617 | sdvo_priv->is_lvds = true; | ||
1722 | } | 1618 | } |
1723 | return intel_sdvo_hdmi_sink_detect(connector, response); | 1619 | |
1620 | return ret; | ||
1724 | } | 1621 | } |
1725 | 1622 | ||
1726 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1623 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1727 | { | 1624 | { |
1728 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1625 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1626 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1729 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1627 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1730 | int num_modes; | 1628 | int num_modes; |
1731 | 1629 | ||
1732 | /* set the bus switch and get the modes */ | 1630 | /* set the bus switch and get the modes */ |
1733 | num_modes = intel_ddc_get_modes(intel_encoder); | 1631 | num_modes = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
1734 | 1632 | ||
1735 | /* | 1633 | /* |
1736 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1634 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
@@ -1740,17 +1638,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1740 | */ | 1638 | */ |
1741 | if (num_modes == 0 && | 1639 | if (num_modes == 0 && |
1742 | sdvo_priv->analog_ddc_bus && | 1640 | sdvo_priv->analog_ddc_bus && |
1743 | !intel_analog_is_connected(intel_encoder->base.dev)) { | 1641 | !intel_analog_is_connected(connector->dev)) { |
1744 | struct i2c_adapter *digital_ddc_bus; | ||
1745 | |||
1746 | /* Switch to the analog ddc bus and try that | 1642 | /* Switch to the analog ddc bus and try that |
1747 | */ | 1643 | */ |
1748 | digital_ddc_bus = intel_encoder->ddc_bus; | 1644 | (void) intel_ddc_get_modes(connector, sdvo_priv->analog_ddc_bus); |
1749 | intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus; | ||
1750 | |||
1751 | (void) intel_ddc_get_modes(intel_encoder); | ||
1752 | |||
1753 | intel_encoder->ddc_bus = digital_ddc_bus; | ||
1754 | } | 1645 | } |
1755 | } | 1646 | } |
1756 | 1647 | ||
@@ -1821,8 +1712,9 @@ struct drm_display_mode sdvo_tv_modes[] = { | |||
1821 | 1712 | ||
1822 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | 1713 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) |
1823 | { | 1714 | { |
1824 | struct intel_encoder *output = to_intel_encoder(connector); | 1715 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1825 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1716 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1717 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1826 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1718 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1827 | uint32_t reply = 0, format_map = 0; | 1719 | uint32_t reply = 0, format_map = 0; |
1828 | int i; | 1720 | int i; |
@@ -1842,11 +1734,11 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1842 | sizeof(format_map) ? sizeof(format_map) : | 1734 | sizeof(format_map) ? sizeof(format_map) : |
1843 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | 1735 | sizeof(struct intel_sdvo_sdtv_resolution_request)); |
1844 | 1736 | ||
1845 | intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); | 1737 | intel_sdvo_set_target_output(intel_encoder, sdvo_priv->attached_output); |
1846 | 1738 | ||
1847 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1739 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
1848 | &tv_res, sizeof(tv_res)); | 1740 | &tv_res, sizeof(tv_res)); |
1849 | status = intel_sdvo_read_response(output, &reply, 3); | 1741 | status = intel_sdvo_read_response(intel_encoder, &reply, 3); |
1850 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1742 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1851 | return; | 1743 | return; |
1852 | 1744 | ||
@@ -1863,7 +1755,8 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1863 | 1755 | ||
1864 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1756 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1865 | { | 1757 | { |
1866 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1758 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1759 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1867 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1760 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1868 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1761 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1869 | struct drm_display_mode *newmode; | 1762 | struct drm_display_mode *newmode; |
@@ -1873,7 +1766,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1873 | * Assume that the preferred modes are | 1766 | * Assume that the preferred modes are |
1874 | * arranged in priority order. | 1767 | * arranged in priority order. |
1875 | */ | 1768 | */ |
1876 | intel_ddc_get_modes(intel_encoder); | 1769 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
1877 | if (list_empty(&connector->probed_modes) == false) | 1770 | if (list_empty(&connector->probed_modes) == false) |
1878 | goto end; | 1771 | goto end; |
1879 | 1772 | ||
@@ -1902,12 +1795,12 @@ end: | |||
1902 | 1795 | ||
1903 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1796 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
1904 | { | 1797 | { |
1905 | struct intel_encoder *output = to_intel_encoder(connector); | 1798 | struct intel_connector *intel_connector = to_intel_connector(connector); |
1906 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1799 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; |
1907 | 1800 | ||
1908 | if (sdvo_priv->is_tv) | 1801 | if (IS_TV(sdvo_connector)) |
1909 | intel_sdvo_get_tv_modes(connector); | 1802 | intel_sdvo_get_tv_modes(connector); |
1910 | else if (sdvo_priv->is_lvds == true) | 1803 | else if (IS_LVDS(sdvo_connector)) |
1911 | intel_sdvo_get_lvds_modes(connector); | 1804 | intel_sdvo_get_lvds_modes(connector); |
1912 | else | 1805 | else |
1913 | intel_sdvo_get_ddc_modes(connector); | 1806 | intel_sdvo_get_ddc_modes(connector); |
@@ -1920,11 +1813,11 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1920 | static | 1813 | static |
1921 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | 1814 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) |
1922 | { | 1815 | { |
1923 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1816 | struct intel_connector *intel_connector = to_intel_connector(connector); |
1924 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1817 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; |
1925 | struct drm_device *dev = connector->dev; | 1818 | struct drm_device *dev = connector->dev; |
1926 | 1819 | ||
1927 | if (sdvo_priv->is_tv) { | 1820 | if (IS_TV(sdvo_priv)) { |
1928 | if (sdvo_priv->left_property) | 1821 | if (sdvo_priv->left_property) |
1929 | drm_property_destroy(dev, sdvo_priv->left_property); | 1822 | drm_property_destroy(dev, sdvo_priv->left_property); |
1930 | if (sdvo_priv->right_property) | 1823 | if (sdvo_priv->right_property) |
@@ -1937,8 +1830,6 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | |||
1937 | drm_property_destroy(dev, sdvo_priv->hpos_property); | 1830 | drm_property_destroy(dev, sdvo_priv->hpos_property); |
1938 | if (sdvo_priv->vpos_property) | 1831 | if (sdvo_priv->vpos_property) |
1939 | drm_property_destroy(dev, sdvo_priv->vpos_property); | 1832 | drm_property_destroy(dev, sdvo_priv->vpos_property); |
1940 | } | ||
1941 | if (sdvo_priv->is_tv) { | ||
1942 | if (sdvo_priv->saturation_property) | 1833 | if (sdvo_priv->saturation_property) |
1943 | drm_property_destroy(dev, | 1834 | drm_property_destroy(dev, |
1944 | sdvo_priv->saturation_property); | 1835 | sdvo_priv->saturation_property); |
@@ -1948,7 +1839,7 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | |||
1948 | if (sdvo_priv->hue_property) | 1839 | if (sdvo_priv->hue_property) |
1949 | drm_property_destroy(dev, sdvo_priv->hue_property); | 1840 | drm_property_destroy(dev, sdvo_priv->hue_property); |
1950 | } | 1841 | } |
1951 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 1842 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { |
1952 | if (sdvo_priv->brightness_property) | 1843 | if (sdvo_priv->brightness_property) |
1953 | drm_property_destroy(dev, | 1844 | drm_property_destroy(dev, |
1954 | sdvo_priv->brightness_property); | 1845 | sdvo_priv->brightness_property); |
@@ -1958,31 +1849,17 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | |||
1958 | 1849 | ||
1959 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1850 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1960 | { | 1851 | { |
1961 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1852 | struct intel_connector *intel_connector = to_intel_connector(connector); |
1962 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1853 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; |
1963 | |||
1964 | if (intel_encoder->i2c_bus) | ||
1965 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
1966 | if (intel_encoder->ddc_bus) | ||
1967 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
1968 | if (sdvo_priv->analog_ddc_bus) | ||
1969 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
1970 | |||
1971 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
1972 | drm_mode_destroy(connector->dev, | ||
1973 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
1974 | 1854 | ||
1975 | if (sdvo_priv->tv_format_property) | 1855 | if (sdvo_connector->tv_format_property) |
1976 | drm_property_destroy(connector->dev, | 1856 | drm_property_destroy(connector->dev, |
1977 | sdvo_priv->tv_format_property); | 1857 | sdvo_connector->tv_format_property); |
1978 | |||
1979 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) | ||
1980 | intel_sdvo_destroy_enhance_property(connector); | ||
1981 | 1858 | ||
1859 | intel_sdvo_destroy_enhance_property(connector); | ||
1982 | drm_sysfs_connector_remove(connector); | 1860 | drm_sysfs_connector_remove(connector); |
1983 | drm_connector_cleanup(connector); | 1861 | drm_connector_cleanup(connector); |
1984 | 1862 | kfree(connector); | |
1985 | kfree(intel_encoder); | ||
1986 | } | 1863 | } |
1987 | 1864 | ||
1988 | static int | 1865 | static int |
@@ -1990,9 +1867,11 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1990 | struct drm_property *property, | 1867 | struct drm_property *property, |
1991 | uint64_t val) | 1868 | uint64_t val) |
1992 | { | 1869 | { |
1993 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1870 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1871 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1994 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1872 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1995 | struct drm_encoder *encoder = &intel_encoder->enc; | 1873 | struct intel_connector *intel_connector = to_intel_connector(connector); |
1874 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1996 | struct drm_crtc *crtc = encoder->crtc; | 1875 | struct drm_crtc *crtc = encoder->crtc; |
1997 | int ret = 0; | 1876 | int ret = 0; |
1998 | bool changed = false; | 1877 | bool changed = false; |
@@ -2003,101 +1882,101 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
2003 | if (ret < 0) | 1882 | if (ret < 0) |
2004 | goto out; | 1883 | goto out; |
2005 | 1884 | ||
2006 | if (property == sdvo_priv->tv_format_property) { | 1885 | if (property == sdvo_connector->tv_format_property) { |
2007 | if (val >= TV_FORMAT_NUM) { | 1886 | if (val >= TV_FORMAT_NUM) { |
2008 | ret = -EINVAL; | 1887 | ret = -EINVAL; |
2009 | goto out; | 1888 | goto out; |
2010 | } | 1889 | } |
2011 | if (sdvo_priv->tv_format_name == | 1890 | if (sdvo_priv->tv_format_name == |
2012 | sdvo_priv->tv_format_supported[val]) | 1891 | sdvo_connector->tv_format_supported[val]) |
2013 | goto out; | 1892 | goto out; |
2014 | 1893 | ||
2015 | sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; | 1894 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[val]; |
2016 | changed = true; | 1895 | changed = true; |
2017 | } | 1896 | } |
2018 | 1897 | ||
2019 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 1898 | if (IS_TV(sdvo_connector) || IS_LVDS(sdvo_connector)) { |
2020 | cmd = 0; | 1899 | cmd = 0; |
2021 | temp_value = val; | 1900 | temp_value = val; |
2022 | if (sdvo_priv->left_property == property) { | 1901 | if (sdvo_connector->left_property == property) { |
2023 | drm_connector_property_set_value(connector, | 1902 | drm_connector_property_set_value(connector, |
2024 | sdvo_priv->right_property, val); | 1903 | sdvo_connector->right_property, val); |
2025 | if (sdvo_priv->left_margin == temp_value) | 1904 | if (sdvo_connector->left_margin == temp_value) |
2026 | goto out; | 1905 | goto out; |
2027 | 1906 | ||
2028 | sdvo_priv->left_margin = temp_value; | 1907 | sdvo_connector->left_margin = temp_value; |
2029 | sdvo_priv->right_margin = temp_value; | 1908 | sdvo_connector->right_margin = temp_value; |
2030 | temp_value = sdvo_priv->max_hscan - | 1909 | temp_value = sdvo_connector->max_hscan - |
2031 | sdvo_priv->left_margin; | 1910 | sdvo_connector->left_margin; |
2032 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1911 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
2033 | } else if (sdvo_priv->right_property == property) { | 1912 | } else if (sdvo_connector->right_property == property) { |
2034 | drm_connector_property_set_value(connector, | 1913 | drm_connector_property_set_value(connector, |
2035 | sdvo_priv->left_property, val); | 1914 | sdvo_connector->left_property, val); |
2036 | if (sdvo_priv->right_margin == temp_value) | 1915 | if (sdvo_connector->right_margin == temp_value) |
2037 | goto out; | 1916 | goto out; |
2038 | 1917 | ||
2039 | sdvo_priv->left_margin = temp_value; | 1918 | sdvo_connector->left_margin = temp_value; |
2040 | sdvo_priv->right_margin = temp_value; | 1919 | sdvo_connector->right_margin = temp_value; |
2041 | temp_value = sdvo_priv->max_hscan - | 1920 | temp_value = sdvo_connector->max_hscan - |
2042 | sdvo_priv->left_margin; | 1921 | sdvo_connector->left_margin; |
2043 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1922 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
2044 | } else if (sdvo_priv->top_property == property) { | 1923 | } else if (sdvo_connector->top_property == property) { |
2045 | drm_connector_property_set_value(connector, | 1924 | drm_connector_property_set_value(connector, |
2046 | sdvo_priv->bottom_property, val); | 1925 | sdvo_connector->bottom_property, val); |
2047 | if (sdvo_priv->top_margin == temp_value) | 1926 | if (sdvo_connector->top_margin == temp_value) |
2048 | goto out; | 1927 | goto out; |
2049 | 1928 | ||
2050 | sdvo_priv->top_margin = temp_value; | 1929 | sdvo_connector->top_margin = temp_value; |
2051 | sdvo_priv->bottom_margin = temp_value; | 1930 | sdvo_connector->bottom_margin = temp_value; |
2052 | temp_value = sdvo_priv->max_vscan - | 1931 | temp_value = sdvo_connector->max_vscan - |
2053 | sdvo_priv->top_margin; | 1932 | sdvo_connector->top_margin; |
2054 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1933 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
2055 | } else if (sdvo_priv->bottom_property == property) { | 1934 | } else if (sdvo_connector->bottom_property == property) { |
2056 | drm_connector_property_set_value(connector, | 1935 | drm_connector_property_set_value(connector, |
2057 | sdvo_priv->top_property, val); | 1936 | sdvo_connector->top_property, val); |
2058 | if (sdvo_priv->bottom_margin == temp_value) | 1937 | if (sdvo_connector->bottom_margin == temp_value) |
2059 | goto out; | 1938 | goto out; |
2060 | sdvo_priv->top_margin = temp_value; | 1939 | sdvo_connector->top_margin = temp_value; |
2061 | sdvo_priv->bottom_margin = temp_value; | 1940 | sdvo_connector->bottom_margin = temp_value; |
2062 | temp_value = sdvo_priv->max_vscan - | 1941 | temp_value = sdvo_connector->max_vscan - |
2063 | sdvo_priv->top_margin; | 1942 | sdvo_connector->top_margin; |
2064 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1943 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
2065 | } else if (sdvo_priv->hpos_property == property) { | 1944 | } else if (sdvo_connector->hpos_property == property) { |
2066 | if (sdvo_priv->cur_hpos == temp_value) | 1945 | if (sdvo_connector->cur_hpos == temp_value) |
2067 | goto out; | 1946 | goto out; |
2068 | 1947 | ||
2069 | cmd = SDVO_CMD_SET_POSITION_H; | 1948 | cmd = SDVO_CMD_SET_POSITION_H; |
2070 | sdvo_priv->cur_hpos = temp_value; | 1949 | sdvo_connector->cur_hpos = temp_value; |
2071 | } else if (sdvo_priv->vpos_property == property) { | 1950 | } else if (sdvo_connector->vpos_property == property) { |
2072 | if (sdvo_priv->cur_vpos == temp_value) | 1951 | if (sdvo_connector->cur_vpos == temp_value) |
2073 | goto out; | 1952 | goto out; |
2074 | 1953 | ||
2075 | cmd = SDVO_CMD_SET_POSITION_V; | 1954 | cmd = SDVO_CMD_SET_POSITION_V; |
2076 | sdvo_priv->cur_vpos = temp_value; | 1955 | sdvo_connector->cur_vpos = temp_value; |
2077 | } else if (sdvo_priv->saturation_property == property) { | 1956 | } else if (sdvo_connector->saturation_property == property) { |
2078 | if (sdvo_priv->cur_saturation == temp_value) | 1957 | if (sdvo_connector->cur_saturation == temp_value) |
2079 | goto out; | 1958 | goto out; |
2080 | 1959 | ||
2081 | cmd = SDVO_CMD_SET_SATURATION; | 1960 | cmd = SDVO_CMD_SET_SATURATION; |
2082 | sdvo_priv->cur_saturation = temp_value; | 1961 | sdvo_connector->cur_saturation = temp_value; |
2083 | } else if (sdvo_priv->contrast_property == property) { | 1962 | } else if (sdvo_connector->contrast_property == property) { |
2084 | if (sdvo_priv->cur_contrast == temp_value) | 1963 | if (sdvo_connector->cur_contrast == temp_value) |
2085 | goto out; | 1964 | goto out; |
2086 | 1965 | ||
2087 | cmd = SDVO_CMD_SET_CONTRAST; | 1966 | cmd = SDVO_CMD_SET_CONTRAST; |
2088 | sdvo_priv->cur_contrast = temp_value; | 1967 | sdvo_connector->cur_contrast = temp_value; |
2089 | } else if (sdvo_priv->hue_property == property) { | 1968 | } else if (sdvo_connector->hue_property == property) { |
2090 | if (sdvo_priv->cur_hue == temp_value) | 1969 | if (sdvo_connector->cur_hue == temp_value) |
2091 | goto out; | 1970 | goto out; |
2092 | 1971 | ||
2093 | cmd = SDVO_CMD_SET_HUE; | 1972 | cmd = SDVO_CMD_SET_HUE; |
2094 | sdvo_priv->cur_hue = temp_value; | 1973 | sdvo_connector->cur_hue = temp_value; |
2095 | } else if (sdvo_priv->brightness_property == property) { | 1974 | } else if (sdvo_connector->brightness_property == property) { |
2096 | if (sdvo_priv->cur_brightness == temp_value) | 1975 | if (sdvo_connector->cur_brightness == temp_value) |
2097 | goto out; | 1976 | goto out; |
2098 | 1977 | ||
2099 | cmd = SDVO_CMD_SET_BRIGHTNESS; | 1978 | cmd = SDVO_CMD_SET_BRIGHTNESS; |
2100 | sdvo_priv->cur_brightness = temp_value; | 1979 | sdvo_connector->cur_brightness = temp_value; |
2101 | } | 1980 | } |
2102 | if (cmd) { | 1981 | if (cmd) { |
2103 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); | 1982 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); |
@@ -2127,8 +2006,6 @@ static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | |||
2127 | 2006 | ||
2128 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 2007 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
2129 | .dpms = drm_helper_connector_dpms, | 2008 | .dpms = drm_helper_connector_dpms, |
2130 | .save = intel_sdvo_save, | ||
2131 | .restore = intel_sdvo_restore, | ||
2132 | .detect = intel_sdvo_detect, | 2009 | .detect = intel_sdvo_detect, |
2133 | .fill_modes = drm_helper_probe_single_connector_modes, | 2010 | .fill_modes = drm_helper_probe_single_connector_modes, |
2134 | .set_property = intel_sdvo_set_property, | 2011 | .set_property = intel_sdvo_set_property, |
@@ -2138,12 +2015,27 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | |||
2138 | static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { | 2015 | static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { |
2139 | .get_modes = intel_sdvo_get_modes, | 2016 | .get_modes = intel_sdvo_get_modes, |
2140 | .mode_valid = intel_sdvo_mode_valid, | 2017 | .mode_valid = intel_sdvo_mode_valid, |
2141 | .best_encoder = intel_best_encoder, | 2018 | .best_encoder = intel_attached_encoder, |
2142 | }; | 2019 | }; |
2143 | 2020 | ||
2144 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 2021 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
2145 | { | 2022 | { |
2023 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2024 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2025 | |||
2026 | if (intel_encoder->i2c_bus) | ||
2027 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
2028 | if (intel_encoder->ddc_bus) | ||
2029 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2030 | if (sdvo_priv->analog_ddc_bus) | ||
2031 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
2032 | |||
2033 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
2034 | drm_mode_destroy(encoder->dev, | ||
2035 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
2036 | |||
2146 | drm_encoder_cleanup(encoder); | 2037 | drm_encoder_cleanup(encoder); |
2038 | kfree(intel_encoder); | ||
2147 | } | 2039 | } |
2148 | 2040 | ||
2149 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | 2041 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { |
@@ -2159,49 +2051,29 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | |||
2159 | * outputs, then LVDS outputs. | 2051 | * outputs, then LVDS outputs. |
2160 | */ | 2052 | */ |
2161 | static void | 2053 | static void |
2162 | intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) | 2054 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, |
2055 | struct intel_sdvo_priv *sdvo, u32 reg) | ||
2163 | { | 2056 | { |
2164 | uint16_t mask = 0; | 2057 | struct sdvo_device_mapping *mapping; |
2165 | unsigned int num_bits; | ||
2166 | |||
2167 | /* Make a mask of outputs less than or equal to our own priority in the | ||
2168 | * list. | ||
2169 | */ | ||
2170 | switch (dev_priv->controlled_output) { | ||
2171 | case SDVO_OUTPUT_LVDS1: | ||
2172 | mask |= SDVO_OUTPUT_LVDS1; | ||
2173 | case SDVO_OUTPUT_LVDS0: | ||
2174 | mask |= SDVO_OUTPUT_LVDS0; | ||
2175 | case SDVO_OUTPUT_TMDS1: | ||
2176 | mask |= SDVO_OUTPUT_TMDS1; | ||
2177 | case SDVO_OUTPUT_TMDS0: | ||
2178 | mask |= SDVO_OUTPUT_TMDS0; | ||
2179 | case SDVO_OUTPUT_RGB1: | ||
2180 | mask |= SDVO_OUTPUT_RGB1; | ||
2181 | case SDVO_OUTPUT_RGB0: | ||
2182 | mask |= SDVO_OUTPUT_RGB0; | ||
2183 | break; | ||
2184 | } | ||
2185 | 2058 | ||
2186 | /* Count bits to find what number we are in the priority list. */ | 2059 | if (IS_SDVOB(reg)) |
2187 | mask &= dev_priv->caps.output_flags; | 2060 | mapping = &(dev_priv->sdvo_mappings[0]); |
2188 | num_bits = hweight16(mask); | 2061 | else |
2189 | if (num_bits > 3) { | 2062 | mapping = &(dev_priv->sdvo_mappings[1]); |
2190 | /* if more than 3 outputs, default to DDC bus 3 for now */ | ||
2191 | num_bits = 3; | ||
2192 | } | ||
2193 | 2063 | ||
2194 | /* Corresponds to SDVO_CONTROL_BUS_DDCx */ | 2064 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); |
2195 | dev_priv->ddc_bus = 1 << num_bits; | ||
2196 | } | 2065 | } |
2197 | 2066 | ||
2198 | static bool | 2067 | static bool |
2199 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output) | 2068 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output, int device) |
2200 | { | 2069 | { |
2201 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 2070 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
2202 | uint8_t status; | 2071 | uint8_t status; |
2203 | 2072 | ||
2204 | intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); | 2073 | if (device == 0) |
2074 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS0); | ||
2075 | else | ||
2076 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS1); | ||
2205 | 2077 | ||
2206 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); | 2078 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); |
2207 | status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); | 2079 | status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); |
@@ -2214,15 +2086,13 @@ static struct intel_encoder * | |||
2214 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) | 2086 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) |
2215 | { | 2087 | { |
2216 | struct drm_device *dev = chan->drm_dev; | 2088 | struct drm_device *dev = chan->drm_dev; |
2217 | struct drm_connector *connector; | 2089 | struct drm_encoder *encoder; |
2218 | struct intel_encoder *intel_encoder = NULL; | 2090 | struct intel_encoder *intel_encoder = NULL; |
2219 | 2091 | ||
2220 | list_for_each_entry(connector, | 2092 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
2221 | &dev->mode_config.connector_list, head) { | 2093 | intel_encoder = enc_to_intel_encoder(encoder); |
2222 | if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) { | 2094 | if (intel_encoder->ddc_bus == &chan->adapter) |
2223 | intel_encoder = to_intel_encoder(connector); | ||
2224 | break; | 2095 | break; |
2225 | } | ||
2226 | } | 2096 | } |
2227 | return intel_encoder; | 2097 | return intel_encoder; |
2228 | } | 2098 | } |
@@ -2259,7 +2129,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2259 | struct drm_i915_private *dev_priv = dev->dev_private; | 2129 | struct drm_i915_private *dev_priv = dev->dev_private; |
2260 | struct sdvo_device_mapping *my_mapping, *other_mapping; | 2130 | struct sdvo_device_mapping *my_mapping, *other_mapping; |
2261 | 2131 | ||
2262 | if (sdvo_reg == SDVOB) { | 2132 | if (IS_SDVOB(sdvo_reg)) { |
2263 | my_mapping = &dev_priv->sdvo_mappings[0]; | 2133 | my_mapping = &dev_priv->sdvo_mappings[0]; |
2264 | other_mapping = &dev_priv->sdvo_mappings[1]; | 2134 | other_mapping = &dev_priv->sdvo_mappings[1]; |
2265 | } else { | 2135 | } else { |
@@ -2284,120 +2154,237 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2284 | /* No SDVO device info is found for another DVO port, | 2154 | /* No SDVO device info is found for another DVO port, |
2285 | * so use mapping assumption we had before BIOS parsing. | 2155 | * so use mapping assumption we had before BIOS parsing. |
2286 | */ | 2156 | */ |
2287 | if (sdvo_reg == SDVOB) | 2157 | if (IS_SDVOB(sdvo_reg)) |
2288 | return 0x70; | 2158 | return 0x70; |
2289 | else | 2159 | else |
2290 | return 0x72; | 2160 | return 0x72; |
2291 | } | 2161 | } |
2292 | 2162 | ||
2293 | static int intel_sdvo_bad_tv_callback(const struct dmi_system_id *id) | 2163 | static bool |
2164 | intel_sdvo_connector_alloc (struct intel_connector **ret) | ||
2294 | { | 2165 | { |
2295 | DRM_DEBUG_KMS("Ignoring bad SDVO TV connector for %s\n", id->ident); | 2166 | struct intel_connector *intel_connector; |
2296 | return 1; | 2167 | struct intel_sdvo_connector *sdvo_connector; |
2168 | |||
2169 | *ret = kzalloc(sizeof(*intel_connector) + | ||
2170 | sizeof(*sdvo_connector), GFP_KERNEL); | ||
2171 | if (!*ret) | ||
2172 | return false; | ||
2173 | |||
2174 | intel_connector = *ret; | ||
2175 | sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1); | ||
2176 | intel_connector->dev_priv = sdvo_connector; | ||
2177 | |||
2178 | return true; | ||
2297 | } | 2179 | } |
2298 | 2180 | ||
2299 | static struct dmi_system_id intel_sdvo_bad_tv[] = { | 2181 | static void |
2300 | { | 2182 | intel_sdvo_connector_create (struct drm_encoder *encoder, |
2301 | .callback = intel_sdvo_bad_tv_callback, | 2183 | struct drm_connector *connector) |
2302 | .ident = "IntelG45/ICH10R/DME1737", | 2184 | { |
2303 | .matches = { | 2185 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, |
2304 | DMI_MATCH(DMI_SYS_VENDOR, "IBM CORPORATION"), | 2186 | connector->connector_type); |
2305 | DMI_MATCH(DMI_PRODUCT_NAME, "4800784"), | ||
2306 | }, | ||
2307 | }, | ||
2308 | 2187 | ||
2309 | { } /* terminating entry */ | 2188 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); |
2310 | }; | 2189 | |
2190 | connector->interlace_allowed = 0; | ||
2191 | connector->doublescan_allowed = 0; | ||
2192 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
2193 | |||
2194 | drm_mode_connector_attach_encoder(connector, encoder); | ||
2195 | drm_sysfs_connector_add(connector); | ||
2196 | } | ||
2311 | 2197 | ||
2312 | static bool | 2198 | static bool |
2313 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | 2199 | intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device) |
2314 | { | 2200 | { |
2315 | struct drm_connector *connector = &intel_encoder->base; | ||
2316 | struct drm_encoder *encoder = &intel_encoder->enc; | 2201 | struct drm_encoder *encoder = &intel_encoder->enc; |
2317 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2202 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
2318 | bool ret = true, registered = false; | 2203 | struct drm_connector *connector; |
2204 | struct intel_connector *intel_connector; | ||
2205 | struct intel_sdvo_connector *sdvo_connector; | ||
2206 | |||
2207 | if (!intel_sdvo_connector_alloc(&intel_connector)) | ||
2208 | return false; | ||
2209 | |||
2210 | sdvo_connector = intel_connector->dev_priv; | ||
2211 | |||
2212 | if (device == 0) { | ||
2213 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS0; | ||
2214 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; | ||
2215 | } else if (device == 1) { | ||
2216 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS1; | ||
2217 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; | ||
2218 | } | ||
2219 | |||
2220 | connector = &intel_connector->base; | ||
2221 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | ||
2222 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | ||
2223 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | ||
2224 | |||
2225 | if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode) | ||
2226 | && intel_sdvo_get_digital_encoding_mode(intel_encoder, device) | ||
2227 | && sdvo_priv->is_hdmi) { | ||
2228 | /* enable hdmi encoding mode if supported */ | ||
2229 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); | ||
2230 | intel_sdvo_set_colorimetry(intel_encoder, | ||
2231 | SDVO_COLORIMETRY_RGB256); | ||
2232 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
2233 | } | ||
2234 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2235 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2236 | |||
2237 | intel_sdvo_connector_create(encoder, connector); | ||
2238 | |||
2239 | return true; | ||
2240 | } | ||
2241 | |||
2242 | static bool | ||
2243 | intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type) | ||
2244 | { | ||
2245 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
2246 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2247 | struct drm_connector *connector; | ||
2248 | struct intel_connector *intel_connector; | ||
2249 | struct intel_sdvo_connector *sdvo_connector; | ||
2250 | |||
2251 | if (!intel_sdvo_connector_alloc(&intel_connector)) | ||
2252 | return false; | ||
2253 | |||
2254 | connector = &intel_connector->base; | ||
2255 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
2256 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
2257 | sdvo_connector = intel_connector->dev_priv; | ||
2258 | |||
2259 | sdvo_priv->controlled_output |= type; | ||
2260 | sdvo_connector->output_flag = type; | ||
2261 | |||
2262 | sdvo_priv->is_tv = true; | ||
2263 | intel_encoder->needs_tv_clock = true; | ||
2264 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
2265 | |||
2266 | intel_sdvo_connector_create(encoder, connector); | ||
2267 | |||
2268 | intel_sdvo_tv_create_property(connector, type); | ||
2269 | |||
2270 | intel_sdvo_create_enhance_property(connector); | ||
2271 | |||
2272 | return true; | ||
2273 | } | ||
2274 | |||
2275 | static bool | ||
2276 | intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device) | ||
2277 | { | ||
2278 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
2279 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2280 | struct drm_connector *connector; | ||
2281 | struct intel_connector *intel_connector; | ||
2282 | struct intel_sdvo_connector *sdvo_connector; | ||
2283 | |||
2284 | if (!intel_sdvo_connector_alloc(&intel_connector)) | ||
2285 | return false; | ||
2286 | |||
2287 | connector = &intel_connector->base; | ||
2288 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
2289 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
2290 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
2291 | sdvo_connector = intel_connector->dev_priv; | ||
2292 | |||
2293 | if (device == 0) { | ||
2294 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB0; | ||
2295 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; | ||
2296 | } else if (device == 1) { | ||
2297 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB1; | ||
2298 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | ||
2299 | } | ||
2300 | |||
2301 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2302 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2303 | |||
2304 | intel_sdvo_connector_create(encoder, connector); | ||
2305 | return true; | ||
2306 | } | ||
2307 | |||
2308 | static bool | ||
2309 | intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device) | ||
2310 | { | ||
2311 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
2312 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2313 | struct drm_connector *connector; | ||
2314 | struct intel_connector *intel_connector; | ||
2315 | struct intel_sdvo_connector *sdvo_connector; | ||
2316 | |||
2317 | if (!intel_sdvo_connector_alloc(&intel_connector)) | ||
2318 | return false; | ||
2319 | |||
2320 | connector = &intel_connector->base; | ||
2321 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
2322 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
2323 | sdvo_connector = intel_connector->dev_priv; | ||
2324 | |||
2325 | sdvo_priv->is_lvds = true; | ||
2326 | |||
2327 | if (device == 0) { | ||
2328 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS0; | ||
2329 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; | ||
2330 | } else if (device == 1) { | ||
2331 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS1; | ||
2332 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | ||
2333 | } | ||
2334 | |||
2335 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2336 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2337 | |||
2338 | intel_sdvo_connector_create(encoder, connector); | ||
2339 | intel_sdvo_create_enhance_property(connector); | ||
2340 | return true; | ||
2341 | } | ||
2342 | |||
2343 | static bool | ||
2344 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | ||
2345 | { | ||
2346 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2319 | 2347 | ||
2320 | sdvo_priv->is_tv = false; | 2348 | sdvo_priv->is_tv = false; |
2321 | intel_encoder->needs_tv_clock = false; | 2349 | intel_encoder->needs_tv_clock = false; |
2322 | sdvo_priv->is_lvds = false; | 2350 | sdvo_priv->is_lvds = false; |
2323 | 2351 | ||
2324 | if (device_is_registered(&connector->kdev)) { | 2352 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ |
2325 | drm_sysfs_connector_remove(connector); | ||
2326 | registered = true; | ||
2327 | } | ||
2328 | 2353 | ||
2329 | if (flags & | 2354 | if (flags & SDVO_OUTPUT_TMDS0) |
2330 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | 2355 | if (!intel_sdvo_dvi_init(intel_encoder, 0)) |
2331 | if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) | 2356 | return false; |
2332 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; | 2357 | |
2333 | else | 2358 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) |
2334 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | 2359 | if (!intel_sdvo_dvi_init(intel_encoder, 1)) |
2335 | 2360 | return false; | |
2336 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | 2361 | |
2337 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | 2362 | /* TV has no XXX1 function block */ |
2338 | 2363 | if (flags & SDVO_OUTPUT_SVID0) | |
2339 | if (intel_sdvo_get_supp_encode(intel_encoder, | 2364 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0)) |
2340 | &sdvo_priv->encode) && | 2365 | return false; |
2341 | intel_sdvo_get_digital_encoding_mode(intel_encoder) && | 2366 | |
2342 | sdvo_priv->is_hdmi) { | 2367 | if (flags & SDVO_OUTPUT_CVBS0) |
2343 | /* enable hdmi encoding mode if supported */ | 2368 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0)) |
2344 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); | 2369 | return false; |
2345 | intel_sdvo_set_colorimetry(intel_encoder, | 2370 | |
2346 | SDVO_COLORIMETRY_RGB256); | 2371 | if (flags & SDVO_OUTPUT_RGB0) |
2347 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2372 | if (!intel_sdvo_analog_init(intel_encoder, 0)) |
2348 | intel_encoder->clone_mask = | 2373 | return false; |
2349 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2374 | |
2350 | (1 << INTEL_ANALOG_CLONE_BIT); | 2375 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) |
2351 | } | 2376 | if (!intel_sdvo_analog_init(intel_encoder, 1)) |
2352 | } else if ((flags & SDVO_OUTPUT_SVID0) && | 2377 | return false; |
2353 | !dmi_check_system(intel_sdvo_bad_tv)) { | 2378 | |
2354 | 2379 | if (flags & SDVO_OUTPUT_LVDS0) | |
2355 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | 2380 | if (!intel_sdvo_lvds_init(intel_encoder, 0)) |
2356 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | 2381 | return false; |
2357 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
2358 | sdvo_priv->is_tv = true; | ||
2359 | intel_encoder->needs_tv_clock = true; | ||
2360 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
2361 | } else if (flags & SDVO_OUTPUT_RGB0) { | ||
2362 | |||
2363 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | ||
2364 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
2365 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
2366 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2367 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2368 | } else if (flags & SDVO_OUTPUT_RGB1) { | ||
2369 | |||
2370 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | ||
2371 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
2372 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
2373 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2374 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
2375 | } else if (flags & SDVO_OUTPUT_CVBS0) { | ||
2376 | |||
2377 | sdvo_priv->controlled_output = SDVO_OUTPUT_CVBS0; | ||
2378 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
2379 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
2380 | sdvo_priv->is_tv = true; | ||
2381 | intel_encoder->needs_tv_clock = true; | ||
2382 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
2383 | } else if (flags & SDVO_OUTPUT_LVDS0) { | ||
2384 | |||
2385 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | ||
2386 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
2387 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
2388 | sdvo_priv->is_lvds = true; | ||
2389 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2390 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2391 | } else if (flags & SDVO_OUTPUT_LVDS1) { | ||
2392 | |||
2393 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | ||
2394 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
2395 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
2396 | sdvo_priv->is_lvds = true; | ||
2397 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2398 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
2399 | } else { | ||
2400 | 2382 | ||
2383 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) | ||
2384 | if (!intel_sdvo_lvds_init(intel_encoder, 1)) | ||
2385 | return false; | ||
2386 | |||
2387 | if ((flags & SDVO_OUTPUT_MASK) == 0) { | ||
2401 | unsigned char bytes[2]; | 2388 | unsigned char bytes[2]; |
2402 | 2389 | ||
2403 | sdvo_priv->controlled_output = 0; | 2390 | sdvo_priv->controlled_output = 0; |
@@ -2405,28 +2392,25 @@ intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | |||
2405 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", | 2392 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", |
2406 | SDVO_NAME(sdvo_priv), | 2393 | SDVO_NAME(sdvo_priv), |
2407 | bytes[0], bytes[1]); | 2394 | bytes[0], bytes[1]); |
2408 | ret = false; | 2395 | return false; |
2409 | } | 2396 | } |
2410 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 2397 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
2411 | 2398 | ||
2412 | if (ret && registered) | 2399 | return true; |
2413 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | ||
2414 | |||
2415 | |||
2416 | return ret; | ||
2417 | |||
2418 | } | 2400 | } |
2419 | 2401 | ||
2420 | static void intel_sdvo_tv_create_property(struct drm_connector *connector) | 2402 | static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type) |
2421 | { | 2403 | { |
2422 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 2404 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
2405 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2423 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2406 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
2407 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
2408 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
2424 | struct intel_sdvo_tv_format format; | 2409 | struct intel_sdvo_tv_format format; |
2425 | uint32_t format_map, i; | 2410 | uint32_t format_map, i; |
2426 | uint8_t status; | 2411 | uint8_t status; |
2427 | 2412 | ||
2428 | intel_sdvo_set_target_output(intel_encoder, | 2413 | intel_sdvo_set_target_output(intel_encoder, type); |
2429 | sdvo_priv->controlled_output); | ||
2430 | 2414 | ||
2431 | intel_sdvo_write_cmd(intel_encoder, | 2415 | intel_sdvo_write_cmd(intel_encoder, |
2432 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | 2416 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); |
@@ -2441,35 +2425,37 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector) | |||
2441 | if (format_map == 0) | 2425 | if (format_map == 0) |
2442 | return; | 2426 | return; |
2443 | 2427 | ||
2444 | sdvo_priv->format_supported_num = 0; | 2428 | sdvo_connector->format_supported_num = 0; |
2445 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | 2429 | for (i = 0 ; i < TV_FORMAT_NUM; i++) |
2446 | if (format_map & (1 << i)) { | 2430 | if (format_map & (1 << i)) { |
2447 | sdvo_priv->tv_format_supported | 2431 | sdvo_connector->tv_format_supported |
2448 | [sdvo_priv->format_supported_num++] = | 2432 | [sdvo_connector->format_supported_num++] = |
2449 | tv_format_names[i]; | 2433 | tv_format_names[i]; |
2450 | } | 2434 | } |
2451 | 2435 | ||
2452 | 2436 | ||
2453 | sdvo_priv->tv_format_property = | 2437 | sdvo_connector->tv_format_property = |
2454 | drm_property_create( | 2438 | drm_property_create( |
2455 | connector->dev, DRM_MODE_PROP_ENUM, | 2439 | connector->dev, DRM_MODE_PROP_ENUM, |
2456 | "mode", sdvo_priv->format_supported_num); | 2440 | "mode", sdvo_connector->format_supported_num); |
2457 | 2441 | ||
2458 | for (i = 0; i < sdvo_priv->format_supported_num; i++) | 2442 | for (i = 0; i < sdvo_connector->format_supported_num; i++) |
2459 | drm_property_add_enum( | 2443 | drm_property_add_enum( |
2460 | sdvo_priv->tv_format_property, i, | 2444 | sdvo_connector->tv_format_property, i, |
2461 | i, sdvo_priv->tv_format_supported[i]); | 2445 | i, sdvo_connector->tv_format_supported[i]); |
2462 | 2446 | ||
2463 | sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0]; | 2447 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[0]; |
2464 | drm_connector_attach_property( | 2448 | drm_connector_attach_property( |
2465 | connector, sdvo_priv->tv_format_property, 0); | 2449 | connector, sdvo_connector->tv_format_property, 0); |
2466 | 2450 | ||
2467 | } | 2451 | } |
2468 | 2452 | ||
2469 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | 2453 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) |
2470 | { | 2454 | { |
2471 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 2455 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
2472 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2456 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
2457 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
2458 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
2473 | struct intel_sdvo_enhancements_reply sdvo_data; | 2459 | struct intel_sdvo_enhancements_reply sdvo_data; |
2474 | struct drm_device *dev = connector->dev; | 2460 | struct drm_device *dev = connector->dev; |
2475 | uint8_t status; | 2461 | uint8_t status; |
@@ -2488,7 +2474,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2488 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2474 | DRM_DEBUG_KMS("No enhancement is supported\n"); |
2489 | return; | 2475 | return; |
2490 | } | 2476 | } |
2491 | if (sdvo_priv->is_tv) { | 2477 | if (IS_TV(sdvo_priv)) { |
2492 | /* when horizontal overscan is supported, Add the left/right | 2478 | /* when horizontal overscan is supported, Add the left/right |
2493 | * property | 2479 | * property |
2494 | */ | 2480 | */ |
@@ -2636,8 +2622,6 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2636 | "default %d, current %d\n", | 2622 | "default %d, current %d\n", |
2637 | data_value[0], data_value[1], response); | 2623 | data_value[0], data_value[1], response); |
2638 | } | 2624 | } |
2639 | } | ||
2640 | if (sdvo_priv->is_tv) { | ||
2641 | if (sdvo_data.saturation) { | 2625 | if (sdvo_data.saturation) { |
2642 | intel_sdvo_write_cmd(intel_encoder, | 2626 | intel_sdvo_write_cmd(intel_encoder, |
2643 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); | 2627 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); |
@@ -2733,7 +2717,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2733 | data_value[0], data_value[1], response); | 2717 | data_value[0], data_value[1], response); |
2734 | } | 2718 | } |
2735 | } | 2719 | } |
2736 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 2720 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { |
2737 | if (sdvo_data.brightness) { | 2721 | if (sdvo_data.brightness) { |
2738 | intel_sdvo_write_cmd(intel_encoder, | 2722 | intel_sdvo_write_cmd(intel_encoder, |
2739 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); | 2723 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); |
@@ -2773,12 +2757,11 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2773 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | 2757 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
2774 | { | 2758 | { |
2775 | struct drm_i915_private *dev_priv = dev->dev_private; | 2759 | struct drm_i915_private *dev_priv = dev->dev_private; |
2776 | struct drm_connector *connector; | ||
2777 | struct intel_encoder *intel_encoder; | 2760 | struct intel_encoder *intel_encoder; |
2778 | struct intel_sdvo_priv *sdvo_priv; | 2761 | struct intel_sdvo_priv *sdvo_priv; |
2779 | |||
2780 | u8 ch[0x40]; | 2762 | u8 ch[0x40]; |
2781 | int i; | 2763 | int i; |
2764 | u32 i2c_reg, ddc_reg, analog_ddc_reg; | ||
2782 | 2765 | ||
2783 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2766 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
2784 | if (!intel_encoder) { | 2767 | if (!intel_encoder) { |
@@ -2791,11 +2774,21 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2791 | intel_encoder->dev_priv = sdvo_priv; | 2774 | intel_encoder->dev_priv = sdvo_priv; |
2792 | intel_encoder->type = INTEL_OUTPUT_SDVO; | 2775 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
2793 | 2776 | ||
2777 | if (HAS_PCH_SPLIT(dev)) { | ||
2778 | i2c_reg = PCH_GPIOE; | ||
2779 | ddc_reg = PCH_GPIOE; | ||
2780 | analog_ddc_reg = PCH_GPIOA; | ||
2781 | } else { | ||
2782 | i2c_reg = GPIOE; | ||
2783 | ddc_reg = GPIOE; | ||
2784 | analog_ddc_reg = GPIOA; | ||
2785 | } | ||
2786 | |||
2794 | /* setup the DDC bus. */ | 2787 | /* setup the DDC bus. */ |
2795 | if (sdvo_reg == SDVOB) | 2788 | if (IS_SDVOB(sdvo_reg)) |
2796 | intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 2789 | intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOB"); |
2797 | else | 2790 | else |
2798 | intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 2791 | intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOC"); |
2799 | 2792 | ||
2800 | if (!intel_encoder->i2c_bus) | 2793 | if (!intel_encoder->i2c_bus) |
2801 | goto err_inteloutput; | 2794 | goto err_inteloutput; |
@@ -2809,20 +2802,20 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2809 | for (i = 0; i < 0x40; i++) { | 2802 | for (i = 0; i < 0x40; i++) { |
2810 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { | 2803 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { |
2811 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2804 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
2812 | sdvo_reg == SDVOB ? 'B' : 'C'); | 2805 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2813 | goto err_i2c; | 2806 | goto err_i2c; |
2814 | } | 2807 | } |
2815 | } | 2808 | } |
2816 | 2809 | ||
2817 | /* setup the DDC bus. */ | 2810 | /* setup the DDC bus. */ |
2818 | if (sdvo_reg == SDVOB) { | 2811 | if (IS_SDVOB(sdvo_reg)) { |
2819 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 2812 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); |
2820 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2813 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2821 | "SDVOB/VGA DDC BUS"); | 2814 | "SDVOB/VGA DDC BUS"); |
2822 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2815 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
2823 | } else { | 2816 | } else { |
2824 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 2817 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); |
2825 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2818 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2826 | "SDVOC/VGA DDC BUS"); | 2819 | "SDVOC/VGA DDC BUS"); |
2827 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2820 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2828 | } | 2821 | } |
@@ -2833,41 +2826,21 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2833 | /* Wrap with our custom algo which switches to DDC mode */ | 2826 | /* Wrap with our custom algo which switches to DDC mode */ |
2834 | intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; | 2827 | intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
2835 | 2828 | ||
2829 | /* encoder type will be decided later */ | ||
2830 | drm_encoder_init(dev, &intel_encoder->enc, &intel_sdvo_enc_funcs, 0); | ||
2831 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | ||
2832 | |||
2836 | /* In default case sdvo lvds is false */ | 2833 | /* In default case sdvo lvds is false */ |
2837 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); | 2834 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); |
2838 | 2835 | ||
2839 | if (intel_sdvo_output_setup(intel_encoder, | 2836 | if (intel_sdvo_output_setup(intel_encoder, |
2840 | sdvo_priv->caps.output_flags) != true) { | 2837 | sdvo_priv->caps.output_flags) != true) { |
2841 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2838 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2842 | sdvo_reg == SDVOB ? 'B' : 'C'); | 2839 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2843 | goto err_i2c; | 2840 | goto err_i2c; |
2844 | } | 2841 | } |
2845 | 2842 | ||
2846 | 2843 | intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg); | |
2847 | connector = &intel_encoder->base; | ||
2848 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, | ||
2849 | connector->connector_type); | ||
2850 | |||
2851 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); | ||
2852 | connector->interlace_allowed = 0; | ||
2853 | connector->doublescan_allowed = 0; | ||
2854 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | ||
2855 | |||
2856 | drm_encoder_init(dev, &intel_encoder->enc, | ||
2857 | &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type); | ||
2858 | |||
2859 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | ||
2860 | |||
2861 | drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); | ||
2862 | if (sdvo_priv->is_tv) | ||
2863 | intel_sdvo_tv_create_property(connector); | ||
2864 | |||
2865 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) | ||
2866 | intel_sdvo_create_enhance_property(connector); | ||
2867 | |||
2868 | drm_sysfs_connector_add(connector); | ||
2869 | |||
2870 | intel_sdvo_select_ddc_bus(sdvo_priv); | ||
2871 | 2844 | ||
2872 | /* Set the input timing to the screen. Assume always input 0. */ | 2845 | /* Set the input timing to the screen. Assume always input 0. */ |
2873 | intel_sdvo_set_target_input(intel_encoder, true, false); | 2846 | intel_sdvo_set_target_input(intel_encoder, true, false); |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d7d39b2327df..6d553c29d106 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -916,143 +916,6 @@ intel_tv_dpms(struct drm_encoder *encoder, int mode) | |||
916 | } | 916 | } |
917 | } | 917 | } |
918 | 918 | ||
919 | static void | ||
920 | intel_tv_save(struct drm_connector *connector) | ||
921 | { | ||
922 | struct drm_device *dev = connector->dev; | ||
923 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
924 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
925 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | ||
926 | int i; | ||
927 | |||
928 | tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1); | ||
929 | tv_priv->save_TV_H_CTL_2 = I915_READ(TV_H_CTL_2); | ||
930 | tv_priv->save_TV_H_CTL_3 = I915_READ(TV_H_CTL_3); | ||
931 | tv_priv->save_TV_V_CTL_1 = I915_READ(TV_V_CTL_1); | ||
932 | tv_priv->save_TV_V_CTL_2 = I915_READ(TV_V_CTL_2); | ||
933 | tv_priv->save_TV_V_CTL_3 = I915_READ(TV_V_CTL_3); | ||
934 | tv_priv->save_TV_V_CTL_4 = I915_READ(TV_V_CTL_4); | ||
935 | tv_priv->save_TV_V_CTL_5 = I915_READ(TV_V_CTL_5); | ||
936 | tv_priv->save_TV_V_CTL_6 = I915_READ(TV_V_CTL_6); | ||
937 | tv_priv->save_TV_V_CTL_7 = I915_READ(TV_V_CTL_7); | ||
938 | tv_priv->save_TV_SC_CTL_1 = I915_READ(TV_SC_CTL_1); | ||
939 | tv_priv->save_TV_SC_CTL_2 = I915_READ(TV_SC_CTL_2); | ||
940 | tv_priv->save_TV_SC_CTL_3 = I915_READ(TV_SC_CTL_3); | ||
941 | |||
942 | tv_priv->save_TV_CSC_Y = I915_READ(TV_CSC_Y); | ||
943 | tv_priv->save_TV_CSC_Y2 = I915_READ(TV_CSC_Y2); | ||
944 | tv_priv->save_TV_CSC_U = I915_READ(TV_CSC_U); | ||
945 | tv_priv->save_TV_CSC_U2 = I915_READ(TV_CSC_U2); | ||
946 | tv_priv->save_TV_CSC_V = I915_READ(TV_CSC_V); | ||
947 | tv_priv->save_TV_CSC_V2 = I915_READ(TV_CSC_V2); | ||
948 | tv_priv->save_TV_CLR_KNOBS = I915_READ(TV_CLR_KNOBS); | ||
949 | tv_priv->save_TV_CLR_LEVEL = I915_READ(TV_CLR_LEVEL); | ||
950 | tv_priv->save_TV_WIN_POS = I915_READ(TV_WIN_POS); | ||
951 | tv_priv->save_TV_WIN_SIZE = I915_READ(TV_WIN_SIZE); | ||
952 | tv_priv->save_TV_FILTER_CTL_1 = I915_READ(TV_FILTER_CTL_1); | ||
953 | tv_priv->save_TV_FILTER_CTL_2 = I915_READ(TV_FILTER_CTL_2); | ||
954 | tv_priv->save_TV_FILTER_CTL_3 = I915_READ(TV_FILTER_CTL_3); | ||
955 | |||
956 | for (i = 0; i < 60; i++) | ||
957 | tv_priv->save_TV_H_LUMA[i] = I915_READ(TV_H_LUMA_0 + (i <<2)); | ||
958 | for (i = 0; i < 60; i++) | ||
959 | tv_priv->save_TV_H_CHROMA[i] = I915_READ(TV_H_CHROMA_0 + (i <<2)); | ||
960 | for (i = 0; i < 43; i++) | ||
961 | tv_priv->save_TV_V_LUMA[i] = I915_READ(TV_V_LUMA_0 + (i <<2)); | ||
962 | for (i = 0; i < 43; i++) | ||
963 | tv_priv->save_TV_V_CHROMA[i] = I915_READ(TV_V_CHROMA_0 + (i <<2)); | ||
964 | |||
965 | tv_priv->save_TV_DAC = I915_READ(TV_DAC); | ||
966 | tv_priv->save_TV_CTL = I915_READ(TV_CTL); | ||
967 | } | ||
968 | |||
969 | static void | ||
970 | intel_tv_restore(struct drm_connector *connector) | ||
971 | { | ||
972 | struct drm_device *dev = connector->dev; | ||
973 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
974 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
975 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | ||
976 | struct drm_crtc *crtc = connector->encoder->crtc; | ||
977 | struct intel_crtc *intel_crtc; | ||
978 | int i; | ||
979 | |||
980 | /* FIXME: No CRTC? */ | ||
981 | if (!crtc) | ||
982 | return; | ||
983 | |||
984 | intel_crtc = to_intel_crtc(crtc); | ||
985 | I915_WRITE(TV_H_CTL_1, tv_priv->save_TV_H_CTL_1); | ||
986 | I915_WRITE(TV_H_CTL_2, tv_priv->save_TV_H_CTL_2); | ||
987 | I915_WRITE(TV_H_CTL_3, tv_priv->save_TV_H_CTL_3); | ||
988 | I915_WRITE(TV_V_CTL_1, tv_priv->save_TV_V_CTL_1); | ||
989 | I915_WRITE(TV_V_CTL_2, tv_priv->save_TV_V_CTL_2); | ||
990 | I915_WRITE(TV_V_CTL_3, tv_priv->save_TV_V_CTL_3); | ||
991 | I915_WRITE(TV_V_CTL_4, tv_priv->save_TV_V_CTL_4); | ||
992 | I915_WRITE(TV_V_CTL_5, tv_priv->save_TV_V_CTL_5); | ||
993 | I915_WRITE(TV_V_CTL_6, tv_priv->save_TV_V_CTL_6); | ||
994 | I915_WRITE(TV_V_CTL_7, tv_priv->save_TV_V_CTL_7); | ||
995 | I915_WRITE(TV_SC_CTL_1, tv_priv->save_TV_SC_CTL_1); | ||
996 | I915_WRITE(TV_SC_CTL_2, tv_priv->save_TV_SC_CTL_2); | ||
997 | I915_WRITE(TV_SC_CTL_3, tv_priv->save_TV_SC_CTL_3); | ||
998 | |||
999 | I915_WRITE(TV_CSC_Y, tv_priv->save_TV_CSC_Y); | ||
1000 | I915_WRITE(TV_CSC_Y2, tv_priv->save_TV_CSC_Y2); | ||
1001 | I915_WRITE(TV_CSC_U, tv_priv->save_TV_CSC_U); | ||
1002 | I915_WRITE(TV_CSC_U2, tv_priv->save_TV_CSC_U2); | ||
1003 | I915_WRITE(TV_CSC_V, tv_priv->save_TV_CSC_V); | ||
1004 | I915_WRITE(TV_CSC_V2, tv_priv->save_TV_CSC_V2); | ||
1005 | I915_WRITE(TV_CLR_KNOBS, tv_priv->save_TV_CLR_KNOBS); | ||
1006 | I915_WRITE(TV_CLR_LEVEL, tv_priv->save_TV_CLR_LEVEL); | ||
1007 | |||
1008 | { | ||
1009 | int pipeconf_reg = (intel_crtc->pipe == 0) ? | ||
1010 | PIPEACONF : PIPEBCONF; | ||
1011 | int dspcntr_reg = (intel_crtc->plane == 0) ? | ||
1012 | DSPACNTR : DSPBCNTR; | ||
1013 | int pipeconf = I915_READ(pipeconf_reg); | ||
1014 | int dspcntr = I915_READ(dspcntr_reg); | ||
1015 | int dspbase_reg = (intel_crtc->plane == 0) ? | ||
1016 | DSPAADDR : DSPBADDR; | ||
1017 | /* Pipe must be off here */ | ||
1018 | I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE); | ||
1019 | /* Flush the plane changes */ | ||
1020 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | ||
1021 | |||
1022 | if (!IS_I9XX(dev)) { | ||
1023 | /* Wait for vblank for the disable to take effect */ | ||
1024 | intel_wait_for_vblank(dev); | ||
1025 | } | ||
1026 | |||
1027 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); | ||
1028 | /* Wait for vblank for the disable to take effect. */ | ||
1029 | intel_wait_for_vblank(dev); | ||
1030 | |||
1031 | /* Filter ctl must be set before TV_WIN_SIZE */ | ||
1032 | I915_WRITE(TV_FILTER_CTL_1, tv_priv->save_TV_FILTER_CTL_1); | ||
1033 | I915_WRITE(TV_FILTER_CTL_2, tv_priv->save_TV_FILTER_CTL_2); | ||
1034 | I915_WRITE(TV_FILTER_CTL_3, tv_priv->save_TV_FILTER_CTL_3); | ||
1035 | I915_WRITE(TV_WIN_POS, tv_priv->save_TV_WIN_POS); | ||
1036 | I915_WRITE(TV_WIN_SIZE, tv_priv->save_TV_WIN_SIZE); | ||
1037 | I915_WRITE(pipeconf_reg, pipeconf); | ||
1038 | I915_WRITE(dspcntr_reg, dspcntr); | ||
1039 | /* Flush the plane changes */ | ||
1040 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | ||
1041 | } | ||
1042 | |||
1043 | for (i = 0; i < 60; i++) | ||
1044 | I915_WRITE(TV_H_LUMA_0 + (i <<2), tv_priv->save_TV_H_LUMA[i]); | ||
1045 | for (i = 0; i < 60; i++) | ||
1046 | I915_WRITE(TV_H_CHROMA_0 + (i <<2), tv_priv->save_TV_H_CHROMA[i]); | ||
1047 | for (i = 0; i < 43; i++) | ||
1048 | I915_WRITE(TV_V_LUMA_0 + (i <<2), tv_priv->save_TV_V_LUMA[i]); | ||
1049 | for (i = 0; i < 43; i++) | ||
1050 | I915_WRITE(TV_V_CHROMA_0 + (i <<2), tv_priv->save_TV_V_CHROMA[i]); | ||
1051 | |||
1052 | I915_WRITE(TV_DAC, tv_priv->save_TV_DAC); | ||
1053 | I915_WRITE(TV_CTL, tv_priv->save_TV_CTL); | ||
1054 | } | ||
1055 | |||
1056 | static const struct tv_mode * | 919 | static const struct tv_mode * |
1057 | intel_tv_mode_lookup (char *tv_format) | 920 | intel_tv_mode_lookup (char *tv_format) |
1058 | { | 921 | { |
@@ -1078,7 +941,8 @@ intel_tv_mode_find (struct intel_encoder *intel_encoder) | |||
1078 | static enum drm_mode_status | 941 | static enum drm_mode_status |
1079 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 942 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) |
1080 | { | 943 | { |
1081 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 944 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
945 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1082 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 946 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1083 | 947 | ||
1084 | /* Ensure TV refresh is close to desired refresh */ | 948 | /* Ensure TV refresh is close to desired refresh */ |
@@ -1441,7 +1305,8 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
1441 | */ | 1305 | */ |
1442 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1306 | static void intel_tv_find_better_format(struct drm_connector *connector) |
1443 | { | 1307 | { |
1444 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1308 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1309 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1445 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1310 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
1446 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1311 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1447 | int i; | 1312 | int i; |
@@ -1475,9 +1340,9 @@ intel_tv_detect(struct drm_connector *connector) | |||
1475 | { | 1340 | { |
1476 | struct drm_crtc *crtc; | 1341 | struct drm_crtc *crtc; |
1477 | struct drm_display_mode mode; | 1342 | struct drm_display_mode mode; |
1478 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1343 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1344 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1479 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1345 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
1480 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
1481 | int dpms_mode; | 1346 | int dpms_mode; |
1482 | int type = tv_priv->type; | 1347 | int type = tv_priv->type; |
1483 | 1348 | ||
@@ -1487,10 +1352,12 @@ intel_tv_detect(struct drm_connector *connector) | |||
1487 | if (encoder->crtc && encoder->crtc->enabled) { | 1352 | if (encoder->crtc && encoder->crtc->enabled) { |
1488 | type = intel_tv_detect_type(encoder->crtc, intel_encoder); | 1353 | type = intel_tv_detect_type(encoder->crtc, intel_encoder); |
1489 | } else { | 1354 | } else { |
1490 | crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode); | 1355 | crtc = intel_get_load_detect_pipe(intel_encoder, connector, |
1356 | &mode, &dpms_mode); | ||
1491 | if (crtc) { | 1357 | if (crtc) { |
1492 | type = intel_tv_detect_type(crtc, intel_encoder); | 1358 | type = intel_tv_detect_type(crtc, intel_encoder); |
1493 | intel_release_load_detect_pipe(intel_encoder, dpms_mode); | 1359 | intel_release_load_detect_pipe(intel_encoder, connector, |
1360 | dpms_mode); | ||
1494 | } else | 1361 | } else |
1495 | type = -1; | 1362 | type = -1; |
1496 | } | 1363 | } |
@@ -1525,7 +1392,8 @@ static void | |||
1525 | intel_tv_chose_preferred_modes(struct drm_connector *connector, | 1392 | intel_tv_chose_preferred_modes(struct drm_connector *connector, |
1526 | struct drm_display_mode *mode_ptr) | 1393 | struct drm_display_mode *mode_ptr) |
1527 | { | 1394 | { |
1528 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1395 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1396 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1529 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1397 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1530 | 1398 | ||
1531 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1399 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
@@ -1550,7 +1418,8 @@ static int | |||
1550 | intel_tv_get_modes(struct drm_connector *connector) | 1418 | intel_tv_get_modes(struct drm_connector *connector) |
1551 | { | 1419 | { |
1552 | struct drm_display_mode *mode_ptr; | 1420 | struct drm_display_mode *mode_ptr; |
1553 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1421 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1422 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1554 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1423 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1555 | int j, count = 0; | 1424 | int j, count = 0; |
1556 | u64 tmp; | 1425 | u64 tmp; |
@@ -1604,11 +1473,9 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
1604 | static void | 1473 | static void |
1605 | intel_tv_destroy (struct drm_connector *connector) | 1474 | intel_tv_destroy (struct drm_connector *connector) |
1606 | { | 1475 | { |
1607 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
1608 | |||
1609 | drm_sysfs_connector_remove(connector); | 1476 | drm_sysfs_connector_remove(connector); |
1610 | drm_connector_cleanup(connector); | 1477 | drm_connector_cleanup(connector); |
1611 | kfree(intel_encoder); | 1478 | kfree(connector); |
1612 | } | 1479 | } |
1613 | 1480 | ||
1614 | 1481 | ||
@@ -1617,9 +1484,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1617 | uint64_t val) | 1484 | uint64_t val) |
1618 | { | 1485 | { |
1619 | struct drm_device *dev = connector->dev; | 1486 | struct drm_device *dev = connector->dev; |
1620 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1487 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1488 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1621 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1489 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
1622 | struct drm_encoder *encoder = &intel_encoder->enc; | ||
1623 | struct drm_crtc *crtc = encoder->crtc; | 1490 | struct drm_crtc *crtc = encoder->crtc; |
1624 | int ret = 0; | 1491 | int ret = 0; |
1625 | bool changed = false; | 1492 | bool changed = false; |
@@ -1676,8 +1543,6 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { | |||
1676 | 1543 | ||
1677 | static const struct drm_connector_funcs intel_tv_connector_funcs = { | 1544 | static const struct drm_connector_funcs intel_tv_connector_funcs = { |
1678 | .dpms = drm_helper_connector_dpms, | 1545 | .dpms = drm_helper_connector_dpms, |
1679 | .save = intel_tv_save, | ||
1680 | .restore = intel_tv_restore, | ||
1681 | .detect = intel_tv_detect, | 1546 | .detect = intel_tv_detect, |
1682 | .destroy = intel_tv_destroy, | 1547 | .destroy = intel_tv_destroy, |
1683 | .set_property = intel_tv_set_property, | 1548 | .set_property = intel_tv_set_property, |
@@ -1687,12 +1552,15 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = { | |||
1687 | static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { | 1552 | static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { |
1688 | .mode_valid = intel_tv_mode_valid, | 1553 | .mode_valid = intel_tv_mode_valid, |
1689 | .get_modes = intel_tv_get_modes, | 1554 | .get_modes = intel_tv_get_modes, |
1690 | .best_encoder = intel_best_encoder, | 1555 | .best_encoder = intel_attached_encoder, |
1691 | }; | 1556 | }; |
1692 | 1557 | ||
1693 | static void intel_tv_enc_destroy(struct drm_encoder *encoder) | 1558 | static void intel_tv_enc_destroy(struct drm_encoder *encoder) |
1694 | { | 1559 | { |
1560 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1561 | |||
1695 | drm_encoder_cleanup(encoder); | 1562 | drm_encoder_cleanup(encoder); |
1563 | kfree(intel_encoder); | ||
1696 | } | 1564 | } |
1697 | 1565 | ||
1698 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { | 1566 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { |
@@ -1741,6 +1609,7 @@ intel_tv_init(struct drm_device *dev) | |||
1741 | struct drm_i915_private *dev_priv = dev->dev_private; | 1609 | struct drm_i915_private *dev_priv = dev->dev_private; |
1742 | struct drm_connector *connector; | 1610 | struct drm_connector *connector; |
1743 | struct intel_encoder *intel_encoder; | 1611 | struct intel_encoder *intel_encoder; |
1612 | struct intel_connector *intel_connector; | ||
1744 | struct intel_tv_priv *tv_priv; | 1613 | struct intel_tv_priv *tv_priv; |
1745 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1614 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
1746 | char **tv_format_names; | 1615 | char **tv_format_names; |
@@ -1786,7 +1655,13 @@ intel_tv_init(struct drm_device *dev) | |||
1786 | return; | 1655 | return; |
1787 | } | 1656 | } |
1788 | 1657 | ||
1789 | connector = &intel_encoder->base; | 1658 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1659 | if (!intel_connector) { | ||
1660 | kfree(intel_encoder); | ||
1661 | return; | ||
1662 | } | ||
1663 | |||
1664 | connector = &intel_connector->base; | ||
1790 | 1665 | ||
1791 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1666 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
1792 | DRM_MODE_CONNECTOR_SVIDEO); | 1667 | DRM_MODE_CONNECTOR_SVIDEO); |
@@ -1794,7 +1669,7 @@ intel_tv_init(struct drm_device *dev) | |||
1794 | drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs, | 1669 | drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs, |
1795 | DRM_MODE_ENCODER_TVDAC); | 1670 | DRM_MODE_ENCODER_TVDAC); |
1796 | 1671 | ||
1797 | drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); | 1672 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); |
1798 | tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); | 1673 | tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); |
1799 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1674 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
1800 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1675 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |