Linux Audio

Check our new training course

Loading...
v5.4
   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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  32
  33#include <linux/kernel.h>
  34#include <linux/moduleparam.h>
  35#include <linux/pwm.h>
  36
 
 
 
 
  37#include "intel_connector.h"
 
  38#include "intel_display_types.h"
  39#include "intel_dp_aux_backlight.h"
  40#include "intel_dsi_dcs_backlight.h"
  41#include "intel_panel.h"
 
 
  42
  43#define CRC_PMIC_PWM_PERIOD_NS	21333
 
 
 
 
 
 
  44
  45void
  46intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
  47		       struct drm_display_mode *adjusted_mode)
  48{
  49	drm_mode_copy(adjusted_mode, fixed_mode);
 
 
  50
  51	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  52}
  53
  54static bool is_downclock_mode(const struct drm_display_mode *downclock_mode,
  55			      const struct drm_display_mode *fixed_mode)
 
  56{
  57	return drm_mode_match(downclock_mode, fixed_mode,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  58			      DRM_MODE_MATCH_TIMINGS |
  59			      DRM_MODE_MATCH_FLAGS |
  60			      DRM_MODE_MATCH_3D_FLAGS) &&
  61		downclock_mode->clock < fixed_mode->clock;
  62}
  63
  64struct drm_display_mode *
  65intel_panel_edid_downclock_mode(struct intel_connector *connector,
  66				const struct drm_display_mode *fixed_mode)
  67{
  68	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
  69	const struct drm_display_mode *scan, *best_mode = NULL;
  70	struct drm_display_mode *downclock_mode;
  71	int best_clock = fixed_mode->clock;
  72
  73	list_for_each_entry(scan, &connector->base.probed_modes, head) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  74		/*
  75		 * If one mode has the same resolution with the fixed_panel
  76		 * mode while they have the different refresh rate, it means
  77		 * that the reduced downclock is found. In such
  78		 * case we can set the different FPx0/1 to dynamically select
  79		 * between low and high frequency.
  80		 */
  81		if (is_downclock_mode(scan, fixed_mode) &&
  82		    scan->clock < best_clock) {
  83			/*
  84			 * The downclock is already found. But we
  85			 * expect to find the lower downclock.
  86			 */
  87			best_clock = scan->clock;
  88			best_mode = scan;
  89		}
  90	}
  91
  92	if (!best_mode)
  93		return NULL;
  94
  95	downclock_mode = drm_mode_duplicate(&dev_priv->drm, best_mode);
  96	if (!downclock_mode)
  97		return NULL;
 
  98
  99	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] using downclock mode from EDID: ",
 100		      connector->base.base.id, connector->base.name);
 101	drm_mode_debug_printmodeline(downclock_mode);
 102
 103	return downclock_mode;
 104}
 105
 106struct drm_display_mode *
 107intel_panel_edid_fixed_mode(struct intel_connector *connector)
 108{
 109	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 110	const struct drm_display_mode *scan;
 111	struct drm_display_mode *fixed_mode;
 112
 113	if (list_empty(&connector->base.probed_modes))
 114		return NULL;
 115
 116	/* prefer fixed mode from EDID if available */
 117	list_for_each_entry(scan, &connector->base.probed_modes, head) {
 118		if ((scan->type & DRM_MODE_TYPE_PREFERRED) == 0)
 119			continue;
 120
 121		fixed_mode = drm_mode_duplicate(&dev_priv->drm, scan);
 122		if (!fixed_mode)
 123			return NULL;
 124
 125		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] using preferred mode from EDID: ",
 126			      connector->base.base.id, connector->base.name);
 127		drm_mode_debug_printmodeline(fixed_mode);
 128
 129		return fixed_mode;
 130	}
 
 
 
 
 
 
 131
 132	scan = list_first_entry(&connector->base.probed_modes,
 133				typeof(*scan), head);
 
 
 
 
 
 
 
 
 134
 135	fixed_mode = drm_mode_duplicate(&dev_priv->drm, scan);
 136	if (!fixed_mode)
 137		return NULL;
 
 
 
 
 
 
 
 138
 139	fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
 140
 141	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] using first mode from EDID: ",
 142		      connector->base.base.id, connector->base.name);
 143	drm_mode_debug_printmodeline(fixed_mode);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 144
 145	return fixed_mode;
 
 
 
 
 
 
 146}
 147
 148struct drm_display_mode *
 149intel_panel_vbt_fixed_mode(struct intel_connector *connector)
 
 150{
 151	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 152	struct drm_display_info *info = &connector->base.display_info;
 153	struct drm_display_mode *fixed_mode;
 154
 155	if (!dev_priv->vbt.lfp_lvds_vbt_mode)
 156		return NULL;
 157
 158	fixed_mode = drm_mode_duplicate(&dev_priv->drm,
 159					dev_priv->vbt.lfp_lvds_vbt_mode);
 160	if (!fixed_mode)
 161		return NULL;
 162
 163	fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
 164
 165	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] using mode from VBT: ",
 166		      connector->base.base.id, connector->base.name);
 167	drm_mode_debug_printmodeline(fixed_mode);
 168
 169	info->width_mm = fixed_mode->width_mm;
 170	info->height_mm = fixed_mode->height_mm;
 171
 172	return fixed_mode;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 173}
 174
 175/* adjusted_mode has been preset to be the panel's fixed mode */
 176void
 177intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
 178			struct intel_crtc_state *pipe_config,
 179			int fitting_mode)
 180{
 181	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 182	int x = 0, y = 0, width = 0, height = 0;
 
 
 
 183
 184	/* Native modes don't need fitting */
 185	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
 186	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h &&
 187	    pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR420)
 188		goto done;
 189
 190	switch (fitting_mode) {
 191	case DRM_MODE_SCALE_CENTER:
 192		width = pipe_config->pipe_src_w;
 193		height = pipe_config->pipe_src_h;
 194		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
 195		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
 196		break;
 197
 198	case DRM_MODE_SCALE_ASPECT:
 199		/* Scale but preserve the aspect ratio */
 200		{
 201			u32 scaled_width = adjusted_mode->crtc_hdisplay
 202				* pipe_config->pipe_src_h;
 203			u32 scaled_height = pipe_config->pipe_src_w
 204				* adjusted_mode->crtc_vdisplay;
 205			if (scaled_width > scaled_height) { /* pillar */
 206				width = scaled_height / pipe_config->pipe_src_h;
 207				if (width & 1)
 208					width++;
 209				x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
 210				y = 0;
 211				height = adjusted_mode->crtc_vdisplay;
 212			} else if (scaled_width < scaled_height) { /* letter */
 213				height = scaled_width / pipe_config->pipe_src_w;
 214				if (height & 1)
 215				    height++;
 216				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
 217				x = 0;
 218				width = adjusted_mode->crtc_hdisplay;
 219			} else {
 220				x = y = 0;
 221				width = adjusted_mode->crtc_hdisplay;
 222				height = adjusted_mode->crtc_vdisplay;
 223			}
 224		}
 225		break;
 226
 
 
 
 
 227	case DRM_MODE_SCALE_FULLSCREEN:
 228		x = y = 0;
 229		width = adjusted_mode->crtc_hdisplay;
 230		height = adjusted_mode->crtc_vdisplay;
 231		break;
 232
 233	default:
 234		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
 235		return;
 236	}
 237
 238done:
 239	pipe_config->pch_pfit.pos = (x << 16) | y;
 240	pipe_config->pch_pfit.size = (width << 16) | height;
 241	pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
 
 242}
 243
 244static void
 245centre_horizontally(struct drm_display_mode *adjusted_mode,
 246		    int width)
 247{
 248	u32 border, sync_pos, blank_width, sync_width;
 249
 250	/* keep the hsync and hblank widths constant */
 251	sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
 252	blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
 253	sync_pos = (blank_width - sync_width + 1) / 2;
 254
 255	border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
 256	border += border & 1; /* make the border even */
 257
 258	adjusted_mode->crtc_hdisplay = width;
 259	adjusted_mode->crtc_hblank_start = width + border;
 260	adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
 261
 262	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
 263	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
 264}
 265
 266static void
 267centre_vertically(struct drm_display_mode *adjusted_mode,
 268		  int height)
 269{
 270	u32 border, sync_pos, blank_width, sync_width;
 271
 272	/* keep the vsync and vblank widths constant */
 273	sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
 274	blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
 275	sync_pos = (blank_width - sync_width + 1) / 2;
 276
 277	border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
 278
 279	adjusted_mode->crtc_vdisplay = height;
 280	adjusted_mode->crtc_vblank_start = height + border;
 281	adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;
 282
 283	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
 284	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
 285}
 286
 287static inline u32 panel_fitter_scaling(u32 source, u32 target)
 288{
 289	/*
 290	 * Floating point operation is not supported. So the FACTOR
 291	 * is defined, which can avoid the floating point computation
 292	 * when calculating the panel ratio.
 293	 */
 294#define ACCURACY 12
 295#define FACTOR (1 << ACCURACY)
 296	u32 ratio = source * FACTOR / target;
 297	return (FACTOR * ratio + FACTOR/2) / FACTOR;
 298}
 299
 300static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
 301			      u32 *pfit_control)
 302{
 303	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 304	u32 scaled_width = adjusted_mode->crtc_hdisplay *
 305		pipe_config->pipe_src_h;
 306	u32 scaled_height = pipe_config->pipe_src_w *
 307		adjusted_mode->crtc_vdisplay;
 
 308
 309	/* 965+ is easy, it does everything in hw */
 310	if (scaled_width > scaled_height)
 311		*pfit_control |= PFIT_ENABLE |
 312			PFIT_SCALING_PILLAR;
 313	else if (scaled_width < scaled_height)
 314		*pfit_control |= PFIT_ENABLE |
 315			PFIT_SCALING_LETTER;
 316	else if (adjusted_mode->crtc_hdisplay != pipe_config->pipe_src_w)
 317		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
 318}
 319
 320static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
 321			      u32 *pfit_control, u32 *pfit_pgm_ratios,
 322			      u32 *border)
 323{
 324	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 325	u32 scaled_width = adjusted_mode->crtc_hdisplay *
 326		pipe_config->pipe_src_h;
 327	u32 scaled_height = pipe_config->pipe_src_w *
 328		adjusted_mode->crtc_vdisplay;
 329	u32 bits;
 330
 331	/*
 332	 * For earlier chips we have to calculate the scaling
 333	 * ratio by hand and program it into the
 334	 * PFIT_PGM_RATIO register
 335	 */
 336	if (scaled_width > scaled_height) { /* pillar */
 337		centre_horizontally(adjusted_mode,
 338				    scaled_height /
 339				    pipe_config->pipe_src_h);
 340
 341		*border = LVDS_BORDER_ENABLE;
 342		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay) {
 343			bits = panel_fitter_scaling(pipe_config->pipe_src_h,
 344						    adjusted_mode->crtc_vdisplay);
 345
 346			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
 347					     bits << PFIT_VERT_SCALE_SHIFT);
 348			*pfit_control |= (PFIT_ENABLE |
 349					  VERT_INTERP_BILINEAR |
 350					  HORIZ_INTERP_BILINEAR);
 351		}
 352	} else if (scaled_width < scaled_height) { /* letter */
 353		centre_vertically(adjusted_mode,
 354				  scaled_width /
 355				  pipe_config->pipe_src_w);
 356
 357		*border = LVDS_BORDER_ENABLE;
 358		if (pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
 359			bits = panel_fitter_scaling(pipe_config->pipe_src_w,
 360						    adjusted_mode->crtc_hdisplay);
 361
 362			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
 363					     bits << PFIT_VERT_SCALE_SHIFT);
 364			*pfit_control |= (PFIT_ENABLE |
 365					  VERT_INTERP_BILINEAR |
 366					  HORIZ_INTERP_BILINEAR);
 367		}
 368	} else {
 369		/* Aspects match, Let hw scale both directions */
 370		*pfit_control |= (PFIT_ENABLE |
 371				  VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
 372				  VERT_INTERP_BILINEAR |
 373				  HORIZ_INTERP_BILINEAR);
 
 374	}
 375}
 376
 377void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
 378			      struct intel_crtc_state *pipe_config,
 379			      int fitting_mode)
 380{
 381	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
 
 382	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
 383	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 
 
 384
 385	/* Native modes don't need fitting */
 386	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
 387	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
 388		goto out;
 389
 390	switch (fitting_mode) {
 391	case DRM_MODE_SCALE_CENTER:
 392		/*
 393		 * For centered modes, we have to calculate border widths &
 394		 * heights and modify the values programmed into the CRTC.
 395		 */
 396		centre_horizontally(adjusted_mode, pipe_config->pipe_src_w);
 397		centre_vertically(adjusted_mode, pipe_config->pipe_src_h);
 398		border = LVDS_BORDER_ENABLE;
 399		break;
 400	case DRM_MODE_SCALE_ASPECT:
 401		/* Scale but preserve the aspect ratio */
 402		if (INTEL_GEN(dev_priv) >= 4)
 403			i965_scale_aspect(pipe_config, &pfit_control);
 404		else
 405			i9xx_scale_aspect(pipe_config, &pfit_control,
 406					  &pfit_pgm_ratios, &border);
 407		break;
 408	case DRM_MODE_SCALE_FULLSCREEN:
 409		/*
 410		 * Full scaling, even if it changes the aspect ratio.
 411		 * Fortunately this is all done for us in hw.
 412		 */
 413		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay ||
 414		    pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
 415			pfit_control |= PFIT_ENABLE;
 416			if (INTEL_GEN(dev_priv) >= 4)
 417				pfit_control |= PFIT_SCALING_AUTO;
 418			else
 419				pfit_control |= (VERT_AUTO_SCALE |
 420						 VERT_INTERP_BILINEAR |
 421						 HORIZ_AUTO_SCALE |
 422						 HORIZ_INTERP_BILINEAR);
 423		}
 424		break;
 425	default:
 426		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
 427		return;
 428	}
 429
 430	/* 965+ wants fuzzy fitting */
 431	/* FIXME: handle multiple panels by failing gracefully */
 432	if (INTEL_GEN(dev_priv) >= 4)
 433		pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
 434				 PFIT_FILTER_FUZZY);
 435
 436out:
 437	if ((pfit_control & PFIT_ENABLE) == 0) {
 438		pfit_control = 0;
 439		pfit_pgm_ratios = 0;
 440	}
 441
 442	/* Make sure pre-965 set dither correctly for 18bpp panels. */
 443	if (INTEL_GEN(dev_priv) < 4 && pipe_config->pipe_bpp == 18)
 444		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
 445
 446	pipe_config->gmch_pfit.control = pfit_control;
 447	pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
 448	pipe_config->gmch_pfit.lvds_border_bits = border;
 449}
 450
 451/**
 452 * scale - scale values from one range to another
 453 * @source_val: value in range [@source_min..@source_max]
 454 * @source_min: minimum legal value for @source_val
 455 * @source_max: maximum legal value for @source_val
 456 * @target_min: corresponding target value for @source_min
 457 * @target_max: corresponding target value for @source_max
 458 *
 459 * Return @source_val in range [@source_min..@source_max] scaled to range
 460 * [@target_min..@target_max].
 461 */
 462static u32 scale(u32 source_val,
 463		 u32 source_min, u32 source_max,
 464		 u32 target_min, u32 target_max)
 465{
 466	u64 target_val;
 467
 468	WARN_ON(source_min > source_max);
 469	WARN_ON(target_min > target_max);
 470
 471	/* defensive */
 472	source_val = clamp(source_val, source_min, source_max);
 473
 474	/* avoid overflows */
 475	target_val = mul_u32_u32(source_val - source_min,
 476				 target_max - target_min);
 477	target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min);
 478	target_val += target_min;
 479
 480	return target_val;
 481}
 482
 483/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
 484static inline u32 scale_user_to_hw(struct intel_connector *connector,
 485				   u32 user_level, u32 user_max)
 486{
 487	struct intel_panel *panel = &connector->panel;
 488
 489	return scale(user_level, 0, user_max,
 490		     panel->backlight.min, panel->backlight.max);
 491}
 492
 493/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
 494 * to [hw_min..hw_max]. */
 495static inline u32 clamp_user_to_hw(struct intel_connector *connector,
 496				   u32 user_level, u32 user_max)
 497{
 498	struct intel_panel *panel = &connector->panel;
 499	u32 hw_level;
 500
 501	hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
 502	hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
 503
 504	return hw_level;
 505}
 506
 507/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
 508static inline u32 scale_hw_to_user(struct intel_connector *connector,
 509				   u32 hw_level, u32 user_max)
 510{
 511	struct intel_panel *panel = &connector->panel;
 512
 513	return scale(hw_level, panel->backlight.min, panel->backlight.max,
 514		     0, user_max);
 515}
 516
 517static u32 intel_panel_compute_brightness(struct intel_connector *connector,
 518					  u32 val)
 519{
 520	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 521	struct intel_panel *panel = &connector->panel;
 522
 523	WARN_ON(panel->backlight.max == 0);
 524
 525	if (i915_modparams.invert_brightness < 0)
 526		return val;
 527
 528	if (i915_modparams.invert_brightness > 0 ||
 529	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
 530		return panel->backlight.max - val + panel->backlight.min;
 531	}
 532
 533	return val;
 534}
 535
 536static u32 lpt_get_backlight(struct intel_connector *connector)
 537{
 538	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 539
 540	return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
 541}
 542
 543static u32 pch_get_backlight(struct intel_connector *connector)
 544{
 545	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 546
 547	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
 548}
 549
 550static u32 i9xx_get_backlight(struct intel_connector *connector)
 551{
 552	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 553	struct intel_panel *panel = &connector->panel;
 554	u32 val;
 555
 556	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
 557	if (INTEL_GEN(dev_priv) < 4)
 558		val >>= 1;
 559
 560	if (panel->backlight.combination_mode) {
 561		u8 lbpc;
 562
 563		pci_read_config_byte(dev_priv->drm.pdev, LBPC, &lbpc);
 564		val *= lbpc;
 565	}
 566
 567	return val;
 568}
 569
 570static u32 _vlv_get_backlight(struct drm_i915_private *dev_priv, enum pipe pipe)
 571{
 572	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
 573		return 0;
 574
 575	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
 576}
 577
 578static u32 vlv_get_backlight(struct intel_connector *connector)
 579{
 580	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 581	enum pipe pipe = intel_connector_get_pipe(connector);
 582
 583	return _vlv_get_backlight(dev_priv, pipe);
 584}
 585
 586static u32 bxt_get_backlight(struct intel_connector *connector)
 587{
 588	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 589	struct intel_panel *panel = &connector->panel;
 590
 591	return I915_READ(BXT_BLC_PWM_DUTY(panel->backlight.controller));
 592}
 593
 594static u32 pwm_get_backlight(struct intel_connector *connector)
 595{
 596	struct intel_panel *panel = &connector->panel;
 597	int duty_ns;
 598
 599	duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
 600	return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
 601}
 602
 603static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
 604{
 605	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 606	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 607
 608	u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
 609	I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
 610}
 611
 612static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level)
 613{
 614	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 615	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 616	u32 tmp;
 617
 618	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
 619	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
 620}
 621
 622static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level)
 623{
 624	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 625	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 626	struct intel_panel *panel = &connector->panel;
 627	u32 tmp, mask;
 628
 629	WARN_ON(panel->backlight.max == 0);
 630
 631	if (panel->backlight.combination_mode) {
 632		u8 lbpc;
 633
 634		lbpc = level * 0xfe / panel->backlight.max + 1;
 635		level /= lbpc;
 636		pci_write_config_byte(dev_priv->drm.pdev, LBPC, lbpc);
 637	}
 638
 639	if (IS_GEN(dev_priv, 4)) {
 640		mask = BACKLIGHT_DUTY_CYCLE_MASK;
 641	} else {
 642		level <<= 1;
 643		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
 644	}
 645
 646	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
 647	I915_WRITE(BLC_PWM_CTL, tmp | level);
 648}
 649
 650static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level)
 651{
 652	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 653	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 654	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
 655	u32 tmp;
 656
 657	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
 658	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
 659}
 660
 661static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
 662{
 663	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 664	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 665	struct intel_panel *panel = &connector->panel;
 666
 667	I915_WRITE(BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
 668}
 669
 670static void pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
 671{
 672	struct intel_panel *panel = &to_intel_connector(conn_state->connector)->panel;
 673	int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
 674
 675	pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
 676}
 677
 678static void
 679intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level)
 680{
 681	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 682	struct intel_panel *panel = &connector->panel;
 683
 684	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
 685
 686	level = intel_panel_compute_brightness(connector, level);
 687	panel->backlight.set(conn_state, level);
 688}
 689
 690/* set backlight brightness to level in range [0..max], assuming hw min is
 691 * respected.
 692 */
 693void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
 694				    u32 user_level, u32 user_max)
 695{
 696	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 697	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 698	struct intel_panel *panel = &connector->panel;
 699	u32 hw_level;
 700
 701	/*
 702	 * Lack of crtc may occur during driver init because
 703	 * connection_mutex isn't held across the entire backlight
 704	 * setup + modeset readout, and the BIOS can issue the
 705	 * requests at any time.
 706	 */
 707	if (!panel->backlight.present || !conn_state->crtc)
 708		return;
 709
 710	mutex_lock(&dev_priv->backlight_lock);
 711
 712	WARN_ON(panel->backlight.max == 0);
 713
 714	hw_level = clamp_user_to_hw(connector, user_level, user_max);
 715	panel->backlight.level = hw_level;
 716
 717	if (panel->backlight.device)
 718		panel->backlight.device->props.brightness =
 719			scale_hw_to_user(connector,
 720					 panel->backlight.level,
 721					 panel->backlight.device->props.max_brightness);
 722
 723	if (panel->backlight.enabled)
 724		intel_panel_actually_set_backlight(conn_state, hw_level);
 725
 726	mutex_unlock(&dev_priv->backlight_lock);
 727}
 728
 729static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state)
 730{
 731	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
 732	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 733	u32 tmp;
 734
 735	intel_panel_actually_set_backlight(old_conn_state, 0);
 736
 737	/*
 738	 * Although we don't support or enable CPU PWM with LPT/SPT based
 739	 * systems, it may have been enabled prior to loading the
 740	 * driver. Disable to avoid warnings on LCPLL disable.
 741	 *
 742	 * This needs rework if we need to add support for CPU PWM on PCH split
 743	 * platforms.
 744	 */
 745	tmp = I915_READ(BLC_PWM_CPU_CTL2);
 746	if (tmp & BLM_PWM_ENABLE) {
 747		DRM_DEBUG_KMS("cpu backlight was enabled, disabling\n");
 748		I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
 749	}
 750
 751	tmp = I915_READ(BLC_PWM_PCH_CTL1);
 752	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
 753}
 754
 755static void pch_disable_backlight(const struct drm_connector_state *old_conn_state)
 756{
 757	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
 758	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 759	u32 tmp;
 760
 761	intel_panel_actually_set_backlight(old_conn_state, 0);
 762
 763	tmp = I915_READ(BLC_PWM_CPU_CTL2);
 764	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
 765
 766	tmp = I915_READ(BLC_PWM_PCH_CTL1);
 767	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
 768}
 769
 770static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state)
 771{
 772	intel_panel_actually_set_backlight(old_conn_state, 0);
 773}
 774
 775static void i965_disable_backlight(const struct drm_connector_state *old_conn_state)
 776{
 777	struct drm_i915_private *dev_priv = to_i915(old_conn_state->connector->dev);
 778	u32 tmp;
 779
 780	intel_panel_actually_set_backlight(old_conn_state, 0);
 781
 782	tmp = I915_READ(BLC_PWM_CTL2);
 783	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
 784}
 785
 786static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state)
 787{
 788	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
 789	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 790	enum pipe pipe = to_intel_crtc(old_conn_state->crtc)->pipe;
 791	u32 tmp;
 792
 793	intel_panel_actually_set_backlight(old_conn_state, 0);
 794
 795	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
 796	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
 797}
 798
 799static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state)
 800{
 801	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
 802	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 803	struct intel_panel *panel = &connector->panel;
 804	u32 tmp, val;
 805
 806	intel_panel_actually_set_backlight(old_conn_state, 0);
 807
 808	tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
 809	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
 810			tmp & ~BXT_BLC_PWM_ENABLE);
 811
 812	if (panel->backlight.controller == 1) {
 813		val = I915_READ(UTIL_PIN_CTL);
 814		val &= ~UTIL_PIN_ENABLE;
 815		I915_WRITE(UTIL_PIN_CTL, val);
 816	}
 817}
 818
 819static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state)
 820{
 821	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
 822	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 823	struct intel_panel *panel = &connector->panel;
 824	u32 tmp;
 825
 826	intel_panel_actually_set_backlight(old_conn_state, 0);
 827
 828	tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
 829	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
 830		   tmp & ~BXT_BLC_PWM_ENABLE);
 831}
 832
 833static void pwm_disable_backlight(const struct drm_connector_state *old_conn_state)
 834{
 835	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
 836	struct intel_panel *panel = &connector->panel;
 837
 838	/* Disable the backlight */
 839	intel_panel_actually_set_backlight(old_conn_state, 0);
 840	usleep_range(2000, 3000);
 841	pwm_disable(panel->backlight.pwm);
 842}
 843
 844void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state)
 845{
 846	struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
 847	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 848	struct intel_panel *panel = &connector->panel;
 849
 850	if (!panel->backlight.present)
 851		return;
 852
 853	/*
 854	 * Do not disable backlight on the vga_switcheroo path. When switching
 855	 * away from i915, the other client may depend on i915 to handle the
 856	 * backlight. This will leave the backlight on unnecessarily when
 857	 * another client is not activated.
 858	 */
 859	if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
 860		DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
 861		return;
 862	}
 863
 864	mutex_lock(&dev_priv->backlight_lock);
 865
 866	if (panel->backlight.device)
 867		panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
 868	panel->backlight.enabled = false;
 869	panel->backlight.disable(old_conn_state);
 870
 871	mutex_unlock(&dev_priv->backlight_lock);
 872}
 873
 874static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
 875				 const struct drm_connector_state *conn_state)
 876{
 877	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 878	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 879	struct intel_panel *panel = &connector->panel;
 880	u32 pch_ctl1, pch_ctl2, schicken;
 881
 882	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
 883	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
 884		DRM_DEBUG_KMS("pch backlight already enabled\n");
 885		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
 886		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
 887	}
 888
 889	if (HAS_PCH_LPT(dev_priv)) {
 890		schicken = I915_READ(SOUTH_CHICKEN2);
 891		if (panel->backlight.alternate_pwm_increment)
 892			schicken |= LPT_PWM_GRANULARITY;
 893		else
 894			schicken &= ~LPT_PWM_GRANULARITY;
 895		I915_WRITE(SOUTH_CHICKEN2, schicken);
 896	} else {
 897		schicken = I915_READ(SOUTH_CHICKEN1);
 898		if (panel->backlight.alternate_pwm_increment)
 899			schicken |= SPT_PWM_GRANULARITY;
 900		else
 901			schicken &= ~SPT_PWM_GRANULARITY;
 902		I915_WRITE(SOUTH_CHICKEN1, schicken);
 903	}
 904
 905	pch_ctl2 = panel->backlight.max << 16;
 906	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
 907
 908	pch_ctl1 = 0;
 909	if (panel->backlight.active_low_pwm)
 910		pch_ctl1 |= BLM_PCH_POLARITY;
 911
 912	/* After LPT, override is the default. */
 913	if (HAS_PCH_LPT(dev_priv))
 914		pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
 915
 916	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
 917	POSTING_READ(BLC_PWM_PCH_CTL1);
 918	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
 919
 920	/* This won't stick until the above enable. */
 921	intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
 922}
 923
 924static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
 925				 const struct drm_connector_state *conn_state)
 926{
 927	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 928	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 929	struct intel_panel *panel = &connector->panel;
 930	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 931	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
 932
 933	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
 934	if (cpu_ctl2 & BLM_PWM_ENABLE) {
 935		DRM_DEBUG_KMS("cpu backlight already enabled\n");
 936		cpu_ctl2 &= ~BLM_PWM_ENABLE;
 937		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
 938	}
 939
 940	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
 941	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
 942		DRM_DEBUG_KMS("pch backlight already enabled\n");
 943		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
 944		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
 945	}
 946
 947	if (cpu_transcoder == TRANSCODER_EDP)
 948		cpu_ctl2 = BLM_TRANSCODER_EDP;
 949	else
 950		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
 951	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
 952	POSTING_READ(BLC_PWM_CPU_CTL2);
 953	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
 954
 955	/* This won't stick until the above enable. */
 956	intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
 957
 958	pch_ctl2 = panel->backlight.max << 16;
 959	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
 960
 961	pch_ctl1 = 0;
 962	if (panel->backlight.active_low_pwm)
 963		pch_ctl1 |= BLM_PCH_POLARITY;
 964
 965	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
 966	POSTING_READ(BLC_PWM_PCH_CTL1);
 967	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
 968}
 969
 970static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state,
 971				  const struct drm_connector_state *conn_state)
 972{
 973	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 974	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 975	struct intel_panel *panel = &connector->panel;
 976	u32 ctl, freq;
 977
 978	ctl = I915_READ(BLC_PWM_CTL);
 979	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
 980		DRM_DEBUG_KMS("backlight already enabled\n");
 981		I915_WRITE(BLC_PWM_CTL, 0);
 982	}
 983
 984	freq = panel->backlight.max;
 985	if (panel->backlight.combination_mode)
 986		freq /= 0xff;
 987
 988	ctl = freq << 17;
 989	if (panel->backlight.combination_mode)
 990		ctl |= BLM_LEGACY_MODE;
 991	if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm)
 992		ctl |= BLM_POLARITY_PNV;
 993
 994	I915_WRITE(BLC_PWM_CTL, ctl);
 995	POSTING_READ(BLC_PWM_CTL);
 996
 997	/* XXX: combine this into above write? */
 998	intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
 999
