aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_opregion.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_opregion.c')
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c146
1 files changed, 131 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 2d5193556d3f..8fcc75c1aa28 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -118,6 +118,10 @@ struct opregion_asle {
118#define ASLE_BACKLIGHT_FAIL (2<<12) 118#define ASLE_BACKLIGHT_FAIL (2<<12)
119#define ASLE_PFIT_FAIL (2<<14) 119#define ASLE_PFIT_FAIL (2<<14)
120#define ASLE_PWM_FREQ_FAIL (2<<16) 120#define ASLE_PWM_FREQ_FAIL (2<<16)
121#define ASLE_ALS_ILLUM_FAILED (1<<10)
122#define ASLE_BACKLIGHT_FAILED (1<<12)
123#define ASLE_PFIT_FAILED (1<<14)
124#define ASLE_PWM_FREQ_FAILED (1<<16)
121 125
122/* ASLE backlight brightness to set */ 126/* ASLE backlight brightness to set */
123#define ASLE_BCLP_VALID (1<<31) 127#define ASLE_BCLP_VALID (1<<31)
@@ -163,7 +167,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
163 if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE)) 167 if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE))
164 pci_write_config_dword(dev->pdev, PCI_LBPC, bclp); 168 pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
165 else { 169 else {
166 if (IS_IGD(dev)) { 170 if (IS_PINEVIEW(dev)) {
167 blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); 171 blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
168 max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> 172 max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
169 BACKLIGHT_MODULATION_FREQ_SHIFT; 173 BACKLIGHT_MODULATION_FREQ_SHIFT;
@@ -224,7 +228,7 @@ void opregion_asle_intr(struct drm_device *dev)
224 asle_req = asle->aslc & ASLE_REQ_MSK; 228 asle_req = asle->aslc & ASLE_REQ_MSK;
225 229
226 if (!asle_req) { 230 if (!asle_req) {
227 DRM_DEBUG("non asle set request??\n"); 231 DRM_DEBUG_DRIVER("non asle set request??\n");
228 return; 232 return;
229 } 233 }
230 234
@@ -243,6 +247,73 @@ void opregion_asle_intr(struct drm_device *dev)
243 asle->aslc = asle_stat; 247 asle->aslc = asle_stat;
244} 248}
245 249
250static u32 asle_set_backlight_ironlake(struct drm_device *dev, u32 bclp)
251{
252 struct drm_i915_private *dev_priv = dev->dev_private;
253 struct opregion_asle *asle = dev_priv->opregion.asle;
254 u32 cpu_pwm_ctl, pch_pwm_ctl2;
255 u32 max_backlight, level;
256
257 if (!(bclp & ASLE_BCLP_VALID))
258 return ASLE_BACKLIGHT_FAILED;
259
260 bclp &= ASLE_BCLP_MSK;
261 if (bclp < 0 || bclp > 255)
262 return ASLE_BACKLIGHT_FAILED;
263
264 cpu_pwm_ctl = I915_READ(BLC_PWM_CPU_CTL);
265 pch_pwm_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
266 /* get the max PWM frequency */
267 max_backlight = (pch_pwm_ctl2 >> 16) & BACKLIGHT_DUTY_CYCLE_MASK;
268 /* calculate the expected PMW frequency */
269 level = (bclp * max_backlight) / 255;
270 /* reserve the high 16 bits */
271 cpu_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK);
272 /* write the updated PWM frequency */
273 I915_WRITE(BLC_PWM_CPU_CTL, cpu_pwm_ctl | level);
274
275 asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
276
277 return 0;
278}
279
280void ironlake_opregion_gse_intr(struct drm_device *dev)
281{
282 struct drm_i915_private *dev_priv = dev->dev_private;
283 struct opregion_asle *asle = dev_priv->opregion.asle;
284 u32 asle_stat = 0;
285 u32 asle_req;
286
287 if (!asle)
288 return;
289
290 asle_req = asle->aslc & ASLE_REQ_MSK;
291
292 if (!asle_req) {
293 DRM_DEBUG_DRIVER("non asle set request??\n");
294 return;
295 }
296
297 if (asle_req & ASLE_SET_ALS_ILLUM) {
298 DRM_DEBUG_DRIVER("Illum is not supported\n");
299 asle_stat |= ASLE_ALS_ILLUM_FAILED;
300 }
301
302 if (asle_req & ASLE_SET_BACKLIGHT)
303 asle_stat |= asle_set_backlight_ironlake(dev, asle->bclp);
304
305 if (asle_req & ASLE_SET_PFIT) {
306 DRM_DEBUG_DRIVER("Pfit is not supported\n");
307 asle_stat |= ASLE_PFIT_FAILED;
308 }
309
310 if (asle_req & ASLE_SET_PWM_FREQ) {
311 DRM_DEBUG_DRIVER("PWM freq is not supported\n");
312 asle_stat |= ASLE_PWM_FREQ_FAILED;
313 }
314
315 asle->aslc = asle_stat;
316}
246#define ASLE_ALS_EN (1<<0) 317#define ASLE_ALS_EN (1<<0)
247#define ASLE_BLC_EN (1<<1) 318#define ASLE_BLC_EN (1<<1)
248#define ASLE_PFIT_EN (1<<2) 319#define ASLE_PFIT_EN (1<<2)
@@ -258,8 +329,7 @@ void opregion_enable_asle(struct drm_device *dev)
258 unsigned long irqflags; 329 unsigned long irqflags;
259 330
260 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 331 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
261 i915_enable_pipestat(dev_priv, 1, 332 intel_enable_asle(dev);
262 I915_LEGACY_BLC_EVENT_ENABLE);
263 spin_unlock_irqrestore(&dev_priv->user_irq_lock, 333 spin_unlock_irqrestore(&dev_priv->user_irq_lock,
264 irqflags); 334 irqflags);
265 } 335 }
@@ -312,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev)
312 struct drm_i915_private *dev_priv = dev->dev_private; 382 struct drm_i915_private *dev_priv = dev->dev_private;
313 struct intel_opregion *opregion = &dev_priv->opregion; 383 struct intel_opregion *opregion = &dev_priv->opregion;
314 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;
315 int i = 0; 389 int i = 0;
316 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
428end:
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
434blind_set:
435 i = 0;
317 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 436 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
318 int output_type = ACPI_OTHER_OUTPUT; 437 int output_type = ACPI_OTHER_OUTPUT;
319 if (i >= 8) { 438 if (i >= 8) {
@@ -346,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev)
346 opregion->acpi->didl[i] |= (1<<31) | output_type | i; 465 opregion->acpi->didl[i] |= (1<<31) | output_type | i;
347 i++; 466 i++;
348 } 467 }
349 468 goto end;
350 /* If fewer than 8 outputs, the list must be null terminated */
351 if (i < 8)
352 opregion->acpi->didl[i] = 0;
353} 469}
354 470
355int intel_opregion_init(struct drm_device *dev, int resume) 471int intel_opregion_init(struct drm_device *dev, int resume)
@@ -361,9 +477,9 @@ int intel_opregion_init(struct drm_device *dev, int resume)
361 int err = 0; 477 int err = 0;
362 478
363 pci_read_config_dword(dev->pdev, PCI_ASLS, &asls); 479 pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
364 DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls); 480 DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls);
365 if (asls == 0) { 481 if (asls == 0) {
366 DRM_DEBUG("ACPI OpRegion not supported!\n"); 482 DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n");
367 return -ENOTSUPP; 483 return -ENOTSUPP;
368 } 484 }
369 485
@@ -373,30 +489,30 @@ int intel_opregion_init(struct drm_device *dev, int resume)
373 489
374 opregion->header = base; 490 opregion->header = base;
375 if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) { 491 if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
376 DRM_DEBUG("opregion signature mismatch\n"); 492 DRM_DEBUG_DRIVER("opregion signature mismatch\n");
377 err = -EINVAL; 493 err = -EINVAL;
378 goto err_out; 494 goto err_out;
379 } 495 }
380 496
381 mboxes = opregion->header->mboxes; 497 mboxes = opregion->header->mboxes;
382 if (mboxes & MBOX_ACPI) { 498 if (mboxes & MBOX_ACPI) {
383 DRM_DEBUG("Public ACPI methods supported\n"); 499 DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
384 opregion->acpi = base + OPREGION_ACPI_OFFSET; 500 opregion->acpi = base + OPREGION_ACPI_OFFSET;
385 if (drm_core_check_feature(dev, DRIVER_MODESET)) 501 if (drm_core_check_feature(dev, DRIVER_MODESET))
386 intel_didl_outputs(dev); 502 intel_didl_outputs(dev);
387 } else { 503 } else {
388 DRM_DEBUG("Public ACPI methods not supported\n"); 504 DRM_DEBUG_DRIVER("Public ACPI methods not supported\n");
389 err = -ENOTSUPP; 505 err = -ENOTSUPP;
390 goto err_out; 506 goto err_out;
391 } 507 }
392 opregion->enabled = 1; 508 opregion->enabled = 1;
393 509
394 if (mboxes & MBOX_SWSCI) { 510 if (mboxes & MBOX_SWSCI) {
395 DRM_DEBUG("SWSCI supported\n"); 511 DRM_DEBUG_DRIVER("SWSCI supported\n");
396 opregion->swsci = base + OPREGION_SWSCI_OFFSET; 512 opregion->swsci = base + OPREGION_SWSCI_OFFSET;
397 } 513 }
398 if (mboxes & MBOX_ASLE) { 514 if (mboxes & MBOX_ASLE) {
399 DRM_DEBUG("ASLE supported\n"); 515 DRM_DEBUG_DRIVER("ASLE supported\n");
400 opregion->asle = base + OPREGION_ASLE_OFFSET; 516 opregion->asle = base + OPREGION_ASLE_OFFSET;
401 opregion_enable_asle(dev); 517 opregion_enable_asle(dev);
402 } 518 }