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 32 #include <linux/kernel.h> 33 #include <linux/moduleparam.h> 34 #include <linux/pwm.h> 35 #include "intel_drv.h" 36 37 #define CRC_PMIC_PWM_PERIOD_NS 21333 38 39 void 40 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, 41 struct drm_display_mode *adjusted_mode) 42 { 43 drm_mode_copy(adjusted_mode, fixed_mode); 44 45 drm_mode_set_crtcinfo(adjusted_mode, 0); 46 } 47 48 /** 49 * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID 50 * @dev: drm device 51 * @fixed_mode : panel native mode 52 * @connector: LVDS/eDP connector 53 * 54 * Return downclock_avail 55 * Find the reduced downclock for LVDS/eDP in EDID. 56 */ 57 struct drm_display_mode * 58 intel_find_panel_downclock(struct drm_device *dev, 59 struct drm_display_mode *fixed_mode, 60 struct drm_connector *connector) 61 { 62 struct drm_display_mode *scan, *tmp_mode; 63 int temp_downclock; 64 65 temp_downclock = fixed_mode->clock; 66 tmp_mode = NULL; 67 68 list_for_each_entry(scan, &connector->probed_modes, head) { 69 /* 70 * If one mode has the same resolution with the fixed_panel 71 * mode while they have the different refresh rate, it means 72 * that the reduced downclock is found. In such 73 * case we can set the different FPx0/1 to dynamically select 74 * between low and high frequency. 75 */ 76 if (scan->hdisplay == fixed_mode->hdisplay && 77 scan->hsync_start == fixed_mode->hsync_start && 78 scan->hsync_end == fixed_mode->hsync_end && 79 scan->htotal == fixed_mode->htotal && 80 scan->vdisplay == fixed_mode->vdisplay && 81 scan->vsync_start == fixed_mode->vsync_start && 82 scan->vsync_end == fixed_mode->vsync_end && 83 scan->vtotal == fixed_mode->vtotal) { 84 if (scan->clock < temp_downclock) { 85 /* 86 * The downclock is already found. But we 87 * expect to find the lower downclock. 88 */ 89 temp_downclock = scan->clock; 90 tmp_mode = scan; 91 } 92 } 93 } 94 95 if (temp_downclock < fixed_mode->clock) 96 return drm_mode_duplicate(dev, tmp_mode); 97 else 98 return NULL; 99 } 100 101 /* adjusted_mode has been preset to be the panel's fixed mode */ 102 void 103 intel_pch_panel_fitting(struct intel_crtc *intel_crtc, 104 struct intel_crtc_state *pipe_config, 105 int fitting_mode) 106 { 107 const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 108 int x = 0, y = 0, width = 0, height = 0; 109 110 /* Native modes don't need fitting */ 111 if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w && 112 adjusted_mode->crtc_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->crtc_hdisplay - width + 1)/2; 120 y = (adjusted_mode->crtc_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->crtc_hdisplay 127 * pipe_config->pipe_src_h; 128 u32 scaled_height = pipe_config->pipe_src_w 129 * adjusted_mode->crtc_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->crtc_hdisplay - width + 1) / 2; 135 y = 0; 136 height = adjusted_mode->crtc_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->crtc_vdisplay - height + 1) / 2; 142 x = 0; 143 width = adjusted_mode->crtc_hdisplay; 144 } else { 145 x = y = 0; 146 width = adjusted_mode->crtc_hdisplay; 147 height = adjusted_mode->crtc_vdisplay; 148 } 149 } 150 break; 151 152 case DRM_MODE_SCALE_FULLSCREEN: 153 x = y = 0; 154 width = adjusted_mode->crtc_hdisplay; 155 height = adjusted_mode->crtc_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 *adjusted_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 = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; 177 blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start; 178 sync_pos = (blank_width - sync_width + 1) / 2; 179 180 border = (adjusted_mode->crtc_hdisplay - width + 1) / 2; 181 border += border & 1; /* make the border even */ 182 183 adjusted_mode->crtc_hdisplay = width; 184 adjusted_mode->crtc_hblank_start = width + border; 185 adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width; 186 187 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos; 188 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width; 189 } 190 191 static void 192 centre_vertically(struct drm_display_mode *adjusted_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 = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; 199 blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start; 200 sync_pos = (blank_width - sync_width + 1) / 2; 201 202 border = (adjusted_mode->crtc_vdisplay - height + 1) / 2; 203 204 adjusted_mode->crtc_vdisplay = height; 205 adjusted_mode->crtc_vblank_start = height + border; 206 adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width; 207 208 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos; 209 adjusted_mode->crtc_vsync_end = adjusted_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 const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 229 u32 scaled_width = adjusted_mode->crtc_hdisplay * 230 pipe_config->pipe_src_h; 231 u32 scaled_height = pipe_config->pipe_src_w * 232 adjusted_mode->crtc_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->crtc_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->crtc_hdisplay * 251 pipe_config->pipe_src_h; 252 u32 scaled_height = pipe_config->pipe_src_w * 253 adjusted_mode->crtc_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->crtc_vdisplay) { 268 bits = panel_fitter_scaling(pipe_config->pipe_src_h, 269 adjusted_mode->crtc_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->crtc_hdisplay) { 284 bits = panel_fitter_scaling(pipe_config->pipe_src_w, 285 adjusted_mode->crtc_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 = &pipe_config->base.adjusted_mode; 309 310 /* Native modes don't need fitting */ 311 if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w && 312 adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h) 313 goto out; 314 315 switch (fitting_mode) { 316 case DRM_MODE_SCALE_CENTER: 317 /* 318 * For centered modes, we have to calculate border widths & 319 * heights and modify the values programmed into the CRTC. 320 */ 321 centre_horizontally(adjusted_mode, pipe_config->pipe_src_w); 322 centre_vertically(adjusted_mode, pipe_config->pipe_src_h); 323 border = LVDS_BORDER_ENABLE; 324 break; 325 case DRM_MODE_SCALE_ASPECT: 326 /* Scale but preserve the aspect ratio */ 327 if (INTEL_INFO(dev)->gen >= 4) 328 i965_scale_aspect(pipe_config, &pfit_control); 329 else 330 i9xx_scale_aspect(pipe_config, &pfit_control, 331 &pfit_pgm_ratios, &border); 332 break; 333 case DRM_MODE_SCALE_FULLSCREEN: 334 /* 335 * Full scaling, even if it changes the aspect ratio. 336 * Fortunately this is all done for us in hw. 337 */ 338 if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay || 339 pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) { 340 pfit_control |= PFIT_ENABLE; 341 if (INTEL_INFO(dev)->gen >= 4) 342 pfit_control |= PFIT_SCALING_AUTO; 343 else 344 pfit_control |= (VERT_AUTO_SCALE | 345 VERT_INTERP_BILINEAR | 346 HORIZ_AUTO_SCALE | 347 HORIZ_INTERP_BILINEAR); 348 } 349 break; 350 default: 351 WARN(1, "bad panel fit mode: %d\n", fitting_mode); 352 return; 353 } 354 355 /* 965+ wants fuzzy fitting */ 356 /* FIXME: handle multiple panels by failing gracefully */ 357 if (INTEL_INFO(dev)->gen >= 4) 358 pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | 359 PFIT_FILTER_FUZZY); 360 361 out: 362 if ((pfit_control & PFIT_ENABLE) == 0) { 363 pfit_control = 0; 364 pfit_pgm_ratios = 0; 365 } 366 367 /* Make sure pre-965 set dither correctly for 18bpp panels. */ 368 if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18) 369 pfit_control |= PANEL_8TO6_DITHER_ENABLE; 370 371 pipe_config->gmch_pfit.control = pfit_control; 372 pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios; 373 pipe_config->gmch_pfit.lvds_border_bits = border; 374 } 375 376 enum drm_connector_status 377 intel_panel_detect(struct drm_device *dev) 378 { 379 struct drm_i915_private *dev_priv = dev->dev_private; 380 381 /* Assume that the BIOS does not lie through the OpRegion... */ 382 if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) { 383 return *dev_priv->opregion.lid_state & 0x1 ? 384 connector_status_connected : 385 connector_status_disconnected; 386 } 387 388 switch (i915.panel_ignore_lid) { 389 case -2: 390 return connector_status_connected; 391 case -1: 392 return connector_status_disconnected; 393 default: 394 return connector_status_unknown; 395 } 396 } 397 398 /** 399 * scale - scale values from one range to another 400 * 401 * @source_val: value in range [@source_min..@source_max] 402 * 403 * Return @source_val in range [@source_min..@source_max] scaled to range 404 * [@target_min..@target_max]. 405 */ 406 static uint32_t scale(uint32_t source_val, 407 uint32_t source_min, uint32_t source_max, 408 uint32_t target_min, uint32_t target_max) 409 { 410 uint64_t target_val; 411 412 WARN_ON(source_min > source_max); 413 WARN_ON(target_min > target_max); 414 415 /* defensive */ 416 source_val = clamp(source_val, source_min, source_max); 417 418 /* avoid overflows */ 419 target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) * 420 (target_max - target_min), source_max - source_min); 421 target_val += target_min; 422 423 return target_val; 424 } 425 426 /* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */ 427 static inline u32 scale_user_to_hw(struct intel_connector *connector, 428 u32 user_level, u32 user_max) 429 { 430 struct intel_panel *panel = &connector->panel; 431 432 return scale(user_level, 0, user_max, 433 panel->backlight.min, panel->backlight.max); 434 } 435 436 /* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result 437 * to [hw_min..hw_max]. */ 438 static inline u32 clamp_user_to_hw(struct intel_connector *connector, 439 u32 user_level, u32 user_max) 440 { 441 struct intel_panel *panel = &connector->panel; 442 u32 hw_level; 443 444 hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max); 445 hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max); 446 447 return hw_level; 448 } 449 450 /* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */ 451 static inline u32 scale_hw_to_user(struct intel_connector *connector, 452 u32 hw_level, u32 user_max) 453 { 454 struct intel_panel *panel = &connector->panel; 455 456 return scale(hw_level, panel->backlight.min, panel->backlight.max, 457 0, user_max); 458 } 459 460 static u32 intel_panel_compute_brightness(struct intel_connector *connector, 461 u32 val) 462 { 463 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 464 struct intel_panel *panel = &connector->panel; 465 466 WARN_ON(panel->backlight.max == 0); 467 468 if (i915.invert_brightness < 0) 469 return val; 470 471 if (i915.invert_brightness > 0 || 472 dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { 473 return panel->backlight.max - val; 474 } 475 476 return val; 477 } 478 479 static u32 lpt_get_backlight(struct intel_connector *connector) 480 { 481 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 482 483 return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; 484 } 485 486 static u32 pch_get_backlight(struct intel_connector *connector) 487 { 488 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 489 490 return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; 491 } 492 493 static u32 i9xx_get_backlight(struct intel_connector *connector) 494 { 495 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 496 struct intel_panel *panel = &connector->panel; 497 u32 val; 498 499 val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; 500 if (INTEL_INFO(dev_priv)->gen < 4) 501 val >>= 1; 502 503 if (panel->backlight.combination_mode) { 504 u8 lbpc; 505 506 pci_read_config_byte(dev_priv->dev->pdev, LBPC, &lbpc); 507 val *= lbpc; 508 } 509 510 return val; 511 } 512 513 static u32 _vlv_get_backlight(struct drm_i915_private *dev_priv, enum i915_pipe pipe) 514 { 515 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 516 return 0; 517 518 return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; 519 } 520 521 static u32 vlv_get_backlight(struct intel_connector *connector) 522 { 523 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 524 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 525 526 return _vlv_get_backlight(dev_priv, pipe); 527 } 528 529 static u32 bxt_get_backlight(struct intel_connector *connector) 530 { 531 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 532 struct intel_panel *panel = &connector->panel; 533 534 return I915_READ(BXT_BLC_PWM_DUTY(panel->backlight.controller)); 535 } 536 537 static u32 pwm_get_backlight(struct intel_connector *connector) 538 { 539 struct intel_panel *panel = &connector->panel; 540 int duty_ns; 541 542 duty_ns = pwm_get_duty_cycle(panel->backlight.pwm); 543 return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS); 544 } 545 546 #if 0 547 static u32 intel_panel_get_backlight(struct intel_connector *connector) 548 { 549 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 550 struct intel_panel *panel = &connector->panel; 551 u32 val = 0; 552 553 mutex_lock(&dev_priv->backlight_lock); 554 555 if (panel->backlight.enabled) { 556 val = panel->backlight.get(connector); 557 val = intel_panel_compute_brightness(connector, val); 558 } 559 560 mutex_unlock(&dev_priv->backlight_lock); 561 562 DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); 563 return val; 564 } 565 #endif 566 567 static void lpt_set_backlight(struct intel_connector *connector, u32 level) 568 { 569 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 570 u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; 571 I915_WRITE(BLC_PWM_PCH_CTL2, val | level); 572 } 573 574 static void pch_set_backlight(struct intel_connector *connector, u32 level) 575 { 576 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 577 u32 tmp; 578 579 tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; 580 I915_WRITE(BLC_PWM_CPU_CTL, tmp | level); 581 } 582 583 static void i9xx_set_backlight(struct intel_connector *connector, u32 level) 584 { 585 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 586 struct intel_panel *panel = &connector->panel; 587 u32 tmp, mask; 588 589 WARN_ON(panel->backlight.max == 0); 590 591 if (panel->backlight.combination_mode) { 592 u8 lbpc; 593 594 lbpc = level * 0xfe / panel->backlight.max + 1; 595 level /= lbpc; 596 pci_write_config_byte(dev_priv->dev->pdev, LBPC, lbpc); 597 } 598 599 if (IS_GEN4(dev_priv)) { 600 mask = BACKLIGHT_DUTY_CYCLE_MASK; 601 } else { 602 level <<= 1; 603 mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV; 604 } 605 606 tmp = I915_READ(BLC_PWM_CTL) & ~mask; 607 I915_WRITE(BLC_PWM_CTL, tmp | level); 608 } 609 610 static void vlv_set_backlight(struct intel_connector *connector, u32 level) 611 { 612 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 613 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 614 u32 tmp; 615 616 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 617 return; 618 619 tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; 620 I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level); 621 } 622 623 static void bxt_set_backlight(struct intel_connector *connector, u32 level) 624 { 625 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 626 struct intel_panel *panel = &connector->panel; 627 628 I915_WRITE(BXT_BLC_PWM_DUTY(panel->backlight.controller), level); 629 } 630 631 static void pwm_set_backlight(struct intel_connector *connector, u32 level) 632 { 633 struct intel_panel *panel = &connector->panel; 634 int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100); 635 636 pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS); 637 } 638 639 static void 640 intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) 641 { 642 struct intel_panel *panel = &connector->panel; 643 644 DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); 645 646 level = intel_panel_compute_brightness(connector, level); 647 panel->backlight.set(connector, level); 648 } 649 650 /* set backlight brightness to level in range [0..max], scaling wrt hw min */ 651 static void intel_panel_set_backlight(struct intel_connector *connector, 652 u32 user_level, u32 user_max) 653 { 654 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 655 struct intel_panel *panel = &connector->panel; 656 u32 hw_level; 657 658 if (!panel->backlight.present) 659 return; 660 661 mutex_lock(&dev_priv->backlight_lock); 662 663 WARN_ON(panel->backlight.max == 0); 664 665 hw_level = scale_user_to_hw(connector, user_level, user_max); 666 panel->backlight.level = hw_level; 667 668 if (panel->backlight.enabled) 669 intel_panel_actually_set_backlight(connector, hw_level); 670 671 mutex_unlock(&dev_priv->backlight_lock); 672 } 673 674 /* set backlight brightness to level in range [0..max], assuming hw min is 675 * respected. 676 */ 677 void intel_panel_set_backlight_acpi(struct intel_connector *connector, 678 u32 user_level, u32 user_max) 679 { 680 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 681 struct intel_panel *panel = &connector->panel; 682 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 683 u32 hw_level; 684 685 /* 686 * INVALID_PIPE may occur during driver init because 687 * connection_mutex isn't held across the entire backlight 688 * setup + modeset readout, and the BIOS can issue the 689 * requests at any time. 690 */ 691 if (!panel->backlight.present || pipe == INVALID_PIPE) 692 return; 693 694 mutex_lock(&dev_priv->backlight_lock); 695 696 WARN_ON(panel->backlight.max == 0); 697 698 hw_level = clamp_user_to_hw(connector, user_level, user_max); 699 panel->backlight.level = hw_level; 700 701 if (panel->backlight.device) 702 panel->backlight.device->props.brightness = 703 scale_hw_to_user(connector, 704 panel->backlight.level, 705 panel->backlight.device->props.max_brightness); 706 707 if (panel->backlight.enabled) 708 intel_panel_actually_set_backlight(connector, hw_level); 709 710 mutex_unlock(&dev_priv->backlight_lock); 711 } 712 713 static void lpt_disable_backlight(struct intel_connector *connector) 714 { 715 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 716 u32 tmp; 717 718 intel_panel_actually_set_backlight(connector, 0); 719 720 /* 721 * Although we don't support or enable CPU PWM with LPT/SPT based 722 * systems, it may have been enabled prior to loading the 723 * driver. Disable to avoid warnings on LCPLL disable. 724 * 725 * This needs rework if we need to add support for CPU PWM on PCH split 726 * platforms. 727 */ 728 tmp = I915_READ(BLC_PWM_CPU_CTL2); 729 if (tmp & BLM_PWM_ENABLE) { 730 DRM_DEBUG_KMS("cpu backlight was enabled, disabling\n"); 731 I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); 732 } 733 734 tmp = I915_READ(BLC_PWM_PCH_CTL1); 735 I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); 736 } 737 738 static void pch_disable_backlight(struct intel_connector *connector) 739 { 740 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 741 u32 tmp; 742 743 intel_panel_actually_set_backlight(connector, 0); 744 745 tmp = I915_READ(BLC_PWM_CPU_CTL2); 746 I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); 747 748 tmp = I915_READ(BLC_PWM_PCH_CTL1); 749 I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); 750 } 751 752 static void i9xx_disable_backlight(struct intel_connector *connector) 753 { 754 intel_panel_actually_set_backlight(connector, 0); 755 } 756 757 static void i965_disable_backlight(struct intel_connector *connector) 758 { 759 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 760 u32 tmp; 761 762 intel_panel_actually_set_backlight(connector, 0); 763 764 tmp = I915_READ(BLC_PWM_CTL2); 765 I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); 766 } 767 768 static void vlv_disable_backlight(struct intel_connector *connector) 769 { 770 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 771 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 772 u32 tmp; 773 774 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 775 return; 776 777 intel_panel_actually_set_backlight(connector, 0); 778 779 tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe)); 780 I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE); 781 } 782 783 static void bxt_disable_backlight(struct intel_connector *connector) 784 { 785 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 786 struct intel_panel *panel = &connector->panel; 787 u32 tmp, val; 788 789 intel_panel_actually_set_backlight(connector, 0); 790 791 tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); 792 I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), 793 tmp & ~BXT_BLC_PWM_ENABLE); 794 795 if (panel->backlight.controller == 1) { 796 val = I915_READ(UTIL_PIN_CTL); 797 val &= ~UTIL_PIN_ENABLE; 798 I915_WRITE(UTIL_PIN_CTL, val); 799 } 800 } 801 802 static void pwm_disable_backlight(struct intel_connector *connector) 803 { 804 struct intel_panel *panel = &connector->panel; 805 806 /* Disable the backlight */ 807 pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS); 808 usleep_range(2000, 3000); 809 pwm_disable(panel->backlight.pwm); 810 } 811 812 void intel_panel_disable_backlight(struct intel_connector *connector) 813 { 814 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 815 struct intel_panel *panel = &connector->panel; 816 817 if (!panel->backlight.present) 818 return; 819 820 /* 821 * Do not disable backlight on the vga_switcheroo path. When switching 822 * away from i915, the other client may depend on i915 to handle the 823 * backlight. This will leave the backlight on unnecessarily when 824 * another client is not activated. 825 */ 826 if (dev_priv->dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) { 827 DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n"); 828 return; 829 } 830 831 mutex_lock(&dev_priv->backlight_lock); 832 833 if (panel->backlight.device) 834 panel->backlight.device->props.power = FB_BLANK_POWERDOWN; 835 panel->backlight.enabled = false; 836 panel->backlight.disable(connector); 837 838 mutex_unlock(&dev_priv->backlight_lock); 839 } 840 841 static void lpt_enable_backlight(struct intel_connector *connector) 842 { 843 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 844 struct intel_panel *panel = &connector->panel; 845 u32 pch_ctl1, pch_ctl2; 846 847 pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); 848 if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { 849 DRM_DEBUG_KMS("pch backlight already enabled\n"); 850 pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; 851 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); 852 } 853 854 pch_ctl2 = panel->backlight.max << 16; 855 I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); 856 857 pch_ctl1 = 0; 858 if (panel->backlight.active_low_pwm) 859 pch_ctl1 |= BLM_PCH_POLARITY; 860 861 /* After LPT, override is the default. */ 862 if (HAS_PCH_LPT(dev_priv)) 863 pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; 864 865 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); 866 POSTING_READ(BLC_PWM_PCH_CTL1); 867 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); 868 869 /* This won't stick until the above enable. */ 870 intel_panel_actually_set_backlight(connector, panel->backlight.level); 871 } 872 873 static void pch_enable_backlight(struct intel_connector *connector) 874 { 875 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 876 struct intel_panel *panel = &connector->panel; 877 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 878 enum transcoder cpu_transcoder = 879 intel_pipe_to_cpu_transcoder(dev_priv, pipe); 880 u32 cpu_ctl2, pch_ctl1, pch_ctl2; 881 882 cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); 883 if (cpu_ctl2 & BLM_PWM_ENABLE) { 884 DRM_DEBUG_KMS("cpu backlight already enabled\n"); 885 cpu_ctl2 &= ~BLM_PWM_ENABLE; 886 I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); 887 } 888 889 pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); 890 if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { 891 DRM_DEBUG_KMS("pch backlight already enabled\n"); 892 pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; 893 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); 894 } 895 896 if (cpu_transcoder == TRANSCODER_EDP) 897 cpu_ctl2 = BLM_TRANSCODER_EDP; 898 else 899 cpu_ctl2 = BLM_PIPE(cpu_transcoder); 900 I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); 901 POSTING_READ(BLC_PWM_CPU_CTL2); 902 I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); 903 904 /* This won't stick until the above enable. */ 905 intel_panel_actually_set_backlight(connector, panel->backlight.level); 906 907 pch_ctl2 = panel->backlight.max << 16; 908 I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); 909 910 pch_ctl1 = 0; 911 if (panel->backlight.active_low_pwm) 912 pch_ctl1 |= BLM_PCH_POLARITY; 913 914 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); 915 POSTING_READ(BLC_PWM_PCH_CTL1); 916 I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); 917 } 918 919 static void i9xx_enable_backlight(struct intel_connector *connector) 920 { 921 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 922 struct intel_panel *panel = &connector->panel; 923 u32 ctl, freq; 924 925 ctl = I915_READ(BLC_PWM_CTL); 926 if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { 927 DRM_DEBUG_KMS("backlight already enabled\n"); 928 I915_WRITE(BLC_PWM_CTL, 0); 929 } 930 931 freq = panel->backlight.max; 932 if (panel->backlight.combination_mode) 933 freq /= 0xff; 934 935 ctl = freq << 17; 936 if (panel->backlight.combination_mode) 937 ctl |= BLM_LEGACY_MODE; 938 if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm) 939 ctl |= BLM_POLARITY_PNV; 940 941 I915_WRITE(BLC_PWM_CTL, ctl); 942 POSTING_READ(BLC_PWM_CTL); 943 944 /* XXX: combine this into above write? */ 945 intel_panel_actually_set_backlight(connector, panel->backlight.level); 946 947 /* 948 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is 949 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2 950 * that has backlight. 951 */ 952 if (IS_GEN2(dev_priv)) 953 I915_WRITE(BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE); 954 } 955 956 static void i965_enable_backlight(struct intel_connector *connector) 957 { 958 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 959 struct intel_panel *panel = &connector->panel; 960 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 961 u32 ctl, ctl2, freq; 962 963 ctl2 = I915_READ(BLC_PWM_CTL2); 964 if (ctl2 & BLM_PWM_ENABLE) { 965 DRM_DEBUG_KMS("backlight already enabled\n"); 966 ctl2 &= ~BLM_PWM_ENABLE; 967 I915_WRITE(BLC_PWM_CTL2, ctl2); 968 } 969 970 freq = panel->backlight.max; 971 if (panel->backlight.combination_mode) 972 freq /= 0xff; 973 974 ctl = freq << 16; 975 I915_WRITE(BLC_PWM_CTL, ctl); 976 977 ctl2 = BLM_PIPE(pipe); 978 if (panel->backlight.combination_mode) 979 ctl2 |= BLM_COMBINATION_MODE; 980 if (panel->backlight.active_low_pwm) 981 ctl2 |= BLM_POLARITY_I965; 982 I915_WRITE(BLC_PWM_CTL2, ctl2); 983 POSTING_READ(BLC_PWM_CTL2); 984 I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); 985 986 intel_panel_actually_set_backlight(connector, panel->backlight.level); 987 } 988 989 static void vlv_enable_backlight(struct intel_connector *connector) 990 { 991 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 992 struct intel_panel *panel = &connector->panel; 993 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 994 u32 ctl, ctl2; 995 996 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 997 return; 998 999 ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); 1000 if (ctl2 & BLM_PWM_ENABLE) { 1001 DRM_DEBUG_KMS("backlight already enabled\n"); 1002 ctl2 &= ~BLM_PWM_ENABLE; 1003 I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); 1004 } 1005 1006 ctl = panel->backlight.max << 16; 1007 I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl); 1008 1009 /* XXX: combine this into above write? */ 1010 intel_panel_actually_set_backlight(connector, panel->backlight.level); 1011 1012 ctl2 = 0; 1013 if (panel->backlight.active_low_pwm) 1014 ctl2 |= BLM_POLARITY_I965; 1015 I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); 1016 POSTING_READ(VLV_BLC_PWM_CTL2(pipe)); 1017 I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE); 1018 } 1019 1020 static void bxt_enable_backlight(struct intel_connector *connector) 1021 { 1022 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1023 struct intel_panel *panel = &connector->panel; 1024 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 1025 u32 pwm_ctl, val; 1026 1027 /* To use 2nd set of backlight registers, utility pin has to be 1028 * enabled with PWM mode. 1029 * The field should only be changed when the utility pin is disabled 1030 */ 1031 if (panel->backlight.controller == 1) { 1032 val = I915_READ(UTIL_PIN_CTL); 1033 if (val & UTIL_PIN_ENABLE) { 1034 DRM_DEBUG_KMS("util pin already enabled\n"); 1035 val &= ~UTIL_PIN_ENABLE; 1036 I915_WRITE(UTIL_PIN_CTL, val); 1037 } 1038 1039 val = 0; 1040 if (panel->backlight.util_pin_active_low) 1041 val |= UTIL_PIN_POLARITY; 1042 I915_WRITE(UTIL_PIN_CTL, val | UTIL_PIN_PIPE(pipe) | 1043 UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE); 1044 } 1045 1046 pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); 1047 if (pwm_ctl & BXT_BLC_PWM_ENABLE) { 1048 DRM_DEBUG_KMS("backlight already enabled\n"); 1049 pwm_ctl &= ~BXT_BLC_PWM_ENABLE; 1050 I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), 1051 pwm_ctl); 1052 } 1053 1054 I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller), 1055 panel->backlight.max); 1056 1057 intel_panel_actually_set_backlight(connector, panel->backlight.level); 1058 1059 pwm_ctl = 0; 1060 if (panel->backlight.active_low_pwm) 1061 pwm_ctl |= BXT_BLC_PWM_POLARITY; 1062 1063 I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl); 1064 POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); 1065 I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), 1066 pwm_ctl | BXT_BLC_PWM_ENABLE); 1067 } 1068 1069 static void pwm_enable_backlight(struct intel_connector *connector) 1070 { 1071 struct intel_panel *panel = &connector->panel; 1072 1073 pwm_enable(panel->backlight.pwm); 1074 intel_panel_actually_set_backlight(connector, panel->backlight.level); 1075 } 1076 1077 void intel_panel_enable_backlight(struct intel_connector *connector) 1078 { 1079 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1080 struct intel_panel *panel = &connector->panel; 1081 enum i915_pipe pipe = intel_get_pipe_from_connector(connector); 1082 1083 if (!panel->backlight.present) 1084 return; 1085 1086 DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); 1087 1088 mutex_lock(&dev_priv->backlight_lock); 1089 1090 WARN_ON(panel->backlight.max == 0); 1091 1092 if (panel->backlight.level <= panel->backlight.min) { 1093 panel->backlight.level = panel->backlight.max; 1094 if (panel->backlight.device) 1095 panel->backlight.device->props.brightness = 1096 scale_hw_to_user(connector, 1097 panel->backlight.level, 1098 panel->backlight.device->props.max_brightness); 1099 } 1100 1101 panel->backlight.enable(connector); 1102 panel->backlight.enabled = true; 1103 if (panel->backlight.device) 1104 panel->backlight.device->props.power = FB_BLANK_UNBLANK; 1105 1106 mutex_unlock(&dev_priv->backlight_lock); 1107 } 1108 1109 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) 1110 #if 0 /* unused */ 1111 static int intel_backlight_device_update_status(struct backlight_device *bd) 1112 { 1113 #if 0 1114 struct intel_connector *connector = bl_get_data(bd); 1115 struct intel_panel *panel = &connector->panel; 1116 struct drm_device *dev = connector->base.dev; 1117 1118 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 1119 DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", 1120 bd->props.brightness, bd->props.max_brightness); 1121 intel_panel_set_backlight(connector, bd->props.brightness, 1122 bd->props.max_brightness); 1123 1124 /* 1125 * Allow flipping bl_power as a sub-state of enabled. Sadly the 1126 * backlight class device does not make it easy to to differentiate 1127 * between callbacks for brightness and bl_power, so our backlight_power 1128 * callback needs to take this into account. 1129 */ 1130 if (panel->backlight.enabled) { 1131 if (panel->backlight.power) { 1132 bool enable = bd->props.power == FB_BLANK_UNBLANK && 1133 bd->props.brightness != 0; 1134 panel->backlight.power(connector, enable); 1135 } 1136 } else { 1137 bd->props.power = FB_BLANK_POWERDOWN; 1138 } 1139 1140 drm_modeset_unlock(&dev->mode_config.connection_mutex); 1141 #endif 1142 return 0; 1143 } 1144 1145 static int intel_backlight_device_get_brightness(struct backlight_device *bd) 1146 { 1147 #if 0 1148 struct intel_connector *connector = bl_get_data(bd); 1149 struct drm_device *dev = connector->base.dev; 1150 struct drm_i915_private *dev_priv = dev->dev_private; 1151 u32 hw_level; 1152 int ret; 1153 1154 intel_runtime_pm_get(dev_priv); 1155 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 1156 1157 hw_level = intel_panel_get_backlight(connector); 1158 ret = scale_hw_to_user(connector, hw_level, bd->props.max_brightness); 1159 1160 drm_modeset_unlock(&dev->mode_config.connection_mutex); 1161 intel_runtime_pm_put(dev_priv); 1162 1163 return ret; 1164 #endif 1165 return 0; 1166 } 1167 1168 static const struct backlight_ops intel_backlight_device_ops = { 1169 .update_status = intel_backlight_device_update_status, 1170 .get_brightness = intel_backlight_device_get_brightness, 1171 }; 1172 #endif 1173 1174 int intel_backlight_device_register(struct intel_connector *connector) 1175 { 1176 struct intel_panel *panel = &connector->panel; 1177 struct backlight_properties props; 1178 1179 if (WARN_ON(panel->backlight.device)) 1180 return -ENODEV; 1181 1182 if (!panel->backlight.present) 1183 return 0; 1184 1185 WARN_ON(panel->backlight.max == 0); 1186 1187 memset(&props, 0, sizeof(props)); 1188 props.type = BACKLIGHT_RAW; 1189 1190 /* 1191 * Note: Everything should work even if the backlight device max 1192 * presented to the userspace is arbitrarily chosen. 1193 */ 1194 props.max_brightness = panel->backlight.max; 1195 props.brightness = scale_hw_to_user(connector, 1196 panel->backlight.level, 1197 props.max_brightness); 1198 1199 if (panel->backlight.enabled) 1200 props.power = FB_BLANK_UNBLANK; 1201 else 1202 props.power = FB_BLANK_POWERDOWN; 1203 1204 /* 1205 * Note: using the same name independent of the connector prevents 1206 * registration of multiple backlight devices in the driver. 1207 */ 1208 #if 0 1209 panel->backlight.device = 1210 backlight_device_register("intel_backlight", 1211 connector->base.kdev, 1212 connector, 1213 &intel_backlight_device_ops, &props); 1214 1215 if (IS_ERR(panel->backlight.device)) { 1216 DRM_ERROR("Failed to register backlight: %ld\n", 1217 PTR_ERR(panel->backlight.device)); 1218 panel->backlight.device = NULL; 1219 return -ENODEV; 1220 } 1221 1222 DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n", 1223 connector->base.name); 1224 #endif 1225 1226 return 0; 1227 } 1228 1229 void intel_backlight_device_unregister(struct intel_connector *connector) 1230 { 1231 #if 0 1232 struct intel_panel *panel = &connector->panel; 1233 1234 if (panel->backlight.device) { 1235 backlight_device_unregister(panel->backlight.device); 1236 panel->backlight.device = NULL; 1237 } 1238 #endif 1239 } 1240 #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ 1241 1242 /* 1243 * BXT: PWM clock frequency = 19.2 MHz. 1244 */ 1245 static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) 1246 { 1247 return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz); 1248 } 1249 1250 /* 1251 * SPT: This value represents the period of the PWM stream in clock periods 1252 * multiplied by 16 (default increment) or 128 (alternate increment selected in 1253 * SCHICKEN_1 bit 0). PWM clock is 24 MHz. 1254 */ 1255 static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) 1256 { 1257 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1258 u32 mul; 1259 1260 if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY) 1261 mul = 128; 1262 else 1263 mul = 16; 1264 1265 return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul); 1266 } 1267 1268 /* 1269 * LPT: This value represents the period of the PWM stream in clock periods 1270 * multiplied by 128 (default increment) or 16 (alternate increment, selected in 1271 * LPT SOUTH_CHICKEN2 register bit 5). 1272 */ 1273 static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) 1274 { 1275 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1276 u32 mul, clock; 1277 1278 if (I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY) 1279 mul = 16; 1280 else 1281 mul = 128; 1282 1283 if (HAS_PCH_LPT_H(dev_priv)) 1284 clock = MHz(135); /* LPT:H */ 1285 else 1286 clock = MHz(24); /* LPT:LP */ 1287 1288 return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); 1289 } 1290 1291 /* 1292 * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH 1293 * display raw clocks multiplied by 128. 1294 */ 1295 static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) 1296 { 1297 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1298 1299 return DIV_ROUND_CLOSEST(KHz(dev_priv->rawclk_freq), pwm_freq_hz * 128); 1300 } 1301 1302 /* 1303 * Gen2: This field determines the number of time base events (display core 1304 * clock frequency/32) in total for a complete cycle of modulated backlight 1305 * control. 1306 * 1307 * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock) 1308 * divided by 32. 1309 */ 1310 static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) 1311 { 1312 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1313 int clock; 1314 1315 if (IS_PINEVIEW(dev_priv)) 1316 clock = KHz(dev_priv->rawclk_freq); 1317 else 1318 clock = KHz(dev_priv->cdclk_freq); 1319 1320 return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32); 1321 } 1322 1323 /* 1324 * Gen4: This value represents the period of the PWM stream in display core 1325 * clocks ([DevCTG] HRAW clocks) multiplied by 128. 1326 * 1327 */ 1328 static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) 1329 { 1330 struct drm_device *dev = connector->base.dev; 1331 struct drm_i915_private *dev_priv = dev->dev_private; 1332 int clock; 1333 1334 if (IS_G4X(dev_priv)) 1335 clock = KHz(dev_priv->rawclk_freq); 1336 else 1337 clock = KHz(dev_priv->cdclk_freq); 1338 1339 return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128); 1340 } 1341 1342 /* 1343 * VLV: This value represents the period of the PWM stream in display core 1344 * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks 1345 * multiplied by 16. CHV uses a 19.2MHz S0IX clock. 1346 */ 1347 static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) 1348 { 1349 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1350 int mul, clock; 1351 1352 if ((I915_READ(CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) { 1353 if (IS_CHERRYVIEW(dev_priv)) 1354 clock = KHz(19200); 1355 else 1356 clock = MHz(25); 1357 mul = 16; 1358 } else { 1359 clock = KHz(dev_priv->rawclk_freq); 1360 mul = 128; 1361 } 1362 1363 return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); 1364 } 1365 1366 static u32 get_backlight_max_vbt(struct intel_connector *connector) 1367 { 1368 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1369 struct intel_panel *panel = &connector->panel; 1370 u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz; 1371 u32 pwm; 1372 1373 if (!panel->backlight.hz_to_pwm) { 1374 DRM_DEBUG_KMS("backlight frequency conversion not supported\n"); 1375 return 0; 1376 } 1377 1378 if (pwm_freq_hz) { 1379 DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", 1380 pwm_freq_hz); 1381 } else { 1382 pwm_freq_hz = 200; 1383 DRM_DEBUG_KMS("default backlight frequency %u Hz\n", 1384 pwm_freq_hz); 1385 } 1386 1387 pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz); 1388 if (!pwm) { 1389 DRM_DEBUG_KMS("backlight frequency conversion failed\n"); 1390 return 0; 1391 } 1392 1393 return pwm; 1394 } 1395 1396 /* 1397 * Note: The setup hooks can't assume pipe is set! 1398 */ 1399 static u32 get_backlight_min_vbt(struct intel_connector *connector) 1400 { 1401 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1402 struct intel_panel *panel = &connector->panel; 1403 int min; 1404 1405 WARN_ON(panel->backlight.max == 0); 1406 1407 /* 1408 * XXX: If the vbt value is 255, it makes min equal to max, which leads 1409 * to problems. There are such machines out there. Either our 1410 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard 1411 * against this by letting the minimum be at most (arbitrarily chosen) 1412 * 25% of the max. 1413 */ 1414 min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64); 1415 if (min != dev_priv->vbt.backlight.min_brightness) { 1416 DRM_DEBUG_KMS("clamping VBT min backlight %d/255 to %d/255\n", 1417 dev_priv->vbt.backlight.min_brightness, min); 1418 } 1419 1420 /* vbt value is a coefficient in range [0..255] */ 1421 return scale(min, 0, 255, 0, panel->backlight.max); 1422 } 1423 1424 static int lpt_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1425 { 1426 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1427 struct intel_panel *panel = &connector->panel; 1428 u32 pch_ctl1, pch_ctl2, val; 1429 1430 pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); 1431 panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; 1432 1433 pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2); 1434 panel->backlight.max = pch_ctl2 >> 16; 1435 1436 if (!panel->backlight.max) 1437 panel->backlight.max = get_backlight_max_vbt(connector); 1438 1439 if (!panel->backlight.max) 1440 return -ENODEV; 1441 1442 panel->backlight.min = get_backlight_min_vbt(connector); 1443 1444 val = lpt_get_backlight(connector); 1445 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1446 1447 panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) && 1448 panel->backlight.level != 0; 1449 1450 return 0; 1451 } 1452 1453 static int pch_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1454 { 1455 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1456 struct intel_panel *panel = &connector->panel; 1457 u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; 1458 1459 pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); 1460 panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; 1461 1462 pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2); 1463 panel->backlight.max = pch_ctl2 >> 16; 1464 1465 if (!panel->backlight.max) 1466 panel->backlight.max = get_backlight_max_vbt(connector); 1467 1468 if (!panel->backlight.max) 1469 return -ENODEV; 1470 1471 panel->backlight.min = get_backlight_min_vbt(connector); 1472 1473 val = pch_get_backlight(connector); 1474 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1475 1476 cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); 1477 panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) && 1478 (pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0; 1479 1480 return 0; 1481 } 1482 1483 static int i9xx_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1484 { 1485 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1486 struct intel_panel *panel = &connector->panel; 1487 u32 ctl, val; 1488 1489 ctl = I915_READ(BLC_PWM_CTL); 1490 1491 if (IS_GEN2(dev_priv) || IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) 1492 panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; 1493 1494 if (IS_PINEVIEW(dev_priv)) 1495 panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV; 1496 1497 panel->backlight.max = ctl >> 17; 1498 1499 if (!panel->backlight.max) { 1500 panel->backlight.max = get_backlight_max_vbt(connector); 1501 panel->backlight.max >>= 1; 1502 } 1503 1504 if (!panel->backlight.max) 1505 return -ENODEV; 1506 1507 if (panel->backlight.combination_mode) 1508 panel->backlight.max *= 0xff; 1509 1510 panel->backlight.min = get_backlight_min_vbt(connector); 1511 1512 val = i9xx_get_backlight(connector); 1513 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1514 1515 panel->backlight.enabled = panel->backlight.level != 0; 1516 1517 return 0; 1518 } 1519 1520 static int i965_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1521 { 1522 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1523 struct intel_panel *panel = &connector->panel; 1524 u32 ctl, ctl2, val; 1525 1526 ctl2 = I915_READ(BLC_PWM_CTL2); 1527 panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE; 1528 panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; 1529 1530 ctl = I915_READ(BLC_PWM_CTL); 1531 panel->backlight.max = ctl >> 16; 1532 1533 if (!panel->backlight.max) 1534 panel->backlight.max = get_backlight_max_vbt(connector); 1535 1536 if (!panel->backlight.max) 1537 return -ENODEV; 1538 1539 if (panel->backlight.combination_mode) 1540 panel->backlight.max *= 0xff; 1541 1542 panel->backlight.min = get_backlight_min_vbt(connector); 1543 1544 val = i9xx_get_backlight(connector); 1545 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1546 1547 panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) && 1548 panel->backlight.level != 0; 1549 1550 return 0; 1551 } 1552 1553 static int vlv_setup_backlight(struct intel_connector *connector, enum i915_pipe pipe) 1554 { 1555 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1556 struct intel_panel *panel = &connector->panel; 1557 u32 ctl, ctl2, val; 1558 1559 if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B)) 1560 return -ENODEV; 1561 1562 ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); 1563 panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; 1564 1565 ctl = I915_READ(VLV_BLC_PWM_CTL(pipe)); 1566 panel->backlight.max = ctl >> 16; 1567 1568 if (!panel->backlight.max) 1569 panel->backlight.max = get_backlight_max_vbt(connector); 1570 1571 if (!panel->backlight.max) 1572 return -ENODEV; 1573 1574 panel->backlight.min = get_backlight_min_vbt(connector); 1575 1576 val = _vlv_get_backlight(dev_priv, pipe); 1577 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1578 1579 panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) && 1580 panel->backlight.level != 0; 1581 1582 return 0; 1583 } 1584 1585 #ifdef __DragonFly__ 1586 /* 1587 * Read max backlight level 1588 */ 1589 static int 1590 sysctl_backlight_max(SYSCTL_HANDLER_ARGS) 1591 { 1592 int err, val; 1593 struct intel_connector *connector = arg1; 1594 struct drm_device *dev = connector->base.dev; 1595 struct drm_i915_private *dev_priv = dev->dev_private; 1596 struct intel_panel *panel = &connector->panel; 1597 1598 mutex_lock(&dev_priv->backlight_lock); 1599 val = panel->backlight.max; 1600 mutex_unlock(&dev_priv->backlight_lock); 1601 1602 err = sysctl_handle_int(oidp, &val, 0, req); 1603 return(err); 1604 } 1605 1606 /* 1607 * Read/write backlight level 1608 */ 1609 static int 1610 sysctl_backlight_handler(SYSCTL_HANDLER_ARGS) 1611 { 1612 struct intel_connector *connector = arg1; 1613 struct drm_device *dev = connector->base.dev; 1614 struct drm_i915_private *dev_priv = dev->dev_private; 1615 struct intel_panel *panel = &connector->panel; 1616 int err, val; 1617 u32 user_level, max_brightness; 1618 1619 mutex_lock(&dev_priv->backlight_lock); 1620 max_brightness = panel->backlight.max; 1621 user_level = scale_hw_to_user(connector, panel->backlight.level, 1622 max_brightness); 1623 mutex_unlock(&dev_priv->backlight_lock); 1624 1625 val = user_level; 1626 err = sysctl_handle_int(oidp, &val, 0, req); 1627 if (err != 0 || req->newptr == NULL) { 1628 return(err); 1629 } 1630 1631 if (val != user_level && val >= 0 && val <= max_brightness) { 1632 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 1633 intel_panel_set_backlight(arg1, val, max_brightness); 1634 drm_modeset_unlock(&dev->mode_config.connection_mutex); 1635 } 1636 1637 return(err); 1638 } 1639 #endif /* __DragonFly__ */ 1640 1641 static int 1642 bxt_setup_backlight(struct intel_connector *connector, enum i915_pipe unused) 1643 { 1644 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1645 struct intel_panel *panel = &connector->panel; 1646 u32 pwm_ctl, val; 1647 1648 /* 1649 * For BXT hard coding the Backlight controller to 0. 1650 * TODO : Read the controller value from VBT and generalize 1651 */ 1652 panel->backlight.controller = 0; 1653 1654 pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller)); 1655 1656 /* Keeping the check if controller 1 is to be programmed. 1657 * This will come into affect once the VBT parsing 1658 * is fixed for controller selection, and controller 1 is used 1659 * for a prticular display configuration. 1660 */ 1661 if (panel->backlight.controller == 1) { 1662 val = I915_READ(UTIL_PIN_CTL); 1663 panel->backlight.util_pin_active_low = 1664 val & UTIL_PIN_POLARITY; 1665 } 1666 1667 panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY; 1668 panel->backlight.max = 1669 I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller)); 1670 1671 if (!panel->backlight.max) 1672 panel->backlight.max = get_backlight_max_vbt(connector); 1673 1674 if (!panel->backlight.max) 1675 return -ENODEV; 1676 1677 val = bxt_get_backlight(connector); 1678 panel->backlight.level = intel_panel_compute_brightness(connector, val); 1679 1680 panel->backlight.enabled = (pwm_ctl & BXT_BLC_PWM_ENABLE) && 1681 panel->backlight.level != 0; 1682 1683 return 0; 1684 } 1685 1686 static int pwm_setup_backlight(struct intel_connector *connector, 1687 enum i915_pipe pipe) 1688 { 1689 struct drm_device *dev = connector->base.dev; 1690 struct intel_panel *panel = &connector->panel; 1691 int retval; 1692 1693 /* Get the PWM chip for backlight control */ 1694 panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight"); 1695 if (IS_ERR(panel->backlight.pwm)) { 1696 DRM_ERROR("Failed to own the pwm chip\n"); 1697 panel->backlight.pwm = NULL; 1698 return -ENODEV; 1699 } 1700 1701 /* 1702 * FIXME: pwm_apply_args() should be removed when switching to 1703 * the atomic PWM API. 1704 */ 1705 #if 0 1706 pwm_apply_args(panel->backlight.pwm); 1707 #endif 1708 1709 retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS, 1710 CRC_PMIC_PWM_PERIOD_NS); 1711 if (retval < 0) { 1712 DRM_ERROR("Failed to configure the pwm chip\n"); 1713 pwm_put(panel->backlight.pwm); 1714 panel->backlight.pwm = NULL; 1715 return retval; 1716 } 1717 1718 panel->backlight.min = 0; /* 0% */ 1719 panel->backlight.max = 100; /* 100% */ 1720 panel->backlight.level = DIV_ROUND_UP( 1721 pwm_get_duty_cycle(panel->backlight.pwm) * 100, 1722 CRC_PMIC_PWM_PERIOD_NS); 1723 panel->backlight.enabled = panel->backlight.level != 0; 1724 1725 return 0; 1726 } 1727 1728 int intel_panel_setup_backlight(struct drm_connector *connector, enum i915_pipe pipe) 1729 { 1730 struct drm_i915_private *dev_priv = to_i915(connector->dev); 1731 struct intel_connector *intel_connector = to_intel_connector(connector); 1732 struct intel_panel *panel = &intel_connector->panel; 1733 int ret; 1734 1735 if (!dev_priv->vbt.backlight.present) { 1736 if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { 1737 DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n"); 1738 } else { 1739 DRM_DEBUG_KMS("no backlight present per VBT\n"); 1740 return 0; 1741 } 1742 } 1743 1744 /* ensure intel_panel has been initialized first */ 1745 if (WARN_ON(!panel->backlight.setup)) 1746 return -ENODEV; 1747 1748 /* set level and max in panel struct */ 1749 mutex_lock(&dev_priv->backlight_lock); 1750 ret = panel->backlight.setup(intel_connector, pipe); 1751 mutex_unlock(&dev_priv->backlight_lock); 1752 1753 if (ret) { 1754 DRM_DEBUG_KMS("failed to setup backlight for connector %s\n", 1755 connector->name); 1756 return ret; 1757 } 1758 1759 panel->backlight.present = true; 1760 1761 #ifdef __DragonFly__ 1762 SYSCTL_ADD_PROC(&connector->dev->sysctl->ctx, &sysctl__hw_children, 1763 OID_AUTO, "backlight_max", 1764 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_ANYBODY, 1765 connector, sizeof(int), 1766 sysctl_backlight_max, 1767 "I", "Max backlight level"); 1768 SYSCTL_ADD_PROC(&connector->dev->sysctl->ctx, &sysctl__hw_children, 1769 OID_AUTO, "backlight_level", 1770 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, 1771 connector, sizeof(int), 1772 sysctl_backlight_handler, 1773 "I", "Backlight level"); 1774 #endif 1775 1776 DRM_DEBUG_KMS("Connector %s backlight initialized, %s, brightness %u/%u\n", 1777 connector->name, 1778 panel->backlight.enabled ? "enabled" : "disabled", 1779 panel->backlight.level, panel->backlight.max); 1780 1781 return 0; 1782 } 1783 1784 void intel_panel_destroy_backlight(struct drm_connector *connector) 1785 { 1786 struct intel_connector *intel_connector = to_intel_connector(connector); 1787 struct intel_panel *panel = &intel_connector->panel; 1788 1789 /* dispose of the pwm */ 1790 if (panel->backlight.pwm) 1791 pwm_put(panel->backlight.pwm); 1792 1793 panel->backlight.present = false; 1794 } 1795 1796 /* Set up chip specific backlight functions */ 1797 static void 1798 intel_panel_init_backlight_funcs(struct intel_panel *panel) 1799 { 1800 struct intel_connector *connector = 1801 container_of(panel, struct intel_connector, panel); 1802 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1803 1804 if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP && 1805 intel_dp_aux_init_backlight_funcs(connector) == 0) 1806 return; 1807 1808 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI && 1809 intel_dsi_dcs_init_backlight_funcs(connector) == 0) 1810 return; 1811 1812 if (IS_BROXTON(dev_priv)) { 1813 panel->backlight.setup = bxt_setup_backlight; 1814 panel->backlight.enable = bxt_enable_backlight; 1815 panel->backlight.disable = bxt_disable_backlight; 1816 panel->backlight.set = bxt_set_backlight; 1817 panel->backlight.get = bxt_get_backlight; 1818 panel->backlight.hz_to_pwm = bxt_hz_to_pwm; 1819 } else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_SPT(dev_priv) || 1820 HAS_PCH_KBP(dev_priv)) { 1821 panel->backlight.setup = lpt_setup_backlight; 1822 panel->backlight.enable = lpt_enable_backlight; 1823 panel->backlight.disable = lpt_disable_backlight; 1824 panel->backlight.set = lpt_set_backlight; 1825 panel->backlight.get = lpt_get_backlight; 1826 if (HAS_PCH_LPT(dev_priv)) 1827 panel->backlight.hz_to_pwm = lpt_hz_to_pwm; 1828 else 1829 panel->backlight.hz_to_pwm = spt_hz_to_pwm; 1830 } else if (HAS_PCH_SPLIT(dev_priv)) { 1831 panel->backlight.setup = pch_setup_backlight; 1832 panel->backlight.enable = pch_enable_backlight; 1833 panel->backlight.disable = pch_disable_backlight; 1834 panel->backlight.set = pch_set_backlight; 1835 panel->backlight.get = pch_get_backlight; 1836 panel->backlight.hz_to_pwm = pch_hz_to_pwm; 1837 } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 1838 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { 1839 panel->backlight.setup = pwm_setup_backlight; 1840 panel->backlight.enable = pwm_enable_backlight; 1841 panel->backlight.disable = pwm_disable_backlight; 1842 panel->backlight.set = pwm_set_backlight; 1843 panel->backlight.get = pwm_get_backlight; 1844 } else { 1845 panel->backlight.setup = vlv_setup_backlight; 1846 panel->backlight.enable = vlv_enable_backlight; 1847 panel->backlight.disable = vlv_disable_backlight; 1848 panel->backlight.set = vlv_set_backlight; 1849 panel->backlight.get = vlv_get_backlight; 1850 panel->backlight.hz_to_pwm = vlv_hz_to_pwm; 1851 } 1852 } else if (IS_GEN4(dev_priv)) { 1853 panel->backlight.setup = i965_setup_backlight; 1854 panel->backlight.enable = i965_enable_backlight; 1855 panel->backlight.disable = i965_disable_backlight; 1856 panel->backlight.set = i9xx_set_backlight; 1857 panel->backlight.get = i9xx_get_backlight; 1858 panel->backlight.hz_to_pwm = i965_hz_to_pwm; 1859 } else { 1860 panel->backlight.setup = i9xx_setup_backlight; 1861 panel->backlight.enable = i9xx_enable_backlight; 1862 panel->backlight.disable = i9xx_disable_backlight; 1863 panel->backlight.set = i9xx_set_backlight; 1864 panel->backlight.get = i9xx_get_backlight; 1865 panel->backlight.hz_to_pwm = i9xx_hz_to_pwm; 1866 } 1867 } 1868 1869 int intel_panel_init(struct intel_panel *panel, 1870 struct drm_display_mode *fixed_mode, 1871 struct drm_display_mode *downclock_mode) 1872 { 1873 intel_panel_init_backlight_funcs(panel); 1874 1875 panel->fixed_mode = fixed_mode; 1876 panel->downclock_mode = downclock_mode; 1877 1878 return 0; 1879 } 1880 1881 void intel_panel_fini(struct intel_panel *panel) 1882 { 1883 struct intel_connector *intel_connector = 1884 container_of(panel, struct intel_connector, panel); 1885 1886 if (panel->fixed_mode) 1887 drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); 1888 1889 if (panel->downclock_mode) 1890 drm_mode_destroy(intel_connector->base.dev, 1891 panel->downclock_mode); 1892 } 1893