1000	/*
1001	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
1002	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
1003	 * that has backlight.
1004	 */
1005	if (IS_GEN(dev_priv, 2))
1006		I915_WRITE(BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
1007}
1008
1009static void i965_enable_backlight(const struct intel_crtc_state *crtc_state,
1010				  const struct drm_connector_state *conn_state)
1011{
1012	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1013	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1014	struct intel_panel *panel = &connector->panel;
1015	enum pipe pipe = to_intel_crtc(conn_state->crtc)->pipe;
1016	u32 ctl, ctl2, freq;
1017
1018	ctl2 = I915_READ(BLC_PWM_CTL2);
1019	if (ctl2 & BLM_PWM_ENABLE) {
1020		DRM_DEBUG_KMS("backlight already enabled\n");
1021		ctl2 &= ~BLM_PWM_ENABLE;
1022		I915_WRITE(BLC_PWM_CTL2, ctl2);
1023	}
1024
1025	freq = panel->backlight.max;
1026	if (panel->backlight.combination_mode)
1027		freq /= 0xff;
1028
1029	ctl = freq << 16;
1030	I915_WRITE(BLC_PWM_CTL, ctl);
1031
1032	ctl2 = BLM_PIPE(pipe);
1033	if (panel->backlight.combination_mode)
1034		ctl2 |= BLM_COMBINATION_MODE;
1035	if (panel->backlight.active_low_pwm)
1036		ctl2 |= BLM_POLARITY_I965;
1037	I915_WRITE(BLC_PWM_CTL2, ctl2);
1038	POSTING_READ(BLC_PWM_CTL2);
1039	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
1040
1041	intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1042}
1043
1044static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
1045				 const struct drm_connector_state *conn_state)
1046{
1047	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1048	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1049	struct intel_panel *panel = &connector->panel;
1050	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
1051	u32 ctl, ctl2;
1052
1053	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
1054	if (ctl2 & BLM_PWM_ENABLE) {
1055		DRM_DEBUG_KMS("backlight already enabled\n");
1056		ctl2 &= ~BLM_PWM_ENABLE;
1057		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
1058	}
1059
1060	ctl = panel->backlight.max << 16;
1061	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
1062
1063	/* XXX: combine this into above write? */
1064	intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1065
1066	ctl2 = 0;
1067	if (panel->backlight.active_low_pwm)
1068		ctl2 |= BLM_POLARITY_I965;
1069	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
1070	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
1071	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
1072}
1073
1074static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
1075				 const struct drm_connector_state *conn_state)
1076{
1077	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1078	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1079	struct intel_panel *panel = &connector->panel;
1080	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
1081	u32 pwm_ctl, val;
1082
1083	/* Controller 1 uses the utility pin. */
1084	if (panel->backlight.controller == 1) {
1085		val = I915_READ(UTIL_PIN_CTL);
1086		if (val & UTIL_PIN_ENABLE) {
1087			DRM_DEBUG_KMS("util pin already enabled\n");
1088			val &= ~UTIL_PIN_ENABLE;
1089			I915_WRITE(UTIL_PIN_CTL, val);
1090		}
1091
1092		val = 0;
1093		if (panel->backlight.util_pin_active_low)
1094			val |= UTIL_PIN_POLARITY;
1095		I915_WRITE(UTIL_PIN_CTL, val | UTIL_PIN_PIPE(pipe) |
1096				UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
1097	}
1098
1099	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1100	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
1101		DRM_DEBUG_KMS("backlight already enabled\n");
1102		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
1103		I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
1104				pwm_ctl);
1105	}
1106
1107	I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller),
1108			panel->backlight.max);
1109
1110	intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1111
1112	pwm_ctl = 0;
1113	if (panel->backlight.active_low_pwm)
1114		pwm_ctl |= BXT_BLC_PWM_POLARITY;
1115
1116	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl);
1117	POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1118	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
1119			pwm_ctl | BXT_BLC_PWM_ENABLE);
1120}
1121
1122static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state,
1123				 const struct drm_connector_state *conn_state)
1124{
1125	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1126	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1127	struct intel_panel *panel = &connector->panel;
1128	u32 pwm_ctl;
1129
1130	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1131	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
1132		DRM_DEBUG_KMS("backlight already enabled\n");
1133		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
1134		I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
1135			   pwm_ctl);
1136	}
1137
1138	I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller),
1139		   panel->backlight.max);
1140
1141	intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1142
1143	pwm_ctl = 0;
1144	if (panel->backlight.active_low_pwm)
1145		pwm_ctl |= BXT_BLC_PWM_POLARITY;
1146
1147	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl);
1148	POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1149	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
1150		   pwm_ctl | BXT_BLC_PWM_ENABLE);
1151}
1152
1153static void pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
1154				 const struct drm_connector_state *conn_state)
1155{
1156	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1157	struct intel_panel *panel = &connector->panel;
1158
1159	pwm_enable(panel->backlight.pwm);
1160	intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1161}
1162
1163static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
1164					   const struct drm_connector_state *conn_state)
1165{
1166	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1167	struct intel_panel *panel = &connector->panel;
1168
1169	WARN_ON(panel->backlight.max == 0);
1170
1171	if (panel->backlight.level <= panel->backlight.min) {
1172		panel->backlight.level = panel->backlight.max;
1173		if (panel->backlight.device)
1174			panel->backlight.device->props.brightness =
1175				scale_hw_to_user(connector,
1176						 panel->backlight.level,
1177						 panel->backlight.device->props.max_brightness);
1178	}
1179
1180	panel->backlight.enable(crtc_state, conn_state);
1181	panel->backlight.enabled = true;
1182	if (panel->backlight.device)
1183		panel->backlight.device->props.power = FB_BLANK_UNBLANK;
1184}
1185
1186void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
1187				  const struct drm_connector_state *conn_state)
1188{
1189	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1190	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1191	struct intel_panel *panel = &connector->panel;
1192	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
1193
1194	if (!panel->backlight.present)
1195		return;
1196
1197	DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
1198
1199	mutex_lock(&dev_priv->backlight_lock);
1200
1201	__intel_panel_enable_backlight(crtc_state, conn_state);
1202
1203	mutex_unlock(&dev_priv->backlight_lock);
1204}
1205
1206#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
1207static u32 intel_panel_get_backlight(struct intel_connector *connector)
1208{
1209	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1210	struct intel_panel *panel = &connector->panel;
1211	u32 val = 0;
1212
1213	mutex_lock(&dev_priv->backlight_lock);
1214
1215	if (panel->backlight.enabled) {
1216		val = panel->backlight.get(connector);
1217		val = intel_panel_compute_brightness(connector, val);
1218	}
1219
1220	mutex_unlock(&dev_priv->backlight_lock);
1221
1222	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
1223	return val;
1224}
1225
1226/* set backlight brightness to level in range [0..max], scaling wrt hw min */
1227static void intel_panel_set_backlight(const struct drm_connector_state *conn_state,
1228				      u32 user_level, u32 user_max)
1229{
1230	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1231	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1232	struct intel_panel *panel = &connector->panel;
1233	u32 hw_level;
1234
1235	if (!panel->backlight.present)
1236		return;
1237
1238	mutex_lock(&dev_priv->backlight_lock);
1239
1240	WARN_ON(panel->backlight.max == 0);
1241
1242	hw_level = scale_user_to_hw(connector, user_level, user_max);
1243	panel->backlight.level = hw_level;
1244
1245	if (panel->backlight.enabled)
1246		intel_panel_actually_set_backlight(conn_state, hw_level);
1247
1248	mutex_unlock(&dev_priv->backlight_lock);
1249}
1250
1251static int intel_backlight_device_update_status(struct backlight_device *bd)
1252{
1253	struct intel_connector *connector = bl_get_data(bd);
1254	struct intel_panel *panel = &connector->panel;
1255	struct drm_device *dev = connector->base.dev;
1256
1257	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1258	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
1259		      bd->props.brightness, bd->props.max_brightness);
1260	intel_panel_set_backlight(connector->base.state, bd->props.brightness,
1261				  bd->props.max_brightness);
1262
1263	/*
1264	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
1265	 * backlight class device does not make it easy to to differentiate
1266	 * between callbacks for brightness and bl_power, so our backlight_power
1267	 * callback needs to take this into account.
1268	 */
1269	if (panel->backlight.enabled) {
1270		if (panel->backlight.power) {
1271			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
1272				bd->props.brightness != 0;
1273			panel->backlight.power(connector, enable);
1274		}
1275	} else {
1276		bd->props.power = FB_BLANK_POWERDOWN;
1277	}
1278
1279	drm_modeset_unlock(&dev->mode_config.connection_mutex);
1280	return 0;
1281}
1282
1283static int intel_backlight_device_get_brightness(struct backlight_device *bd)
1284{
1285	struct intel_connector *connector = bl_get_data(bd);
1286	struct drm_device *dev = connector->base.dev;
1287	struct drm_i915_private *dev_priv = to_i915(dev);
1288	intel_wakeref_t wakeref;
1289	int ret = 0;
1290
1291	with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
1292		u32 hw_level;
1293
1294		drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1295
1296		hw_level = intel_panel_get_backlight(connector);
1297		ret = scale_hw_to_user(connector,
1298				       hw_level, bd->props.max_brightness);
1299
1300		drm_modeset_unlock(&dev->mode_config.connection_mutex);
1301	}
1302
1303	return ret;
1304}
1305
1306static const struct backlight_ops intel_backlight_device_ops = {
1307	.update_status = intel_backlight_device_update_status,
1308	.get_brightness = intel_backlight_device_get_brightness,
1309};
1310
1311int intel_backlight_device_register(struct intel_connector *connector)
1312{
1313	struct intel_panel *panel = &connector->panel;
1314	struct backlight_properties props;
1315
1316	if (WARN_ON(panel->backlight.device))
1317		return -ENODEV;
1318
1319	if (!panel->backlight.present)
1320		return 0;
1321
1322	WARN_ON(panel->backlight.max == 0);
1323
1324	memset(&props, 0, sizeof(props));
1325	props.type = BACKLIGHT_RAW;
1326
1327	/*
1328	 * Note: Everything should work even if the backlight device max
1329	 * presented to the userspace is arbitrarily chosen.
1330	 */
1331	props.max_brightness = panel->backlight.max;
1332	props.brightness = scale_hw_to_user(connector,
1333					    panel->backlight.level,
1334					    props.max_brightness);
1335
1336	if (panel->backlight.enabled)
1337		props.power = FB_BLANK_UNBLANK;
1338	else
1339		props.power = FB_BLANK_POWERDOWN;
1340
1341	/*
1342	 * Note: using the same name independent of the connector prevents
1343	 * registration of multiple backlight devices in the driver.
1344	 */
1345	panel->backlight.device =
1346		backlight_device_register("intel_backlight",
1347					  connector->base.kdev,
1348					  connector,
1349					  &intel_backlight_device_ops, &props);
1350
1351	if (IS_ERR(panel->backlight.device)) {
1352		DRM_ERROR("Failed to register backlight: %ld\n",
1353			  PTR_ERR(panel->backlight.device));
1354		panel->backlight.device = NULL;
1355		return -ENODEV;
1356	}
1357
1358	DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n",
1359		      connector->base.name);
1360
1361	return 0;
1362}
1363
1364void intel_backlight_device_unregister(struct intel_connector *connector)
1365{
1366	struct intel_panel *panel = &connector->panel;
1367
1368	if (panel->backlight.device) {
1369		backlight_device_unregister(panel->backlight.device);
1370		panel->backlight.device = NULL;
1371	}
1372}
1373#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
1374
1375/*
1376 * CNP: PWM clock frequency is 19.2 MHz or 24 MHz.
1377 *      PWM increment = 1
1378 */
1379static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1380{
1381	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1382
1383	return DIV_ROUND_CLOSEST(KHz(dev_priv->rawclk_freq), pwm_freq_hz);
1384}
1385
1386/*
1387 * BXT: PWM clock frequency = 19.2 MHz.
1388 */
1389static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1390{
1391	return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz);
1392}
1393
1394/*
1395 * SPT: This value represents the period of the PWM stream in clock periods
1396 * multiplied by 16 (default increment) or 128 (alternate increment selected in
1397 * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
1398 */
1399static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1400{
1401	struct intel_panel *panel = &connector->panel;
1402	u32 mul;
1403
1404	if (panel->backlight.alternate_pwm_increment)
1405		mul = 128;
1406	else
1407		mul = 16;
1408
1409	return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul);
1410}
1411
1412/*
1413 * LPT: This value represents the period of the PWM stream in clock periods
1414 * multiplied by 128 (default increment) or 16 (alternate increment, selected in
1415 * LPT SOUTH_CHICKEN2 register bit 5).
1416 */
1417static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1418{
1419	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1420	struct intel_panel *panel = &connector->panel;
1421	u32 mul, clock;
1422
1423	if (panel->backlight.alternate_pwm_increment)
1424		mul = 16;
1425	else
1426		mul = 128;
1427
1428	if (HAS_PCH_LPT_H(dev_priv))
1429		clock = MHz(135); /* LPT:H */
1430	else
1431		clock = MHz(24); /* LPT:LP */
1432
1433	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
1434}
1435
1436/*
1437 * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
1438 * display raw clocks multiplied by 128.
1439 */
1440static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1441{
1442	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1443
1444	return DIV_ROUND_CLOSEST(KHz(dev_priv->rawclk_freq), pwm_freq_hz * 128);
1445}
1446
1447/*
1448 * Gen2: This field determines the number of time base events (display core
1449 * clock frequency/32) in total for a complete cycle of modulated backlight
1450 * control.
1451 *
1452 * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
1453 * divided by 32.
1454 */
1455static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1456{
1457	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1458	int clock;
1459
1460	if (IS_PINEVIEW(dev_priv))
1461		clock = KHz(dev_priv->rawclk_freq);
1462	else
1463		clock = KHz(dev_priv->cdclk.hw.cdclk);
1464
1465	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
1466}
1467
1468/*
1469 * Gen4: This value represents the period of the PWM stream in display core
1470 * clocks ([DevCTG] HRAW clocks) multiplied by 128.
1471 *
1472 */
1473static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1474{
1475	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1476	int clock;
1477
1478	if (IS_G4X(dev_priv))
1479		clock = KHz(dev_priv->rawclk_freq);
1480	else
1481		clock = KHz(dev_priv->cdclk.hw.cdclk);
1482
1483	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
1484}
1485
1486/*
1487 * VLV: This value represents the period of the PWM stream in display core
1488 * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
1489 * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
1490 */
1491static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1492{
1493	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1494	int mul, clock;
1495
1496	if ((I915_READ(CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
1497		if (IS_CHERRYVIEW(dev_priv))
1498			clock = KHz(19200);
1499		else
1500			clock = MHz(25);
1501		mul = 16;
1502	} else {
1503		clock = KHz(dev_priv->rawclk_freq);
1504		mul = 128;
1505	}
1506
1507	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
1508}
1509
1510static u32 get_backlight_max_vbt(struct intel_connector *connector)
 
 
1511{
1512	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1513	struct intel_panel *panel = &connector->panel;
1514	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
1515	u32 pwm;
1516
1517	if (!panel->backlight.hz_to_pwm) {
1518		DRM_DEBUG_KMS("backlight frequency conversion not supported\n");
1519		return 0;
1520	}
1521
1522	if (pwm_freq_hz) {
1523		DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n",
1524			      pwm_freq_hz);
1525	} else {
1526		pwm_freq_hz = 200;
1527		DRM_DEBUG_KMS("default backlight frequency %u Hz\n",
1528			      pwm_freq_hz);
1529	}
1530
1531	pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz);
1532	if (!pwm) {
1533		DRM_DEBUG_KMS("backlight frequency conversion failed\n");
1534		return 0;
1535	}
1536
1537	return pwm;
1538}
1539
1540/*
1541 * Note: The setup hooks can't assume pipe is set!
1542 */
1543static u32 get_backlight_min_vbt(struct intel_connector *connector)
1544{
1545	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1546	struct intel_panel *panel = &connector->panel;
1547	int min;
1548
1549	WARN_ON(panel->backlight.max == 0);
1550
1551	/*
1552	 * XXX: If the vbt value is 255, it makes min equal to max, which leads
1553	 * to problems. There are such machines out there. Either our
1554	 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
1555	 * against this by letting the minimum be at most (arbitrarily chosen)
1556	 * 25% of the max.
1557	 */
1558	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
1559	if (min != dev_priv->vbt.backlight.min_brightness) {
1560		DRM_DEBUG_KMS("clamping VBT min backlight %d/255 to %d/255\n",
1561			      dev_priv->vbt.backlight.min_brightness, min);
1562	}
1563
1564	/* vbt value is a coefficient in range [0..255] */
1565	return scale(min, 0, 255, 0, panel->backlight.max);
1566}
1567
1568static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
1569{
1570	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1571	struct intel_panel *panel = &connector->panel;
1572	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
1573	bool alt, cpu_mode;
1574
1575	if (HAS_PCH_LPT(dev_priv))
1576		alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
1577	else
1578		alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
1579	panel->backlight.alternate_pwm_increment = alt;
1580
1581	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
1582	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
1583
1584	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
1585	panel->backlight.max = pch_ctl2 >> 16;
1586
1587	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
1588
1589	if (!panel->backlight.max)
1590		panel->backlight.max = get_backlight_max_vbt(connector);
1591
1592	if (!panel->backlight.max)
1593		return -ENODEV;
1594
1595	panel->backlight.min = get_backlight_min_vbt(connector);
1596
1597	panel->backlight.enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
1598
1599	cpu_mode = panel->backlight.enabled && HAS_PCH_LPT(dev_priv) &&
1600		   !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) &&
1601		   (cpu_ctl2 & BLM_PWM_ENABLE);
1602	if (cpu_mode)
1603		val = pch_get_backlight(connector);
1604	else
1605		val = lpt_get_backlight(connector);
1606	val = intel_panel_compute_brightness(connector, val);
1607	panel->backlight.level = clamp(val, panel->backlight.min,
1608				       panel->backlight.max);
1609
1610	if (cpu_mode) {
1611		DRM_DEBUG_KMS("CPU backlight register was enabled, switching to PCH override\n");
1612
1613		/* Write converted CPU PWM value to PCH override register */
1614		lpt_set_backlight(connector->base.state, panel->backlight.level);
1615		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE);
1616
1617		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 & ~BLM_PWM_ENABLE);
1618	}
1619
1620	return 0;
1621}
1622
1623static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
1624{
1625	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1626	struct intel_panel *panel = &connector->panel;
1627	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
1628
1629	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
1630	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
1631
1632	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
1633	panel->backlight.max = pch_ctl2 >> 16;
1634
1635	if (!panel->backlight.max)
1636		panel->backlight.max = get_backlight_max_vbt(connector);
1637
1638	if (!panel->backlight.max)
1639		return -ENODEV;
1640
1641	panel->backlight.min = get_backlight_min_vbt(connector);
1642
1643	val = pch_get_backlight(connector);
1644	val = intel_panel_compute_brightness(connector, val);
1645	panel->backlight.level = clamp(val, panel->backlight.min,
1646				       panel->backlight.max);
1647
1648	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
1649	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
1650		(pch_ctl1 & BLM_PCH_PWM_ENABLE);
1651
1652	return 0;
1653}
1654
1655static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
1656{
1657	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1658	struct intel_panel *panel = &connector->panel;
1659	u32 ctl, val;
1660
1661	ctl = I915_READ(BLC_PWM_CTL);
1662
1663	if (IS_GEN(dev_priv, 2) || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
1664		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
1665
1666	if (IS_PINEVIEW(dev_priv))
1667		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
1668
1669	panel->backlight.max = ctl >> 17;
1670
1671	if (!panel->backlight.max) {
1672		panel->backlight.max = get_backlight_max_vbt(connector);
1673		panel->backlight.max >>= 1;
1674	}
1675
1676	if (!panel->backlight.max)
1677		return -ENODEV;
1678
1679	if (panel->backlight.combination_mode)
1680		panel->backlight.max *= 0xff;
1681
1682	panel->backlight.min = get_backlight_min_vbt(connector);
1683
1684	val = i9xx_get_backlight(connector);
1685	val = intel_panel_compute_brightness(connector, val);
1686	panel->backlight.level = clamp(val, panel->backlight.min,
1687				       panel->backlight.max);
1688
1689	panel->backlight.enabled = val != 0;
1690
1691	return 0;
1692}
1693
1694static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
1695{
1696	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1697	struct intel_panel *panel = &connector->panel;
1698	u32 ctl, ctl2, val;
1699
1700	ctl2 = I915_READ(BLC_PWM_CTL2);
1701	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
1702	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
1703
1704	ctl = I915_READ(BLC_PWM_CTL);
1705	panel->backlight.max = ctl >> 16;
1706
1707	if (!panel->backlight.max)
1708		panel->backlight.max = get_backlight_max_vbt(connector);
1709
1710	if (!panel->backlight.max)
1711		return -ENODEV;
1712
1713	if (panel->backlight.combination_mode)
1714		panel->backlight.max *= 0xff;
1715
1716	panel->backlight.min = get_backlight_min_vbt(connector);
1717
1718	val = i9xx_get_backlight(connector);
1719	val = intel_panel_compute_brightness(connector, val);
1720	panel->backlight.level = clamp(val, panel->backlight.min,
1721				       panel->backlight.max);
1722
1723	panel->backlight.enabled = ctl2 & BLM_PWM_ENABLE;
1724
1725	return 0;
1726}
1727
1728static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
1729{
1730	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1731	struct intel_panel *panel = &connector->panel;
1732	u32 ctl, ctl2, val;
1733
1734	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
1735		return -ENODEV;
1736
1737	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
1738	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
1739
1740	ctl = I915_READ(VLV_BLC_PWM_CTL(pipe));
1741	panel->backlight.max = ctl >> 16;
1742
1743	if (!panel->backlight.max)
1744		panel->backlight.max = get_backlight_max_vbt(connector);
1745
1746	if (!panel->backlight.max)
1747		return -ENODEV;
1748
1749	panel->backlight.min = get_backlight_min_vbt(connector);
1750
1751	val = _vlv_get_backlight(dev_priv, pipe);
1752	val = intel_panel_compute_brightness(connector, val);
1753	panel->backlight.level = clamp(val, panel->backlight.min,
1754				       panel->backlight.max);
1755
1756	panel->backlight.enabled = ctl2 & BLM_PWM_ENABLE;
1757
1758	return 0;
1759}
1760
1761static int
1762bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
1763{
1764	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1765	struct intel_panel *panel = &connector->panel;
1766	u32 pwm_ctl, val;
1767
1768	panel->backlight.controller = dev_priv->vbt.backlight.controller;
1769
1770	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1771
1772	/* Controller 1 uses the utility pin. */
1773	if (panel->backlight.controller == 1) {
1774		val = I915_READ(UTIL_PIN_CTL);
1775		panel->backlight.util_pin_active_low =
1776					val & UTIL_PIN_POLARITY;
1777	}
1778
1779	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
1780	panel->backlight.max =
1781		I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller));
1782
1783	if (!panel->backlight.max)
1784		panel->backlight.max = get_backlight_max_vbt(connector);
1785
1786	if (!panel->backlight.max)
1787		return -ENODEV;
1788
1789	panel->backlight.min = get_backlight_min_vbt(connector);
 
