1 /* 2 * Copyright © 2006-2010 Intel Corporation 3 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Eric Anholt <eric@anholt.net> 26 * Dave Airlie <airlied@linux.ie> 27 * Jesse Barnes <jesse.barnes@intel.com> 28 * Chris Wilson <chris@chris-wilson.co.uk> 29 */ 30 31 #include <linux/kernel.h> 32 #include <linux/moduleparam.h> 33 #include "intel_drv.h" 34 35 void 36 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, 37 struct drm_display_mode *adjusted_mode) 38 { 39 drm_mode_copy(adjusted_mode, fixed_mode); 40 41 drm_mode_set_crtcinfo(adjusted_mode, 0); 42 } 43 44 /** 45 * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID 46 * @dev: drm device 47 * @fixed_mode : panel native mode 48 * @connector: LVDS/eDP connector 49 * 50 * Return downclock_avail 51 * Find the reduced downclock for LVDS/eDP in EDID. 52 */ 53 struct drm_display_mode * 54 intel_find_panel_downclock(struct drm_device *dev, 55 struct drm_display_mode *fixed_mode, 56 struct drm_connector *connector) 57 { 58 struct drm_display_mode *scan, *tmp_mode; 59 int temp_downclock; 60 61 temp_downclock = fixed_mode->clock; 62 tmp_mode = NULL; 63 64 list_for_each_entry(scan, &connector->probed_modes, head) { 65 /* 66 * If one mode has the same resolution with the fixed_panel 67 * mode while they have the different refresh rate, it means 68 * that the reduced downclock is found. In such 69 * case we can set the different FPx0/1 to dynamically select 70 * between low and high frequency. 71 */ 72 if (scan->hdisplay == fixed_mode->hdisplay && 73 scan->hsync_start == fixed_mode->hsync_start && 74 scan->hsync_end == fixed_mode->hsync_end && 75 scan->htotal == fixed_mode->htotal && 76 scan->vdisplay == fixed_mode->vdisplay && 77 scan->vsync_start == fixed_mode->vsync_start && 78 scan->vsync_end == fixed_mode->vsync_end && 79 scan->vtotal == fixed_mode->vtotal) { 80 if (scan->clock < temp_downclock) { 81 /* 82 * The downclock is already found. But we 83 * expect to find the lower downclock. 84 */ 85 temp_downclock = scan->clock; 86 tmp_mode = scan; 87 } 88 } 89 } 90 91 if (temp_downclock < fixed_mode->clock) 92 return drm_mode_duplicate(dev, tmp_mode); 93 else 94 return NULL; 95 } 96 97 /* adjusted_mode has been preset to be the panel's fixed mode */ 98 void 99 intel_pch_panel_fitting(struct intel_crtc *intel_crtc, 100 struct intel_crtc_state *pipe_config, 101 int fitting_mode) 102 { 103 struct drm_display_mode *adjusted_mode; 104 int x, y, width, height; 105 106 adjusted_mode = &pipe_config->base.adjusted_mode; 107 108 x = y = width = height = 0; 109 110 /* Native modes don't need fitting */ 111 if (adjusted_mode->hdisplay == pipe_config->pipe_src_w && 112 adjusted_mode->vdisplay == pipe_config->pipe_src_h) 113 goto done; 114 115 switch (fitting_mode) { 116 case DRM_MODE_SCALE_CENTER: 117 width = pipe_config->pipe_src_w; 118 height = pipe_config->pipe_src_h; 119 x = (adjusted_mode->hdisplay - width + 1)/2; 120 y = (adjusted_mode->vdisplay - height + 1)/2; 121 break; 122 123 case DRM_MODE_SCALE_ASPECT: 124 /* Scale but preserve the aspect ratio */ 125 { 126 u32 scaled_width = adjusted_mode->hdisplay 127 * pipe_config->pipe_src_h; 128 u32 scaled_height = pipe_config->pipe_src_w 129 * adjusted_mode->vdisplay; 130 if (scaled_width > scaled_height) { /* pillar */ 131 width = scaled_height / pipe_config->pipe_src_h; 132 if (width & 1) 133 width++; 134 x = (adjusted_mode->hdisplay - width + 1) / 2; 135 y = 0; 136 height = adjusted_mode->vdisplay; 137 } else if (scaled_width < scaled_height) { /* letter */ 138 height = scaled_width / pipe_config->pipe_src_w; 139 if (height & 1) 140 height++; 141 y = (adjusted_mode->vdisplay - height + 1) / 2; 142 x = 0; 143 width = adjusted_mode->hdisplay; 144 } else { 145 x = y = 0; 146 width = adjusted_mode->hdisplay; 147 height = adjusted_mode->vdisplay; 148 } 149 } 150 break; 151 152 case DRM_MODE_SCALE_FULLSCREEN: 153 x = y = 0; 154 width = adjusted_mode->hdisplay; 155 height = adjusted_mode->vdisplay; 156 break; 157 158 default: 159 WARN(1, "bad panel fit mode: %d\n", fitting_mode); 160 return; 161 } 162 163 done: 164 pipe_config->pch_pfit.pos = (x << 16) | y; 165 pipe_config->pch_pfit.size = (width << 16) | height; 166 pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0; 167 } 168 169 static void 170 centre_horizontally(struct drm_display_mode *mode, 171 int width) 172 { 173 u32 border, sync_pos, blank_width, sync_width; 174 175 /* keep the hsync and hblank widths constant */ 176 sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start; 177 blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start; 178 sync_pos = (blank_width - sync_width + 1) / 2; 179 180 border = (mode->hdisplay - width + 1) / 2; 181 border += border & 1; /* make the border even */ 182 183 mode->crtc_hdisplay = width; 184 mode->crtc_hblank_start = width + border; 185 mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; 186 187 mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; 188 mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; 189 } 190 191 static void 192 centre_vertically(struct drm_display_mode *mode, 193 int height) 194 { 195 u32 border, sync_pos, blank_width, sync_width; 196 197 /* keep the vsync and vblank widths constant */ 198 sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start; 199 blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start; 200 sync_pos = (blank_width - sync_width + 1) / 2; 201 202 border = (mode->vdisplay - height + 1) / 2; 203 204 mode->crtc_vdisplay = height; 205 mode->crtc_vblank_start = height + border; 206 mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; 207 208 mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; 209 mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; 210 } 211 212 static inline u32 panel_fitter_scaling(u32 source, u32 target) 213 { 214 /* 215 * Floating point operation is not supported. So the FACTOR 216 * is defined, which can avoid the floating point computation 217 * when calculating the panel ratio. 218 */ 219 #define ACCURACY 12 220 #define FACTOR (1 << ACCURACY) 221 u32 ratio = source * FACTOR / target; 222 return (FACTOR * ratio + FACTOR/2) / FACTOR; 223 } 224 225 static void i965_scale_aspect(struct intel_crtc_state *pipe_config, 226 u32 *pfit_control) 227 { 228 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 229 u32 scaled_width = adjusted_mode->hdisplay * 230 pipe_config->pipe_src_h; 231 u32 scaled_height = pipe_config->pipe_src_w * 232 adjusted_mode->vdisplay; 233 234 /* 965+ is easy, it does everything in hw */ 235 if (scaled_width > scaled_height) 236 *pfit_control |= PFIT_ENABLE | 237 PFIT_SCALING_PILLAR; 238 else if (scaled_width < scaled_height) 239 *pfit_control |= PFIT_ENABLE | 240 PFIT_SCALING_LETTER; 241 else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w) 242 *pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; 243 } 244 245 static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config, 246 u32 *pfit_control, u32 *pfit_pgm_ratios, 247 u32 *border) 248 { 249 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 250 u32 scaled_width = adjusted_mode->hdisplay * 251 pipe_config->pipe_src_h; 252 u32 scaled_height = pipe_config->pipe_src_w * 253 adjusted_mode->vdisplay; 254 u32 bits; 255 256 /* 257 * For earlier chips we have to calculate the scaling 258 * ratio by hand and program it into the 259 * PFIT_PGM_RATIO register 260 */ 261 if (scaled_width > scaled_height) { /* pillar */ 262 centre_horizontally(adjusted_mode, 263 scaled_height / 264 pipe_config->pipe_src_h); 265 266 *border = LVDS_BORDER_ENABLE; 267 if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) { 268 bits = panel_fitter_scaling(pipe_config->pipe_src_h, 269 adjusted_mode->vdisplay); 270 271 *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | 272 bits << PFIT_VERT_SCALE_SHIFT); 273 *pfit_control |= (PFIT_ENABLE | 274 VERT_INTERP_BILINEAR | 275 HORIZ_INTERP_BILINEAR); 276 } 277 } else if (scaled_width < scaled_height) { /* letter */ 278 centre_vertically(adjusted_mode, 279 scaled_width / 280 pipe_config->pipe_src_w); 281 282 *border = LVDS_BORDER_ENABLE; 283 if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) { 284 bits = panel_fitter_scaling(pipe_config->pipe_src_w, 285 adjusted_mode->hdisplay); 286 287 *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | 288 bits << PFIT_VERT_SCALE_SHIFT); 289 *pfit_control |= (PFIT_ENABLE | 290 VERT_INTERP_BILINEAR | 291 HORIZ_INTERP_BILINEAR); 292 } 293 } else { 294 /* Aspects match, Let hw scale both directions */ 295 *pfit_control |= (PFIT_ENABLE | 296 VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | 297 VERT_INTERP_BILINEAR | 298 HORIZ_INTERP_BILINEAR); 299 } 300 } 301 302 void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, 303 struct intel_crtc_state *pipe_config, 304 int fitting_mode) 305 { 306 struct drm_device *dev = intel_crtc->base.dev; 307 u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; 308 struct drm_display_mode *adjusted_mode; 309 310 adjusted_mode = &pipe_config->base.adjusted_mode; 311 312 /* Native modes don't need fitting */ 313 if (adjusted_mode->hdisplay == pipe_config->pipe_src_w && 314 adjusted_mode->vdisplay == pipe_config->pipe_src_h) 315 goto out; 316 317 switch (fitting_mode) { 318 case DRM_MODE_SCALE_CENTER: 319 /* 320 * For centered modes, we have to calculate border widths & 321 * heights and modify the values programmed into the CRTC. 322 */ 323 centre_horizontally(adjusted_mode, pipe_config->pipe_src_w); 324 centre_vertically(adjusted_mode, pipe_config->pipe_src_h); 325 border = LVDS_BORDER_ENABLE; 326 break; 327 case DRM_MODE_SCALE_ASPECT: 328 /* Scale but preserve the aspect ratio */ 329 if (INTEL_INFO(dev)->gen >= 4) 330 i965_scale_aspect(pipe_config, &pfit_control); 331 else 332 i9xx_scale_aspect(pipe_config, &pfit_control, 333 &pfit_pgm_ratios, &border); 334 break; 335 case DRM_MODE_SCALE_FULLSCREEN: 336 /* 337 * Full scaling, even if it changes the aspect ratio. 338 * Fortunately this is all done for us in hw. 339 */ 340 if (pipe_config->pipe_src_h != adjusted_mode->vdisplay || 341 pipe_config->pipe_src_w != adjusted_mode->hdisplay) { 342 pfit_control |= PFIT_ENABLE; 343 if (INTEL_INFO(dev)->gen >= 4) 344 pfit_control |= PFIT_SCALING_AUTO; 345 else 346 pfit_control |= (VERT_AUTO_SCALE | 347 VERT_INTERP_BILINEAR | 348 HORIZ_AUTO_SCALE | 349 HORIZ_INTERP_BILINEAR); 350 } 351 break; 352 default: 353 WARN(1, "bad panel fit mode: %d\n", fitting_mode); 354 return; 355 } 356 357 /* 965+ wants fuzzy fitting */ 358 /* FIXME: handle multiple panels by failing gracefully */ 359 if (INTEL_INFO(dev)->gen >= 4) 360 pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | 361 PFIT_FILTER_FUZZY); 362 363 out: 364 if ((pfit_control & PFIT_ENABLE) == 0) { 365 pfit_control = 0; 366 pfit_pgm_ratios = 0; 367 } 368 369 /* Make sure pre-965 set dither correctly for 18bpp panels. */ 370 if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18) 371 pfit_control |= PANEL_8TO6_DITHER_ENABLE; 372 373 pipe_config->gmch_pfit.control = pfit_control; 374 pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios; 375 pipe_config->gmch_pfit.lvds_border_bits = border; 376 } 377 378 enum drm_connector_status 379 intel_panel_detect(struct drm_device *dev) 380 { 381 struct drm_i915_private *dev_priv = dev->dev_private; 382 383 /* Assume that the BIOS does not lie through the OpRegion... */ 384 if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) { 385 return ioread32(dev_priv->opregion.lid_state) & 0x1 ? 386 connector_status_connected : 387 connector_status_disconnected; 388 } 389 390 switch (i915.panel_ignore_lid) { 391 case -2: 392 return connector_status_connected; 393 case -1: 394 return connector_status_disconnected; 395 default: 396 return connector_status_unknown; 397 } 398 } 399 400 /** 401 * scale - scale values from one range to another 402 * 403 * @source_val: value in range [@source_min..@source_max] 404 * 405 * Return @source_val in range [@source_min..@source_max] scaled to range 406 * [@target_min..@target_max]. 407 */ 408 static uint32_t scale(uint32_t source_val, 409 uint32_t source_min, uint32_t source_max, 410 uint32_t target_min, uint32_t target_max) 411 { 412 uint64_t target_val; 413 414 WARN_ON(source_min > source_max); 415 WARN_ON(target_min > target_max); 416 417 /* defensive */ 418 source_val = clamp(source_val, source_min, source_max); 419 420 /* avoid overflows */ 421 target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) * 422 (target_max - target_min), source_max - source_min); 423 target_val += target_min; 424 425 return target_val; 426 } 427 428 /* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */ 429 static inline u32 scale_user_to_hw(struct intel_connector *connector, 430 u32 user_level, u32 user_max) 431 { 432 struct intel_panel *panel = &connector->panel; 433 434 return scale(user_level, 0, user_max, 435 panel->backlight.min, panel->backlight.max); 436 } 437 438 /* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result 439 * to [hw_min..hw_max]. */ 440 static inline u32 clamp_user_to_hw(struct intel_connector *connector, 441 u32 user_level, u32 user_max) 442 { 443 struct intel_panel *panel = &connector->panel; 444 u32 hw_level; 445 446 hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max); 447 hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max); 448 449 return hw_level; 450 } 451 452 /* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */ 453 static inline u32 scale_hw_to_user(struct intel_connector *connector, 454 u32 hw_level, u32 user_max) 455 { 456 struct intel_panel *panel = &connector->panel; 457 458 return scale(hw_level, panel->backlight.min, panel->backlight.max, 459 0, user_max); 460 } 461 462 static u32 intel_panel_compute_brightness(struct intel_connector *connector, 463 u32 val) 464 { 465 struct drm_device *dev = connector->base.dev; 466 struct drm_i915_private *dev_priv = dev->dev_private; 467 struct intel_panel *panel = &connector->panel; 468 469 WARN_ON(panel->backlight.max == 0); 470 471 if (i915.invert_brightness < 0) 472 return val; 473 474 if (i915.invert_brightness > 0 || 475 dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { 476 return panel->backlight.max - val; 477 } 478 479 return val; 480 } 481 482 static u32 bdw_get_backlight(struct intel_connector *connector) 483 { 484 struct drm_device *dev = connector->base.dev; 485 struct drm_i915_private *dev_priv = dev->dev_private; 486 487 return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; 488 } 489 490 static u32 pch_get_backlight(struct intel_connector *connector) 491 { 492 struct drm_device *dev = connector->base.dev; 493 struct drm_i915_private *dev_priv = dev->dev_private; 494 495 return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; 496 } 497 498 static u32 i9xx_get_backlight(struct intel_connector *connector) 499 { 500 struct drm_device *dev = connector->base.dev; 501 struct drm_i915_private *dev_priv = dev->dev_private; 502 struct intel_panel *panel = &connector->panel; 503 u32 val; 504 505 val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; 506 if (INTEL_INFO(dev)->gen < 4) 507 val >>= 1; 508 509 if (panel->backlight.combination_mode) { 510 u8 lbpc; 511 512 pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); 513 val *= lbpc; 514 } 515 516 return val; 517 } 518 519 static u32 _vlv_get_backlight(struct drm_device *dev, enum i915_pipe pipe) 520 { 521 struct drm_i915_private *dev_priv = dev->dev_private; 522 523 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 524 return 0; 525 526 return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; 527 } 528 529 static u32 vlv_get_backlight(struct intel_connector *connector) 530 { 531 struct drm_device *dev = connector->base.dev; 532 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 533 534 return _vlv_get_backlight(dev, pipe); 535 } 536 537 #if 0 538 static u32 intel_panel_get_backlight(struct intel_connector *connector) 539 { 540 struct drm_device *dev = connector->base.dev; 541 struct drm_i915_private *dev_priv = dev->dev_private; 542 struct intel_panel *panel = &connector->panel; 543 u32 val = 0; 544 545 mutex_lock(&dev_priv->backlight_lock); 546 547 if (panel->backlight.enabled) { 548 val = dev_priv->display.get_backlight(connector); 549 val = intel_panel_compute_brightness(connector, val); 550 } 551 552 mutex_unlock(&dev_priv->backlight_lock); 553 554 DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); 555 return val; 556 } 557 #endif 558 559 static void bdw_set_backlight(struct intel_connector *connector, u32 level) 560 { 561 struct drm_device *dev = connector->base.dev; 562 struct drm_i915_private *dev_priv = dev->dev_private; 563 u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; 564 I915_WRITE(BLC_PWM_PCH_CTL2, val | level); 565 } 566 567 static void pch_set_backlight(struct intel_connector *connector, u32 level) 568 { 569 struct drm_device *dev = connector->base.dev; 570 struct drm_i915_private *dev_priv = dev->dev_private; 571 u32 tmp; 572 573 tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; 574 I915_WRITE(BLC_PWM_CPU_CTL, tmp | level); 575 } 576 577 static void i9xx_set_backlight(struct intel_connector *connector, u32 level) 578 { 579 struct drm_device *dev = connector->base.dev; 580 struct drm_i915_private *dev_priv = dev->dev_private; 581 struct intel_panel *panel = &connector->panel; 582 u32 tmp, mask; 583 584 WARN_ON(panel->backlight.max == 0); 585 586 if (panel->backlight.combination_mode) { 587 u8 lbpc; 588 589 lbpc = level * 0xfe / panel->backlight.max + 1; 590 level /= lbpc; 591 pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); 592 } 593 594 if (IS_GEN4(dev)) { 595 mask = BACKLIGHT_DUTY_CYCLE_MASK; 596 } else { 597 level <<= 1; 598 mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV; 599 } 600 601 tmp = I915_READ(BLC_PWM_CTL) & ~mask; 602 I915_WRITE(BLC_PWM_CTL, tmp | level); 603 } 604 605 static void vlv_set_backlight(struct intel_connector *connector, u32 level) 606 { 607 struct drm_device *dev = connector->base.dev; 608 struct drm_i915_private *dev_priv = dev->dev_private; 609 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 610 u32 tmp; 611 612 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 613 return; 614 615 tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; 616 I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level); 617 } 618 619 static void 620 intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) 621 { 622 struct drm_device *dev = connector->base.dev; 623 struct drm_i915_private *dev_priv = dev->dev_private; 624 625 DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); 626 627 level = intel_panel_compute_brightness(connector, level); 628 dev_priv->display.set_backlight(connector, level); 629 } 630 631 /* set backlight brightness to level in range [0..max], scaling wrt hw min */ 632 static void intel_panel_set_backlight(struct intel_connector *connector, 633 u32 user_level, u32 user_max) 634 { 635 struct drm_device *dev = connector->base.dev; 636 struct drm_i915_private *dev_priv = dev->dev_private; 637 struct intel_panel *panel = &connector->panel; 638 u32 hw_level; 639 640 if (!panel->backlight.present) 641 return; 642 643 mutex_lock(&dev_priv->backlight_lock); 644 645 WARN_ON(panel->backlight.max == 0); 646 647 hw_level = scale_user_to_hw(connector, user_level, user_max); 648 panel->backlight.level = hw_level; 649 650 if (panel->backlight.enabled) 651 intel_panel_actually_set_backlight(connector, hw_level); 652 653 mutex_unlock(&dev_priv->backlight_lock); 654 } 655 656 /* set backlight brightness to level in range [0..max], assuming hw min is 657 * respected. 658 */ 659 void intel_panel_set_backlight_acpi(struct intel_connector *connector, 660 u32 user_level, u32 user_max) 661 { 662 struct drm_device *dev = connector->base.dev; 663 struct drm_i915_private *dev_priv = dev->dev_private; 664 struct intel_panel *panel = &connector->panel; 665 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 666 u32 hw_level; 667 668 /* 669 * INVALID_PIPE may occur during driver init because 670 * connection_mutex isn't held across the entire backlight 671 * setup + modeset readout, and the BIOS can issue the 672 * requests at any time. 673 */ 674 if (!panel->backlight.present || pipe == INVALID_PIPE) 675 return; 676 677 mutex_lock(&dev_priv->backlight_lock); 678 679 WARN_ON(panel->backlight.max == 0); 680 681 hw_level = clamp_user_to_hw(connector, user_level, user_max); 682 panel->backlight.level = hw_level; 683 684 if (panel->backlight.device) 685 panel->backlight.device->props.brightness = 686 scale_hw_to_user(connector, 687 panel->backlight.level, 688 panel->backlight.device->props.max_brightness); 689 690 if (panel->backlight.enabled) 691 intel_panel_actually_set_backlight(connector, hw_level); 692 693 mutex_unlock(&dev_priv->backlight_lock); 694 } 695 696 static void pch_disable_backlight(struct intel_connector *connector) 697 { 698 struct drm_device *dev = connector->base.dev; 699 struct drm_i915_private *dev_priv = dev->dev_private; 700 u32 tmp; 701 702 intel_panel_actually_set_backlight(connector, 0); 703 704 tmp = I915_READ(BLC_PWM_CPU_CTL2); 705 I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); 706 707 tmp = I915_READ(BLC_PWM_PCH_CTL1); 708 I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); 709 } 710 711 static void i9xx_disable_backlight(struct intel_connector *connector) 712 { 713 intel_panel_actually_set_backlight(connector, 0); 714 } 715 716 static void i965_disable_backlight(struct intel_connector *connector) 717 { 718 struct drm_device *dev = connector->base.dev; 719 struct drm_i915_private *dev_priv = dev->dev_private; 720 u32 tmp; 721 722 intel_panel_actually_set_backlight(connector, 0); 723 724 tmp = I915_READ(BLC_PWM_CTL2); 725 I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); 726 } 727 728 static void vlv_disable_backlight(struct intel_connector *connector) 729 { 730 struct drm_device *dev = connector->base.dev; 731 struct drm_i915_private *dev_priv = dev->dev_private; 732 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 733 u32 tmp; 734 735 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 736 return; 737 738 intel_panel_actually_set_backlight(connector, 0); 739 740 tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe)); 741 I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE); 742 } 743 744 void intel_panel_disable_backlight(struct intel_connector *connector) 745 { 746 struct drm_device *dev = connector->base.dev; 747 struct drm_i915_private *dev_priv = dev->dev_private; 748 struct intel_panel *panel = &connector->panel; 749 750 if (!panel->backlight.present) 751 return; 752 753 /* 754 * Do not disable backlight on the vgaswitcheroo path. When switching 755 * away from i915, the other client may depend on i915 to handle the 756 * backlight. This will leave the backlight on unnecessarily when 757 * another client is not activated. 758 */ 759 if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) { 760 DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n"); 761 return; 762 } 763 764 mutex_lock(&dev_priv->backlight_lock); 765 766 if (panel->backlight.device) 767 panel->backlight.device->props.power = FB_BLANK_POWERDOWN; 768 panel->backlight.enabled = false; 769 dev_priv->display.disable_backlight(connector); 770 771 mutex_unlock(&dev_priv->backlight_lock); 772 } 773 774 static void bdw_enable_backlight(struct intel_connector *connector) 775 { 776 struct drm_device *dev = connector->base.dev; 777 struct drm_i915_private *dev_priv = dev->dev_private; 778 struct intel_panel *panel = &connector->panel; 779 u32 pch_ctl1, pch_ctl2; 780 781 pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); 782 if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { 783 DRM_DEBUG_KMS("pch backlight already enabled\n"); 784 pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; 785 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); 786 } 787 788 pch_ctl2 = panel->backlight.max << 16; 789 I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); 790 791 pch_ctl1 = 0; 792 if (panel->backlight.active_low_pwm) 793 pch_ctl1 |= BLM_PCH_POLARITY; 794 795 /* After LPT, override is the default. */ 796 if (HAS_PCH_LPT(dev_priv)) 797 pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; 798 799 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); 800 POSTING_READ(BLC_PWM_PCH_CTL1); 801 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); 802 803 /* This won't stick until the above enable. */ 804 intel_panel_actually_set_backlight(connector, panel->backlight.level); 805 } 806 807 static void pch_enable_backlight(struct intel_connector *connector) 808 { 809 struct drm_device *dev = connector->base.dev; 810 struct drm_i915_private *dev_priv = dev->dev_private; 811 struct intel_panel *panel = &connector->panel; 812 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 813 enum transcoder cpu_transcoder = 814 intel_pipe_to_cpu_transcoder(dev_priv, pipe); 815 u32 cpu_ctl2, pch_ctl1, pch_ctl2; 816 817 cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); 818 if (cpu_ctl2 & BLM_PWM_ENABLE) { 819 DRM_DEBUG_KMS("cpu backlight already enabled\n"); 820 cpu_ctl2 &= ~BLM_PWM_ENABLE; 821 I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); 822 } 823 824 pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); 825 if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { 826 DRM_DEBUG_KMS("pch backlight already enabled\n"); 827 pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; 828 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); 829 } 830 831 if (cpu_transcoder == TRANSCODER_EDP) 832 cpu_ctl2 = BLM_TRANSCODER_EDP; 833 else 834 cpu_ctl2 = BLM_PIPE(cpu_transcoder); 835 I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); 836 POSTING_READ(BLC_PWM_CPU_CTL2); 837 I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); 838 839 /* This won't stick until the above enable. */ 840 intel_panel_actually_set_backlight(connector, panel->backlight.level); 841 842 pch_ctl2 = panel->backlight.max << 16; 843 I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); 844 845 pch_ctl1 = 0; 846 if (panel->backlight.active_low_pwm) 847 pch_ctl1 |= BLM_PCH_POLARITY; 848 849 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); 850 POSTING_READ(BLC_PWM_PCH_CTL1); 851 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); 852 } 853 854 static void i9xx_enable_backlight(struct intel_connector *connector) 855 { 856 struct drm_device *dev = connector->base.dev; 857 struct drm_i915_private *dev_priv = dev->dev_private; 858 struct intel_panel *panel = &connector->panel; 859 u32 ctl, freq; 860 861 ctl = I915_READ(BLC_PWM_CTL); 862 if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { 863 DRM_DEBUG_KMS("backlight already enabled\n"); 864 I915_WRITE(BLC_PWM_CTL, 0); 865 } 866 867 freq = panel->backlight.max; 868 if (panel->backlight.combination_mode) 869 freq /= 0xff; 870 871 ctl = freq << 17; 872 if (panel->backlight.combination_mode) 873 ctl |= BLM_LEGACY_MODE; 874 if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm) 875 ctl |= BLM_POLARITY_PNV; 876 877 I915_WRITE(BLC_PWM_CTL, ctl); 878 POSTING_READ(BLC_PWM_CTL); 879 880 /* XXX: combine this into above write? */ 881 intel_panel_actually_set_backlight(connector, panel->backlight.level); 882 } 883 884 static void i965_enable_backlight(struct intel_connector *connector) 885 { 886 struct drm_device *dev = connector->base.dev; 887 struct drm_i915_private *dev_priv = dev->dev_private; 888 struct intel_panel *panel = &connector->panel; 889 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 890 u32 ctl, ctl2, freq; 891 892 ctl2 = I915_READ(BLC_PWM_CTL2); 893 if (ctl2 & BLM_PWM_ENABLE) { 894 DRM_DEBUG_KMS("backlight already enabled\n"); 895 ctl2 &= ~BLM_PWM_ENABLE; 896 I915_WRITE(BLC_PWM_CTL2, ctl2); 897 } 898 899 freq = panel->backlight.max; 900 if (panel->backlight.combination_mode) 901 freq /= 0xff; 902 903 ctl = freq << 16; 904 I915_WRITE(BLC_PWM_CTL, ctl); 905 906 ctl2 = BLM_PIPE(pipe); 907 if (panel->backlight.combination_mode) 908 ctl2 |= BLM_COMBINATION_MODE; 909 if (panel->backlight.active_low_pwm) 910 ctl2 |= BLM_POLARITY_I965; 911 I915_WRITE(BLC_PWM_CTL2, ctl2); 912 POSTING_READ(BLC_PWM_CTL2); 913 I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); 914 915 intel_panel_actually_set_backlight(connector, panel->backlight.level); 916 } 917 918 static void vlv_enable_backlight(struct intel_connector *connector) 919 { 920 struct drm_device *dev = connector->base.dev; 921 struct drm_i915_private *dev_priv = dev->dev_private; 922 struct intel_panel *panel = &connector->panel; 923 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 924 u32 ctl, ctl2; 925 926 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 927 return; 928 929 ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); 930 if (ctl2 & BLM_PWM_ENABLE) { 931 DRM_DEBUG_KMS("backlight already enabled\n"); 932 ctl2 &= ~BLM_PWM_ENABLE; 933 I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); 934 } 935 936 ctl = panel->backlight.max << 16; 937 I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl); 938 939 /* XXX: combine this into above write? */ 940 intel_panel_actually_set_backlight(connector, panel->backlight.level); 941 942 ctl2 = 0; 943 if (panel->backlight.active_low_pwm) 944 ctl2 |= BLM_POLARITY_I965; 945 I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); 946 POSTING_READ(VLV_BLC_PWM_CTL2(pipe)); 947 I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE); 948 } 949 950 void intel_panel_enable_backlight(struct intel_connector *connector) 951 { 952 struct drm_device *dev = connector->base.dev; 953 struct drm_i915_private *dev_priv = dev->dev_private; 954 struct intel_panel *panel = &connector->panel; 955 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 956 957 if (!panel->backlight.present) 958 return; 959 960 DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); 961 962 mutex_lock(&dev_priv->backlight_lock); 963 964 WARN_ON(panel->backlight.max == 0); 965 966 if (panel->backlight.level <= panel->backlight.min) { 967 panel->backlight.level = panel->backlight.max; 968 if (panel->backlight.device) 969 panel->backlight.device->props.brightness = 970 scale_hw_to_user(connector, 971 panel->backlight.level, 972 panel->backlight.device->props.max_brightness); 973 } 974 975 dev_priv->display.enable_backlight(connector); 976 panel->backlight.enabled = true; 977 if (panel->backlight.device) 978 panel->backlight.device->props.power = FB_BLANK_UNBLANK; 979 980 mutex_unlock(&dev_priv->backlight_lock); 981 } 982 983 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) 984 static int intel_backlight_device_update_status(struct backlight_device *bd) 985 { 986 #if 0 987 struct intel_connector *connector = bl_get_data(bd); 988 struct intel_panel *panel = &connector->panel; 989 struct drm_device *dev = connector->base.dev; 990 991 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 992 DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", 993 bd->props.brightness, bd->props.max_brightness); 994 intel_panel_set_backlight(connector, bd->props.brightness, 995 bd->props.max_brightness); 996 997 /* 998 * Allow flipping bl_power as a sub-state of enabled. Sadly the 999 * backlight class device does not make it easy to to differentiate 1000 * between callbacks for brightness and bl_power, so our backlight_power 1001 * callback needs to take this into account. 1002 */ 1003 if (panel->backlight.enabled) { 1004 if (panel->backlight_power) { 1005 bool enable = bd->props.power == FB_BLANK_UNBLANK && 1006 bd->props.brightness != 0; 1007 panel->backlight_power(connector, enable); 1008 } 1009 } else { 1010 bd->props.power = FB_BLANK_POWERDOWN; 1011 } 1012 1013 drm_modeset_unlock(&dev->mode_config.connection_mutex); 1014 #endif 1015 return 0; 1016 } 1017 1018 static int intel_backlight_device_get_brightness(struct backlight_device *bd) 1019 { 1020 #if 0 1021 struct intel_connector *connector = bl_get_data(bd); 1022 struct drm_device *dev = connector->base.dev; 1023 struct drm_i915_private *dev_priv = dev->dev_private; 1024 u32 hw_level; 1025 int ret; 1026 1027 intel_runtime_pm_get(dev_priv); 1028 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 1029 1030 hw_level = intel_panel_get_backlight(connector); 1031 ret = scale_hw_to_user(connector, hw_level, bd->props.max_brightness); 1032 1033 drm_modeset_unlock(&dev->mode_config.connection_mutex); 1034 intel_runtime_pm_put(dev_priv); 1035 1036 return ret; 1037 #endif 1038 return 0; 1039 } 1040 1041 static const struct backlight_ops intel_backlight_device_ops = { 1042 .update_status = intel_backlight_device_update_status, 1043 .get_brightness = intel_backlight_device_get_brightness, 1044 }; 1045 1046 static int intel_backlight_device_register(struct intel_connector *connector) 1047 { 1048 struct intel_panel *panel = &connector->panel; 1049 struct backlight_properties props; 1050 1051 if (WARN_ON(panel->backlight.device)) 1052 return -ENODEV; 1053 1054 if (!panel->backlight.present) 1055 return 0; 1056 1057 WARN_ON(panel->backlight.max == 0); 1058 1059 memset(&props, 0, sizeof(props)); 1060 props.type = BACKLIGHT_RAW; 1061 1062 /* 1063 * Note: Everything should work even if the backlight device max 1064 * presented to the userspace is arbitrarily chosen. 1065 */ 1066 props.max_brightness = panel->backlight.max; 1067 props.brightness = scale_hw_to_user(connector, 1068 panel->backlight.level, 1069 props.max_brightness); 1070 1071 if (panel->backlight.enabled) 1072 props.power = FB_BLANK_UNBLANK; 1073 else 1074 props.power = FB_BLANK_POWERDOWN; 1075 1076 /* 1077 * Note: using the same name independent of the connector prevents 1078 * registration of multiple backlight devices in the driver. 1079 */ 1080 #if 0 1081 panel->backlight.device = 1082 backlight_device_register("intel_backlight", 1083 connector->base.kdev, 1084 connector, 1085 &intel_backlight_device_ops, &props); 1086 1087 if (IS_ERR(panel->backlight.device)) { 1088 DRM_ERROR("Failed to register backlight: %ld\n", 1089 PTR_ERR(panel->backlight.device)); 1090 panel->backlight.device = NULL; 1091 return -ENODEV; 1092 } 1093 #endif 1094 1095 DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n", 1096 connector->base.name); 1097 1098 return 0; 1099 } 1100 1101 static void intel_backlight_device_unregister(struct intel_connector *connector) 1102 { 1103 #if 0 1104 struct intel_panel *panel = &connector->panel; 1105 1106 if (panel->backlight.device) { 1107 backlight_device_unregister(panel->backlight.device); 1108 panel->backlight.device = NULL; 1109 } 1110 #endif 1111 } 1112 #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ 1113 static int intel_backlight_device_register(struct intel_connector *connector) 1114 { 1115 return 0; 1116 } 1117 static void intel_backlight_device_unregister(struct intel_connector *connector) 1118 { 1119 } 1120 #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ 1121 1122 /* 1123 * Note: The setup hooks can't assume pipe is set! 1124 * 1125 * XXX: Query mode clock or hardware clock and program PWM modulation frequency 1126 * appropriately when it's 0. Use VBT and/or sane defaults. 1127 */ 1128 static u32 get_backlight_min_vbt(struct intel_connector *connector) 1129 { 1130 struct drm_device *dev = connector->base.dev; 1131 struct drm_i915_private *dev_priv = dev->dev_private; 1132 struct intel_panel *panel = &connector->panel; 1133 int min; 1134 1135 WARN_ON(panel->backlight.max == 0); 1136 1137 /* 1138 * XXX: If the vbt value is 255, it makes min equal to max, which leads 1139 * to problems. There are such machines out there. Either our 1140 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard 1141 * against this by letting the minimum be at most (arbitrarily chosen) 1142 * 25% of the max. 1143 */ 1144 min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64); 1145 if (min != dev_priv->vbt.backlight.min_brightness) { 1146 DRM_DEBUG_KMS("clamping VBT min backlight %d/255 to %d/255\n", 1147 dev_priv->vbt.backlight.min_brightness, min); 1148 } 1149 1150 /* vbt value is a coefficient in range [0..255] */ 1151 return scale(min, 0, 255, 0, panel->backlight.max); 1152 } 1153 1154 static int bdw_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1155 { 1156 struct drm_device *dev = connector->base.dev; 1157 struct drm_i915_private *dev_priv = dev->dev_private; 1158 struct intel_panel *panel = &connector->panel; 1159 u32 pch_ctl1, pch_ctl2, val; 1160 1161 pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); 1162 panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; 1163 1164 pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2); 1165 panel->backlight.max = pch_ctl2 >> 16; 1166 if (!panel->backlight.max) 1167 return -ENODEV; 1168 1169 panel->backlight.min = get_backlight_min_vbt(connector); 1170 1171 val = bdw_get_backlight(connector); 1172 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1173 1174 panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) && 1175 panel->backlight.level != 0; 1176 1177 return 0; 1178 } 1179 1180 static int pch_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1181 { 1182 struct drm_device *dev = connector->base.dev; 1183 struct drm_i915_private *dev_priv = dev->dev_private; 1184 struct intel_panel *panel = &connector->panel; 1185 u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; 1186 1187 pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); 1188 panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; 1189 1190 pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2); 1191 panel->backlight.max = pch_ctl2 >> 16; 1192 if (!panel->backlight.max) 1193 return -ENODEV; 1194 1195 panel->backlight.min = get_backlight_min_vbt(connector); 1196 1197 val = pch_get_backlight(connector); 1198 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1199 1200 cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); 1201 panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) && 1202 (pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0; 1203 1204 return 0; 1205 } 1206 1207 static int i9xx_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1208 { 1209 struct drm_device *dev = connector->base.dev; 1210 struct drm_i915_private *dev_priv = dev->dev_private; 1211 struct intel_panel *panel = &connector->panel; 1212 u32 ctl, val; 1213 1214 ctl = I915_READ(BLC_PWM_CTL); 1215 1216 if (IS_GEN2(dev) || IS_I915GM(dev) || IS_I945GM(dev)) 1217 panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; 1218 1219 if (IS_PINEVIEW(dev)) 1220 panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV; 1221 1222 panel->backlight.max = ctl >> 17; 1223 if (panel->backlight.combination_mode) 1224 panel->backlight.max *= 0xff; 1225 1226 if (!panel->backlight.max) 1227 return -ENODEV; 1228 1229 panel->backlight.min = get_backlight_min_vbt(connector); 1230 1231 val = i9xx_get_backlight(connector); 1232 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1233 1234 panel->backlight.enabled = panel->backlight.level != 0; 1235 1236 return 0; 1237 } 1238 1239 static int i965_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1240 { 1241 struct drm_device *dev = connector->base.dev; 1242 struct drm_i915_private *dev_priv = dev->dev_private; 1243 struct intel_panel *panel = &connector->panel; 1244 u32 ctl, ctl2, val; 1245 1246 ctl2 = I915_READ(BLC_PWM_CTL2); 1247 panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE; 1248 panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; 1249 1250 ctl = I915_READ(BLC_PWM_CTL); 1251 panel->backlight.max = ctl >> 16; 1252 if (panel->backlight.combination_mode) 1253 panel->backlight.max *= 0xff; 1254 1255 if (!panel->backlight.max) 1256 return -ENODEV; 1257 1258 panel->backlight.min = get_backlight_min_vbt(connector); 1259 1260 val = i9xx_get_backlight(connector); 1261 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1262 1263 panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) && 1264 panel->backlight.level != 0; 1265 1266 return 0; 1267 } 1268 1269 static int vlv_setup_backlight(struct intel_connector *connector, enum i915_pipe pipe) 1270 { 1271 struct drm_device *dev = connector->base.dev; 1272 struct drm_i915_private *dev_priv = dev->dev_private; 1273 struct intel_panel *panel = &connector->panel; 1274 enum i915_pipe p; 1275 u32 ctl, ctl2, val; 1276 1277 for_each_pipe(dev_priv, p) { 1278 u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(p)); 1279 1280 /* Skip if the modulation freq is already set */ 1281 if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK) 1282 continue; 1283 1284 cur_val &= BACKLIGHT_DUTY_CYCLE_MASK; 1285 I915_WRITE(VLV_BLC_PWM_CTL(p), (0xf42 << 16) | 1286 cur_val); 1287 } 1288 1289 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 1290 return -ENODEV; 1291 1292 ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); 1293 panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; 1294 1295 ctl = I915_READ(VLV_BLC_PWM_CTL(pipe)); 1296 panel->backlight.max = ctl >> 16; 1297 if (!panel->backlight.max) 1298 return -ENODEV; 1299 1300 panel->backlight.min = get_backlight_min_vbt(connector); 1301 1302 val = _vlv_get_backlight(dev, pipe); 1303 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1304 1305 panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) && 1306 panel->backlight.level != 0; 1307 1308 return 0; 1309 } 1310 1311 #ifdef __DragonFly__ 1312 /* 1313 * Read max backlight level 1314 */ 1315 static int 1316 sysctl_backlight_max(SYSCTL_HANDLER_ARGS) 1317 { 1318 int err, val; 1319 struct intel_connector *connector = arg1; 1320 struct drm_device *dev = connector->base.dev; 1321 struct drm_i915_private *dev_priv = dev->dev_private; 1322 struct intel_panel *panel = &connector->panel; 1323 1324 mutex_lock(&dev_priv->backlight_lock); 1325 val = panel->backlight.max; 1326 mutex_unlock(&dev_priv->backlight_lock); 1327 1328 err = sysctl_handle_int(oidp, &val, 0, req); 1329 return(err); 1330 } 1331 1332 /* 1333 * Read/write backlight level 1334 */ 1335 static int 1336 sysctl_backlight_handler(SYSCTL_HANDLER_ARGS) 1337 { 1338 struct intel_connector *connector = arg1; 1339 struct drm_device *dev = connector->base.dev; 1340 struct drm_i915_private *dev_priv = dev->dev_private; 1341 struct intel_panel *panel = &connector->panel; 1342 int err, val; 1343 u32 user_level, max_brightness; 1344 1345 mutex_lock(&dev_priv->backlight_lock); 1346 max_brightness = panel->backlight.max; 1347 user_level = scale_hw_to_user(connector, panel->backlight.level, 1348 max_brightness); 1349 mutex_unlock(&dev_priv->backlight_lock); 1350 1351 val = user_level; 1352 err = sysctl_handle_int(oidp, &val, 0, req); 1353 if (err != 0 || req->newptr == NULL) { 1354 return(err); 1355 } 1356 1357 if (val != user_level && val >= 0 && val <= max_brightness) { 1358 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 1359 intel_panel_set_backlight(arg1, val, max_brightness); 1360 drm_modeset_unlock(&dev->mode_config.connection_mutex); 1361 } 1362 1363 return(err); 1364 } 1365 #endif /* __DragonFly__ */ 1366 1367 int intel_panel_setup_backlight(struct drm_connector *connector, enum i915_pipe pipe) 1368 { 1369 struct drm_device *dev = connector->dev; 1370 struct drm_i915_private *dev_priv = dev->dev_private; 1371 struct intel_connector *intel_connector = to_intel_connector(connector); 1372 struct intel_panel *panel = &intel_connector->panel; 1373 int ret; 1374 1375 if (!dev_priv->vbt.backlight.present) { 1376 if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { 1377 DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n"); 1378 } else { 1379 DRM_DEBUG_KMS("no backlight present per VBT\n"); 1380 return 0; 1381 } 1382 } 1383 1384 /* set level and max in panel struct */ 1385 mutex_lock(&dev_priv->backlight_lock); 1386 ret = dev_priv->display.setup_backlight(intel_connector, pipe); 1387 mutex_unlock(&dev_priv->backlight_lock); 1388 1389 if (ret) { 1390 DRM_DEBUG_KMS("failed to setup backlight for connector %s\n", 1391 connector->name); 1392 return ret; 1393 } 1394 1395 panel->backlight.present = true; 1396 1397 #ifdef __DragonFly__ 1398 SYSCTL_ADD_PROC(&connector->dev->sysctl->ctx, &sysctl__hw_children, 1399 OID_AUTO, "backlight_max", 1400 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_ANYBODY, 1401 connector, sizeof(int), 1402 sysctl_backlight_max, 1403 "I", "Max backlight level"); 1404 SYSCTL_ADD_PROC(&connector->dev->sysctl->ctx, &sysctl__hw_children, 1405 OID_AUTO, "backlight_level", 1406 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, 1407 connector, sizeof(int), 1408 sysctl_backlight_handler, 1409 "I", "Backlight level"); 1410 #endif 1411 1412 DRM_DEBUG_KMS("Connector %s backlight initialized, %s, brightness %u/%u\n", 1413 connector->name, 1414 panel->backlight.enabled ? "enabled" : "disabled", 1415 panel->backlight.level, panel->backlight.max); 1416 1417 return 0; 1418 } 1419 1420 void intel_panel_destroy_backlight(struct drm_connector *connector) 1421 { 1422 struct intel_connector *intel_connector = to_intel_connector(connector); 1423 struct intel_panel *panel = &intel_connector->panel; 1424 1425 panel->backlight.present = false; 1426 } 1427 1428 /* Set up chip specific backlight functions */ 1429 void intel_panel_init_backlight_funcs(struct drm_device *dev) 1430 { 1431 struct drm_i915_private *dev_priv = dev->dev_private; 1432 1433 if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) { 1434 dev_priv->display.setup_backlight = bdw_setup_backlight; 1435 dev_priv->display.enable_backlight = bdw_enable_backlight; 1436 dev_priv->display.disable_backlight = pch_disable_backlight; 1437 dev_priv->display.set_backlight = bdw_set_backlight; 1438 dev_priv->display.get_backlight = bdw_get_backlight; 1439 } else if (HAS_PCH_SPLIT(dev)) { 1440 dev_priv->display.setup_backlight = pch_setup_backlight; 1441 dev_priv->display.enable_backlight = pch_enable_backlight; 1442 dev_priv->display.disable_backlight = pch_disable_backlight; 1443 dev_priv->display.set_backlight = pch_set_backlight; 1444 dev_priv->display.get_backlight = pch_get_backlight; 1445 } else if (IS_VALLEYVIEW(dev)) { 1446 dev_priv->display.setup_backlight = vlv_setup_backlight; 1447 dev_priv->display.enable_backlight = vlv_enable_backlight; 1448 dev_priv->display.disable_backlight = vlv_disable_backlight; 1449 dev_priv->display.set_backlight = vlv_set_backlight; 1450 dev_priv->display.get_backlight = vlv_get_backlight; 1451 } else if (IS_GEN4(dev)) { 1452 dev_priv->display.setup_backlight = i965_setup_backlight; 1453 dev_priv->display.enable_backlight = i965_enable_backlight; 1454 dev_priv->display.disable_backlight = i965_disable_backlight; 1455 dev_priv->display.set_backlight = i9xx_set_backlight; 1456 dev_priv->display.get_backlight = i9xx_get_backlight; 1457 } else { 1458 dev_priv->display.setup_backlight = i9xx_setup_backlight; 1459 dev_priv->display.enable_backlight = i9xx_enable_backlight; 1460 dev_priv->display.disable_backlight = i9xx_disable_backlight; 1461 dev_priv->display.set_backlight = i9xx_set_backlight; 1462 dev_priv->display.get_backlight = i9xx_get_backlight; 1463 } 1464 } 1465 1466 int intel_panel_init(struct intel_panel *panel, 1467 struct drm_display_mode *fixed_mode, 1468 struct drm_display_mode *downclock_mode) 1469 { 1470 panel->fixed_mode = fixed_mode; 1471 panel->downclock_mode = downclock_mode; 1472 1473 return 0; 1474 } 1475 1476 void intel_panel_fini(struct intel_panel *panel) 1477 { 1478 struct intel_connector *intel_connector = 1479 container_of(panel, struct intel_connector, panel); 1480 1481 if (panel->fixed_mode) 1482 drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); 1483 1484 if (panel->downclock_mode) 1485 drm_mode_destroy(intel_connector->base.dev, 1486 panel->downclock_mode); 1487 } 1488 1489 void intel_backlight_register(struct drm_device *dev) 1490 { 1491 struct intel_connector *connector; 1492 1493 list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) 1494 intel_backlight_device_register(connector); 1495 } 1496 1497 void intel_backlight_unregister(struct drm_device *dev) 1498 { 1499 struct intel_connector *connector; 1500 1501 list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) 1502 intel_backlight_device_unregister(connector); 1503 } 1504