1790
1791	val = bxt_get_backlight(connector);
1792	val = intel_panel_compute_brightness(connector, val);
1793	panel->backlight.level = clamp(val, panel->backlight.min,
1794				       panel->backlight.max);
1795
1796	panel->backlight.enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
 
1797
1798	return 0;
1799}
1800
1801static int
1802cnp_setup_backlight(struct intel_connector *connector, enum pipe unused)
1803{
1804	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1805	struct intel_panel *panel = &connector->panel;
1806	u32 pwm_ctl, val;
1807
1808	/*
1809	 * CNP has the BXT implementation of backlight, but with only one
1810	 * controller. TODO: ICP has multiple controllers but we only use
1811	 * controller 0 for now.
1812	 */
1813	panel->backlight.controller = 0;
1814
1815	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1816
1817	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
1818	panel->backlight.max =
1819		I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller));
1820
1821	if (!panel->backlight.max)
1822		panel->backlight.max = get_backlight_max_vbt(connector);
1823
1824	if (!panel->backlight.max)
1825		return -ENODEV;
1826
1827	panel->backlight.min = get_backlight_min_vbt(connector);
1828
1829	val = bxt_get_backlight(connector);
1830	val = intel_panel_compute_brightness(connector, val);
1831	panel->backlight.level = clamp(val, panel->backlight.min,
1832				       panel->backlight.max);
1833
1834	panel->backlight.enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
1835
1836	return 0;
1837}
1838
1839static int pwm_setup_backlight(struct intel_connector *connector,
1840			       enum pipe pipe)
1841{
1842	struct drm_device *dev = connector->base.dev;
1843	struct intel_panel *panel = &connector->panel;
1844	int retval;
1845
1846	/* Get the PWM chip for backlight control */
1847	panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
1848	if (IS_ERR(panel->backlight.pwm)) {
1849		DRM_ERROR("Failed to own the pwm chip\n");
1850		panel->backlight.pwm = NULL;
1851		return -ENODEV;
1852	}
1853
1854	/*
1855	 * FIXME: pwm_apply_args() should be removed when switching to
1856	 * the atomic PWM API.
1857	 */
1858	pwm_apply_args(panel->backlight.pwm);
1859
1860	retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS,
1861			    CRC_PMIC_PWM_PERIOD_NS);
1862	if (retval < 0) {
1863		DRM_ERROR("Failed to configure the pwm chip\n");
1864		pwm_put(panel->backlight.pwm);
1865		panel->backlight.pwm = NULL;
1866		return retval;
1867	}
1868
1869	panel->backlight.min = 0; /* 0% */
1870	panel->backlight.max = 100; /* 100% */
1871	panel->backlight.level = DIV_ROUND_UP(
1872				 pwm_get_duty_cycle(panel->backlight.pwm) * 100,
1873				 CRC_PMIC_PWM_PERIOD_NS);
1874	panel->backlight.enabled = panel->backlight.level != 0;
1875
1876	return 0;
1877}
1878
1879void intel_panel_update_backlight(struct intel_encoder *encoder,
1880				  const struct intel_crtc_state *crtc_state,
1881				  const struct drm_connector_state *conn_state)
1882{
1883	struct intel_connector *connector = to_intel_connector(conn_state->connector);
1884	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1885	struct intel_panel *panel = &connector->panel;
 
1886
1887	if (!panel->backlight.present)
1888		return;
1889
1890	mutex_lock(&dev_priv->backlight_lock);
1891	if (!panel->backlight.enabled)
1892		__intel_panel_enable_backlight(crtc_state, conn_state);
1893
1894	mutex_unlock(&dev_priv->backlight_lock);
1895}
1896
1897int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
1898{
1899	struct drm_i915_private *dev_priv = to_i915(connector->dev);
1900	struct intel_connector *intel_connector = to_intel_connector(connector);
1901	struct intel_panel *panel = &intel_connector->panel;
1902	int ret;
1903
1904	if (!dev_priv->vbt.backlight.present) {
1905		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
1906			DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n");
1907		} else {
1908			DRM_DEBUG_KMS("no backlight present per VBT\n");
1909			return 0;
1910		}
1911	}
1912
1913	/* ensure intel_panel has been initialized first */
1914	if (WARN_ON(!panel->backlight.setup))
1915		return -ENODEV;
1916
1917	/* set level and max in panel struct */
1918	mutex_lock(&dev_priv->backlight_lock);
1919	ret = panel->backlight.setup(intel_connector, pipe);
1920	mutex_unlock(&dev_priv->backlight_lock);
1921
1922	if (ret) {
1923		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
1924			      connector->name);
1925		return ret;
1926	}
1927
1928	panel->backlight.present = true;
1929
1930	DRM_DEBUG_KMS("Connector %s backlight initialized, %s, brightness %u/%u\n",
1931		      connector->name,
1932		      enableddisabled(panel->backlight.enabled),
1933		      panel->backlight.level, panel->backlight.max);
1934
1935	return 0;
1936}
1937
1938static void intel_panel_destroy_backlight(struct intel_panel *panel)
1939{
1940	/* dispose of the pwm */
1941	if (panel->backlight.pwm)
1942		pwm_put(panel->backlight.pwm);
1943
1944	panel->backlight.present = false;
1945}
1946
1947/* Set up chip specific backlight functions */
1948static void
1949intel_panel_init_backlight_funcs(struct intel_panel *panel)
1950{
1951	struct intel_connector *connector =
1952		container_of(panel, struct intel_connector, panel);
1953	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1954
1955	if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
1956	    intel_dp_aux_init_backlight_funcs(connector) == 0)
1957		return;
1958
1959	if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
1960	    intel_dsi_dcs_init_backlight_funcs(connector) == 0)
1961		return;
1962
1963	if (IS_GEN9_LP(dev_priv)) {
1964		panel->backlight.setup = bxt_setup_backlight;
1965		panel->backlight.enable = bxt_enable_backlight;
1966		panel->backlight.disable = bxt_disable_backlight;
1967		panel->backlight.set = bxt_set_backlight;
1968		panel->backlight.get = bxt_get_backlight;
1969		panel->backlight.hz_to_pwm = bxt_hz_to_pwm;
1970	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) {
1971		panel->backlight.setup = cnp_setup_backlight;
1972		panel->backlight.enable = cnp_enable_backlight;
1973		panel->backlight.disable = cnp_disable_backlight;
1974		panel->backlight.set = bxt_set_backlight;
1975		panel->backlight.get = bxt_get_backlight;
1976		panel->backlight.hz_to_pwm = cnp_hz_to_pwm;
1977	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_LPT) {
1978		panel->backlight.setup = lpt_setup_backlight;
1979		panel->backlight.enable = lpt_enable_backlight;
1980		panel->backlight.disable = lpt_disable_backlight;
1981		panel->backlight.set = lpt_set_backlight;
1982		panel->backlight.get = lpt_get_backlight;
1983		if (HAS_PCH_LPT(dev_priv))
1984			panel->backlight.hz_to_pwm = lpt_hz_to_pwm;
1985		else
1986			panel->backlight.hz_to_pwm = spt_hz_to_pwm;
1987	} else if (HAS_PCH_SPLIT(dev_priv)) {
1988		panel->backlight.setup = pch_setup_backlight;
1989		panel->backlight.enable = pch_enable_backlight;
1990		panel->backlight.disable = pch_disable_backlight;
1991		panel->backlight.set = pch_set_backlight;
1992		panel->backlight.get = pch_get_backlight;
1993		panel->backlight.hz_to_pwm = pch_hz_to_pwm;
1994	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1995		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
1996			panel->backlight.setup = pwm_setup_backlight;
1997			panel->backlight.enable = pwm_enable_backlight;
1998			panel->backlight.disable = pwm_disable_backlight;
1999			panel->backlight.set = pwm_set_backlight;
2000			panel->backlight.get = pwm_get_backlight;
2001		} else {
2002			panel->backlight.setup = vlv_setup_backlight;
2003			panel->backlight.enable = vlv_enable_backlight;
2004			panel->backlight.disable = vlv_disable_backlight;
2005			panel->backlight.set = vlv_set_backlight;
2006			panel->backlight.get = vlv_get_backlight;
2007			panel->backlight.hz_to_pwm = vlv_hz_to_pwm;
2008		}
2009	} else if (IS_GEN(dev_priv, 4)) {
2010		panel->backlight.setup = i965_setup_backlight;
2011		panel->backlight.enable = i965_enable_backlight;
2012		panel->backlight.disable = i965_disable_backlight;
2013		panel->backlight.set = i9xx_set_backlight;
2014		panel->backlight.get = i9xx_get_backlight;
2015		panel->backlight.hz_to_pwm = i965_hz_to_pwm;
2016	} else {
2017		panel->backlight.setup = i9xx_setup_backlight;
2018		panel->backlight.enable = i9xx_enable_backlight;
2019		panel->backlight.disable = i9xx_disable_backlight;
2020		panel->backlight.set = i9xx_set_backlight;
2021		panel->backlight.get = i9xx_get_backlight;
2022		panel->backlight.hz_to_pwm = i9xx_hz_to_pwm;
2023	}
2024}
2025
2026int intel_panel_init(struct intel_panel *panel,
2027		     struct drm_display_mode *fixed_mode,
2028		     struct drm_display_mode *downclock_mode)
2029{
2030	intel_panel_init_backlight_funcs(panel);
2031
2032	panel->fixed_mode = fixed_mode;
2033	panel->downclock_mode = downclock_mode;
2034
2035	return 0;
2036}
2037
2038void intel_panel_fini(struct intel_panel *panel)
2039{
2040	struct intel_connector *intel_connector =
2041		container_of(panel, struct intel_connector, panel);
2042
2043	intel_panel_destroy_backlight(panel);
2044
2045	if (panel->fixed_mode)
2046		drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
2047
2048	if (panel->downclock_mode)
2049		drm_mode_destroy(intel_connector->base.dev,
2050				panel->downclock_mode);
2051}
v6.8
  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/pwm.h>
 33
 34#include <drm/drm_edid.h>
 35
 36#include "i915_reg.h"
 37#include "intel_backlight.h"
 38#include "intel_connector.h"
 39#include "intel_de.h"
 40#include "intel_display_types.h"
 41#include "intel_drrs.h"
 42#include "intel_lvds_regs.h"
 43#include "intel_panel.h"
 44#include "intel_quirks.h"
 45#include "intel_vrr.h"
 46
 47bool intel_panel_use_ssc(struct drm_i915_private *i915)
 48{
 49	if (i915->display.params.panel_use_ssc >= 0)
 50		return i915->display.params.panel_use_ssc != 0;
 51	return i915->display.vbt.lvds_use_ssc &&
 52		!intel_has_quirk(i915, QUIRK_LVDS_SSC_DISABLE);
 53}
 54
 55const struct drm_display_mode *
 56intel_panel_preferred_fixed_mode(struct intel_connector *connector)
 
 57{
 58	return list_first_entry_or_null(&connector->panel.fixed_modes,
 59					struct drm_display_mode, head);
 60}
 61
 62static bool is_best_fixed_mode(struct intel_connector *connector,
 63			       int vrefresh, int fixed_mode_vrefresh,
 64			       const struct drm_display_mode *best_mode)
 65{
 66	/* we want to always return something */
 67	if (!best_mode)
 68		return true;
 69
 70	/*
 71	 * With VRR always pick a mode with equal/higher than requested
 72	 * vrefresh, which we can then reduce to match the requested
 73	 * vrefresh by extending the vblank length.
 74	 */
 75	if (intel_vrr_is_in_range(connector, vrefresh) &&
 76	    intel_vrr_is_in_range(connector, fixed_mode_vrefresh) &&
 77	    fixed_mode_vrefresh < vrefresh)
 78		return false;
 79
 80	/* pick the fixed_mode that is closest in terms of vrefresh */
 81	return abs(fixed_mode_vrefresh - vrefresh) <
 82		abs(drm_mode_vrefresh(best_mode) - vrefresh);
 83}
 84
 85const struct drm_display_mode *
 86intel_panel_fixed_mode(struct intel_connector *connector,
 87		       const struct drm_display_mode *mode)
 88{
 89	const struct drm_display_mode *fixed_mode, *best_mode = NULL;
 90	int vrefresh = drm_mode_vrefresh(mode);
 91
 92	list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
 93		int fixed_mode_vrefresh = drm_mode_vrefresh(fixed_mode);
 94
 95		if (is_best_fixed_mode(connector, vrefresh,
 96				       fixed_mode_vrefresh, best_mode))
 97			best_mode = fixed_mode;
 98	}
 99
100	return best_mode;
101}
102
103static bool is_alt_drrs_mode(const struct drm_display_mode *mode,
104			     const struct drm_display_mode *preferred_mode)
105{
106	return drm_mode_match(mode, preferred_mode,
107			      DRM_MODE_MATCH_TIMINGS |
108			      DRM_MODE_MATCH_FLAGS |
109			      DRM_MODE_MATCH_3D_FLAGS) &&
110		mode->clock != preferred_mode->clock;
111}
112
113static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
114			      const struct drm_display_mode *preferred_mode)
 
115{
116	u32 sync_flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
117		DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC;
 
 
118
119	return (mode->flags & ~sync_flags) == (preferred_mode->flags & ~sync_flags) &&
120		mode->hdisplay == preferred_mode->hdisplay &&
121		mode->vdisplay == preferred_mode->vdisplay;
122}
123
124const struct drm_display_mode *
125intel_panel_downclock_mode(struct intel_connector *connector,
126			   const struct drm_display_mode *adjusted_mode)
127{
128	const struct drm_display_mode *fixed_mode, *best_mode = NULL;
129	int min_vrefresh = connector->panel.vbt.seamless_drrs_min_refresh_rate;
130	int max_vrefresh = drm_mode_vrefresh(adjusted_mode);
131
132	/* pick the fixed_mode with the lowest refresh rate */
133	list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
134		int vrefresh = drm_mode_vrefresh(fixed_mode);
135
136		if (is_alt_drrs_mode(fixed_mode, adjusted_mode) &&
137		    vrefresh >= min_vrefresh && vrefresh < max_vrefresh) {
138			max_vrefresh = vrefresh;
139			best_mode = fixed_mode;
140		}
141	}
142
143	return best_mode;
144}
145
146const struct drm_display_mode *
147intel_panel_highest_mode(struct intel_connector *connector,
148			 const struct drm_display_mode *adjusted_mode)
149{
150	const struct drm_display_mode *fixed_mode, *best_mode = adjusted_mode;
151
152	/* pick the fixed_mode that has the highest clock */
153	list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
154		if (fixed_mode->clock > best_mode->clock)
155			best_mode = fixed_mode;
156	}
157
158	return best_mode;
159}
160
161int intel_panel_get_modes(struct intel_connector *connector)
162{
163	const struct drm_display_mode *fixed_mode;
164	int num_modes = 0;
165
166	list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head) {
167		struct drm_display_mode *mode;
168
169		mode = drm_mode_duplicate(connector->base.dev, fixed_mode);
170		if (mode) {
171			drm_mode_probed_add(&connector->base, mode);
172			num_modes++;
173		}
174	}
175
176	return num_modes;
177}
178
179static bool has_drrs_modes(struct intel_connector *connector)
180{
181	const struct drm_display_mode *mode1;
182
183	list_for_each_entry(mode1, &connector->panel.fixed_modes, head) {
184		const struct drm_display_mode *mode2 = mode1;
185
186		list_for_each_entry_continue(mode2, &connector->panel.fixed_modes, head) {
187			if (is_alt_drrs_mode(mode1, mode2))
188				return true;
189		}
190	}
191
192	return false;
193}
194
195enum drrs_type intel_panel_drrs_type(struct intel_connector *connector)
196{
197	return connector->panel.vbt.drrs_type;
198}
199
200int intel_panel_compute_config(struct intel_connector *connector,
201			       struct drm_display_mode *adjusted_mode)
202{
203	const struct drm_display_mode *fixed_mode =
204		intel_panel_fixed_mode(connector, adjusted_mode);
205	int vrefresh, fixed_mode_vrefresh;
206	bool is_vrr;
207
208	if (!fixed_mode)
209		return 0;
210
211	vrefresh = drm_mode_vrefresh(adjusted_mode);
212	fixed_mode_vrefresh = drm_mode_vrefresh(fixed_mode);
213
214	/*
215	 * Assume that we shouldn't muck about with the
216	 * timings if they don't land in the VRR range.
217	 */
218	is_vrr = intel_vrr_is_in_range(connector, vrefresh) &&
219		intel_vrr_is_in_range(connector, fixed_mode_vrefresh);
220
221	if (!is_vrr) {
222		/*
223		 * We don't want to lie too much to the user about the refresh
224		 * rate they're going to get. But we have to allow a bit of latitude
225		 * for Xorg since it likes to automagically cook up modes with slightly
226		 * off refresh rates.
 
227		 */
228		if (abs(vrefresh - fixed_mode_vrefresh) > 1) {
229			drm_dbg_kms(connector->base.dev,
230				    "[CONNECTOR:%d:%s] Requested mode vrefresh (%d Hz) does not match fixed mode vrefresh (%d Hz)\n",
231				    connector->base.base.id, connector->base.name,
232				    vrefresh, fixed_mode_vrefresh);
233
234			return -EINVAL;
 
235		}
236	}
237
238	drm_mode_copy(adjusted_mode, fixed_mode);
 
239
240	if (is_vrr && fixed_mode_vrefresh != vrefresh)
241		adjusted_mode->vtotal =
242			DIV_ROUND_CLOSEST(adjusted_mode->clock * 1000,
243					  adjusted_mode->htotal * vrefresh);
244
245	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
 
246
247	return 0;
248}
249
250static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector)
 
251{
252	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
253	const struct drm_display_mode *preferred_mode =
254		intel_panel_preferred_fixed_mode(connector);
255	struct drm_display_mode *mode, *next;
 
 
256
257	list_for_each_entry_safe(mode, next, &connector->base.probed_modes, head) {
258		if (!is_alt_fixed_mode(mode, preferred_mode))
 
259			continue;
260
261		drm_dbg_kms(&dev_priv->drm,
262			    "[CONNECTOR:%d:%s] using alternate EDID fixed mode: " DRM_MODE_FMT "\n",
263			    connector->base.base.id, connector->base.name,
264			    DRM_MODE_ARG(mode));
 
 
 
265
266		list_move_tail(&mode->head, &connector->panel.fixed_modes);
267	}
268}
269
270static void intel_panel_add_edid_preferred_mode(struct intel_connector *connector)
271{
272	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
273	struct drm_display_mode *scan, *fixed_mode = NULL;
274
275	if (list_empty(&connector->base.probed_modes))
276		return;
277
278	/* make sure the preferred mode is first */
279	list_for_each_entry(scan, &connector->base.probed_modes, head) {
280		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
281			fixed_mode = scan;
282			break;
283		}
284	}
285
 
286	if (!fixed_mode)
287		fixed_mode = list_first_entry(&connector->base.probed_modes,
288					      typeof(*fixed_mode), head);
289
290	drm_dbg_kms(&dev_priv->drm,
291		    "[CONNECTOR:%d:%s] using %s EDID fixed mode: " DRM_MODE_FMT "\n",
292		    connector->base.base.id, connector->base.name,
293		    fixed_mode->type & DRM_MODE_TYPE_PREFERRED ? "preferred" : "first",
294		    DRM_MODE_ARG(fixed_mode));
295
296	fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
297
298	list_move_tail(&fixed_mode->head, &connector->panel.fixed_modes);
299}
300
301static void intel_panel_destroy_probed_modes(struct intel_connector *connector)
302{
303	struct drm_i915_private *i915 = to_i915(connector->base.dev);
304	struct drm_display_mode *mode, *next;
305
306	list_for_each_entry_safe(mode, next, &connector->base.probed_modes, head) {
307		drm_dbg_kms(&i915->drm,
308			    "[CONNECTOR:%d:%s] not using EDID mode: " DRM_MODE_FMT "\n",
309			    connector->base.base.id, connector->base.name,
310			    DRM_MODE_ARG(mode));
311		list_del(&mode->head);
312		drm_mode_destroy(&i915->drm, mode);
313	}
314}
315
316void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
317				      bool use_alt_fixed_modes)
318{
319	intel_panel_add_edid_preferred_mode(connector);
320	if (intel_panel_preferred_fixed_mode(connector) && use_alt_fixed_modes)
321		intel_panel_add_edid_alt_fixed_modes(connector);
322	intel_panel_destroy_probed_modes(connector);
323}
324
325static void intel_panel_add_fixed_mode(struct intel_connector *connector,
326				       struct drm_display_mode *fixed_mode,
327				       const char *type)
328{
329	struct drm_i915_private *i915 = to_i915(connector->base.dev);
330	struct drm_display_info *info = &connector->base.display_info;
 
 
 
 
331
 
 
332	if (!fixed_mode)
333		return;
 
 
334
335	fixed_mode->type |= DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
 
 
336
337	info->width_mm = fixed_mode->width_mm;
338	info->height_mm = fixed_mode->height_mm;
339
340	drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] using %s fixed mode: " DRM_MODE_FMT "\n",
341		    connector->base.base.id, connector->base.name, type,
342		    DRM_MODE_ARG(fixed_mode));
343
344	list_add_tail(&fixed_mode->head, &connector->panel.fixed_modes);
345}
346
347void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector)
348{
349	struct drm_i915_private *i915 = to_i915(connector->base.dev);
350	const struct drm_display_mode *mode;
351
352	mode = connector->panel.vbt.lfp_lvds_vbt_mode;
353	if (!mode)
354		return;
355
356	intel_panel_add_fixed_mode(connector,
357				   drm_mode_duplicate(&i915->drm, mode),
358				   "VBT LFP");
359}
360
361void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector)
362{
363	struct drm_i915_private *i915 = to_i915(connector->base.dev);
364	const struct drm_display_mode *mode;
365
366	mode = connector->panel.vbt.sdvo_lvds_vbt_mode;
367	if (!mode)
368		return;
369
370	intel_panel_add_fixed_mode(connector,
371				   drm_mode_duplicate(&i915->drm, mode),
372				   "VBT SDVO");
373}
374
375void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector,
376					struct intel_encoder *encoder)
377{
378	intel_panel_add_fixed_mode(connector,
379				   intel_encoder_current_mode(encoder),
380				   "current (BIOS)");
381}
382
383/* adjusted_mode has been preset to be the panel's fixed mode */
384static int pch_panel_fitting(struct intel_crtc_state *crtc_state,
385			     const struct drm_connector_state *conn_state)
 
 
386{
387	const struct drm_display_mode *adjusted_mode =
388		&crtc_state->hw.adjusted_mode;
389	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
390	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
391	int x, y, width, height;
392
393	/* Native modes don't need fitting */
394	if (adjusted_mode->crtc_hdisplay == pipe_src_w &&
395	    adjusted_mode->crtc_vdisplay == pipe_src_h &&
396	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420)
397		return 0;
398
399	switch (conn_state->scaling_mode) {
400	case DRM_MODE_SCALE_CENTER:
401		width = pipe_src_w;
402		height = pipe_src_h;
403		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
404		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
405		break;
406
407	case DRM_MODE_SCALE_ASPECT:
408		/* Scale but preserve the aspect ratio */
409		{
410			u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
411			u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
 
 
412			if (scaled_width > scaled_height) { /* pillar */
413				width = scaled_height / pipe_src_h;
414				if (width & 1)
415					width++;
416				x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
417				y = 0;
418				height = adjusted_mode->crtc_vdisplay;
419			} else if (scaled_width < scaled_height) { /* letter */
420				height = scaled_width / pipe_src_w;
421				if (height & 1)
422				    height++;
423				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
424				x = 0;
425				width = adjusted_mode->crtc_hdisplay;
426			} else {
427				x = y = 0;
428				width = adjusted_mode->crtc_hdisplay;
429				height = adjusted_mode->crtc_vdisplay;
430			}
431		}
432		break;
433
434	case DRM_MODE_SCALE_NONE:
435		WARN_ON(adjusted_mode->crtc_hdisplay != pipe_src_w);
436		WARN_ON(adjusted_mode->crtc_vdisplay != pipe_src_h);
437		fallthrough;
438	case DRM_MODE_SCALE_FULLSCREEN:
439		x = y = 0;
440		width = adjusted_mode->crtc_hdisplay;
441		height = adjusted_mode->crtc_vdisplay;
442		break;
443
444	default:
445		MISSING_CASE(conn_state->scaling_mode);
446		return -EINVAL;
447	}
448
449	drm_rect_init(&crtc_state->pch_pfit.dst,
450		      x, y, width, height);
451	crtc_state->pch_pfit.enabled = true;
452
453	return 0;
454}
455
456static void
457centre_horizontally(struct drm_display_mode *adjusted_mode,
458		    int width)
459{
460	u32 border, sync_pos, blank_width, sync_width;
461
462	/* keep the hsync and hblank widths constant */
463	sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
464	blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
465	sync_pos = (blank_width - sync_width + 1) / 2;
466
467	border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
468	border += border & 1; /* make the border even */
469
470	adjusted_mode->crtc_hdisplay = width;
471	adjusted_mode->crtc_hblank_start = width + border;
472	adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
473
474	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
475	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
476}
477
478static void
479centre_vertically(struct drm_display_mode *adjusted_mode,
480		  int height)
481{
482	u32 border, sync_pos, blank_width, sync_width;
483
484	/* keep the vsync and vblank widths constant */
485	sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
486	blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
487	sync_pos = (blank_width - sync_width + 1) / 2;
488
489	border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
490
491	adjusted_mode->crtc_vdisplay = height;
492	adjusted_mode->crtc_vblank_start = height + border;
493	adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;
494
495	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
496	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
497}
498
499static u32 panel_fitter_scaling(u32 source, u32 target)
500{
501	/*
502	 * Floating point operation is not supported. So the FACTOR
503	 * is defined, which can avoid the floating point computation
504	 * when calculating the panel ratio.
505	 */
506#define ACCURACY 12
507#define FACTOR (1 << ACCURACY)
508	u32 ratio = source * FACTOR / target;
509	return (FACTOR * ratio + FACTOR/2) / FACTOR;
510}
511
512static void i965_scale_aspect(struct intel_crtc_state *crtc_state,
513			      u32 *pfit_control)
514{
515	const struct drm_display_mode *adjusted_mode =
516		&crtc_state->hw.adjusted_mode;
517	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
518	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
519	u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
520	u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
521
522	/* 965+ is easy, it does everything in hw */
523	if (scaled_width > scaled_height)
524		*pfit_control |= PFIT_ENABLE |
525			PFIT_SCALING_PILLAR;
526	else if (scaled_width < scaled_height)
527		*pfit_control |= PFIT_ENABLE |
528			PFIT_SCALING_LETTER;
529	else if (adjusted_mode->crtc_hdisplay != pipe_src_w)
530		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
531}
532
533static void i9xx_scale_aspect(struct intel_crtc_state *crtc_state,
534			      u32 *pfit_control, u32 *pfit_pgm_ratios,
535			      u32 *border)
536{
537	struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
538	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
539	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
540	u32 scaled_width = adjusted_mode->crtc_hdisplay * pipe_src_h;
541	u32 scaled_height = pipe_src_w * adjusted_mode->crtc_vdisplay;
542	u32 bits;
543
544	/*
545	 * For earlier chips we have to calculate the scaling
546	 * ratio by hand and program it into the
547	 * PFIT_PGM_RATIO register
548	 */
549	if (scaled_width > scaled_height) { /* pillar */
550		centre_horizontally(adjusted_mode,
551				    scaled_height / pipe_src_h);
 
552
553		*border = LVDS_BORDER_ENABLE;
554		if (pipe_src_h != adjusted_mode->crtc_vdisplay) {
555			bits = panel_fitter_scaling(pipe_src_h,
556						    adjusted_mode->crtc_vdisplay);
557
558			*pfit_pgm_ratios |= (PFIT_HORIZ_SCALE(bits) |
559					     PFIT_VERT_SCALE(bits));
560			*pfit_control |= (PFIT_ENABLE |
561					  PFIT_VERT_INTERP_BILINEAR |
562					  PFIT_HORIZ_INTERP_BILINEAR);
563		}
564	} else if (scaled_width < scaled_height) { /* letter */
565		centre_vertically(adjusted_mode,
566				  scaled_width / pipe_src_w);
 
567
568		*border = LVDS_BORDER_ENABLE;
569		if (pipe_src_w != adjusted_mode->crtc_hdisplay) {
570			bits = panel_fitter_scaling(pipe_src_w,
571						    adjusted_mode->crtc_hdisplay);
572
573			*pfit_pgm_ratios |= (PFIT_HORIZ_SCALE(bits) |
574					     PFIT_VERT_SCALE(bits));
575			*pfit_control |= (PFIT_ENABLE |
576					  PFIT_VERT_INTERP_BILINEAR |
577					  PFIT_HORIZ_INTERP_BILINEAR);
578		}
579	} else {
580		/* Aspects match, Let hw scale both directions */
581		*pfit_control |= (PFIT_ENABLE |
582				  PFIT_VERT_AUTO_SCALE |
583				  PFIT_HORIZ_AUTO_SCALE |
584				  PFIT_VERT_INTERP_BILINEAR |
585				  PFIT_HORIZ_INTERP_BILINEAR);
586	}
587}
588
589static int gmch_panel_fitting(struct intel_crtc_state *crtc_state,
590			      const struct drm_connector_state *conn_state)
 
591{
592	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
593	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
594	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
595	struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
596	int pipe_src_w = drm_rect_width(&crtc_state->pipe_src);
597	int pipe_src_h = drm_rect_height(&crtc_state->pipe_src);
598
599	/* Native modes don't need fitting */
600	if (adjusted_mode->crtc_hdisplay == pipe_src_w &&
601	    adjusted_mode->crtc_vdisplay == pipe_src_h)
602		goto out;
603
604	switch (conn_state->scaling_mode) {
605	case DRM_MODE_SCALE_CENTER:
606		/*
607		 * For centered modes, we have to calculate border widths &
608		 * heights and modify the values programmed into the CRTC.
609		 */
610		centre_horizontally(adjusted_mode, pipe_src_w);
611		centre_vertically(adjusted_mode, pipe_src_h);
612		border = LVDS_BORDER_ENABLE;
613		break;
614	case DRM_MODE_SCALE_ASPECT:
615		/* Scale but preserve the aspect ratio */
616		if (DISPLAY_VER(dev_priv) >= 4)
617			i965_scale_aspect(crtc_state, &pfit_control);
618		else
619			i9xx_scale_aspect(crtc_state, &pfit_control,
620					  &pfit_pgm_ratios, &border);
621		break;
622	case DRM_MODE_SCALE_FULLSCREEN:
623		/*
624		 * Full scaling, even if it changes the aspect ratio.
625		 * Fortunately this is all done for us in hw.
626		 */
627		if (pipe_src_h != adjusted_mode->crtc_vdisplay ||
628		    pipe_src_w != adjusted_mode->crtc_hdisplay) {
629			pfit_control |= PFIT_ENABLE;
630			if (DISPLAY_VER(dev_priv) >= 4)
631				pfit_control |= PFIT_SCALING_AUTO;
632			else
633				pfit_control |= (PFIT_VERT_AUTO_SCALE |
634						 PFIT_VERT_INTERP_BILINEAR |
635						 PFIT_HORIZ_AUTO_SCALE |
636						 PFIT_HORIZ_INTERP_BILINEAR);
637		}
638		break;
639	default:
640		MISSING_CASE(conn_state->scaling_mode);
641		return -EINVAL;
642	}
643
644	/* 965+ wants fuzzy fitting */
645	/* FIXME: handle multiple panels by failing gracefully */
646	if (DISPLAY_VER(dev_priv) >= 4)
647		pfit_control |= PFIT_PIPE(crtc->pipe) | PFIT_FILTER_FUZZY;
 
648
649out:
650	if ((pfit_control & PFIT_ENABLE) == 0) {
651		pfit_control = 0;
652		pfit_pgm_ratios = 0;
653	}
654
655	/* Make sure pre-965 set dither correctly for 18bpp panels. */
656	if (DISPLAY_VER(dev_priv) < 4 && crtc_state->pipe_bpp == 18)
657		pfit_control |= PFIT_PANEL_8TO6_DITHER_ENABLE;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
658
659	crtc_state->gmch_pfit.control = pfit_control;
660	crtc_state->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
661	crtc_state->gmch_pfit.lvds_border_bits = border;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662
663	return 0;
664}
665
666int intel_panel_fitting(struct intel_crtc_state *crtc_state,
667			const struct drm_connector_state *conn_state)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
668{
669	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
670	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
671
672	if (HAS_GMCH(i915))
673		return gmch_panel_fitting(crtc_state, conn_state);
674	else
675		return pch_panel_fitting(crtc_state, conn_state);
 
 
676}
677
678enum drm_connector_status
679intel_panel_detect(struct drm_connector *connector, bool force)
 
 
 
 
680{
681	struct drm_i915_private *i915 = to_i915(connector->dev);
 
682
683	if (!intel_display_device_enabled(i915))
684		return connector_status_disconnected;
 
 
 
 
 
 
 
 
685
686	return connector_status_connected;
687}
688
689enum drm_mode_status
690intel_panel_mode_valid(struct intel_connector *connector,
691		       const struct drm_display_mode *mode)
692{
693	const struct drm_display_mode *fixed_mode =
694		intel_panel_fixed_mode(connector, mode);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
695
696	if (!fixed_mode)
697		return MODE_OK;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
698
699	if (mode->hdisplay != fixed_mode->hdisplay)
700		return MODE_PANEL;
701
702	if (mode->vdisplay != fixed_mode->vdisplay)
703		return MODE_PANEL;
 
 
704
705	if (drm_mode_vrefresh(mode) != drm_mode_vrefresh(fixed_mode))
706		return MODE_PANEL;
707
708	return MODE_OK;
709}
710
711void intel_panel_init_alloc(struct intel_connector *connector)
 
712{
 
713	struct intel_panel *panel = &connector->panel;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
714
715	connector->panel.vbt.panel_type = -1;
716	connector->panel.vbt.backlight.controller = -1;
717	INIT_LIST_HEAD(&panel->fixed_modes);
 
 
 
 
 
718}
719
720int intel_panel_init(struct intel_connector *connector,
721		     const struct drm_edid *fixed_edid)
722{
 
723	struct intel_panel *panel = &connector->panel;
 
724
725	panel->fixed_edid = fixed_edid;
 
 
 
 
 
 
726
727	intel_backlight_init_funcs(panel);
 
 
 
 
728
729	if (!has_drrs_modes(connector))
730		connector->panel.vbt.drrs_type = DRRS_TYPE_NONE;
 
 
 
 
 
 
731
732	drm_dbg_kms(connector->base.dev,
733		    "[CONNECTOR:%d:%s] DRRS type: %s\n",
734		    connector->base.base.id, connector->base.name,
735		    intel_drrs_type_str(intel_panel_drrs_type(connector)));
 
 
736
737	return 0;
738}
739
740void intel_panel_fini(struct intel_connector *connector)
 
 
741{
 
 
742	struct intel_panel *panel = &connector->panel;
743	struct drm_display_mode *fixed_mode, *next;
744
745	if (!IS_ERR_OR_NULL(panel->fixed_edid))
746		drm_edid_free(panel->fixed_edid);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747
748	intel_backlight_destroy(panel);
 
 
 
 
 
 
749
750	intel_bios_fini_panel(panel);
 
 
751
752	list_for_each_entry_safe(fixed_mode, next, &panel->fixed_modes, head) {
753		list_del(&fixed_mode->head);
754		drm_mode_destroy(connector->base.dev, fixed_mode);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
756}