Subversion Repositories Kolibri OS

Rev

Rev 4293 | Rev 5060 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4293 Rev 4560
Line 48... Line 48...
48
void
48
void
49
intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
49
intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
50
			struct intel_crtc_config *pipe_config,
50
			struct intel_crtc_config *pipe_config,
51
			int fitting_mode)
51
			int fitting_mode)
52
{
52
{
53
	struct drm_display_mode *mode, *adjusted_mode;
53
	struct drm_display_mode *adjusted_mode;
54
	int x, y, width, height;
54
	int x, y, width, height;
Line 55... Line -...
55
 
-
 
56
	mode = &pipe_config->requested_mode;
55
 
Line 57... Line 56...
57
	adjusted_mode = &pipe_config->adjusted_mode;
56
	adjusted_mode = &pipe_config->adjusted_mode;
Line 58... Line 57...
58
 
57
 
59
	x = y = width = height = 0;
58
	x = y = width = height = 0;
60
 
59
 
61
	/* Native modes don't need fitting */
60
	/* Native modes don't need fitting */
Line 62... Line 61...
62
	if (adjusted_mode->hdisplay == mode->hdisplay &&
61
	if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
63
	    adjusted_mode->vdisplay == mode->vdisplay)
62
	    adjusted_mode->vdisplay == pipe_config->pipe_src_h)
64
		goto done;
63
		goto done;
65
 
64
 
66
	switch (fitting_mode) {
65
	switch (fitting_mode) {
67
	case DRM_MODE_SCALE_CENTER:
66
	case DRM_MODE_SCALE_CENTER:
68
		width = mode->hdisplay;
67
		width = pipe_config->pipe_src_w;
Line 69... Line 68...
69
		height = mode->vdisplay;
68
		height = pipe_config->pipe_src_h;
70
		x = (adjusted_mode->hdisplay - width + 1)/2;
69
		x = (adjusted_mode->hdisplay - width + 1)/2;
71
		y = (adjusted_mode->vdisplay - height + 1)/2;
70
		y = (adjusted_mode->vdisplay - height + 1)/2;
72
		break;
71
		break;
-
 
72
 
73
 
73
	case DRM_MODE_SCALE_ASPECT:
-
 
74
		/* Scale but preserve the aspect ratio */
74
	case DRM_MODE_SCALE_ASPECT:
75
		{
75
		/* Scale but preserve the aspect ratio */
76
			u32 scaled_width = adjusted_mode->hdisplay
76
		{
77
				* pipe_config->pipe_src_h;
77
			u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
78
			u32 scaled_height = pipe_config->pipe_src_w
78
			u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
79
				* adjusted_mode->vdisplay;
79
			if (scaled_width > scaled_height) { /* pillar */
80
			if (scaled_width > scaled_height) { /* pillar */
80
				width = scaled_height / mode->vdisplay;
81
				width = scaled_height / pipe_config->pipe_src_h;
81
				if (width & 1)
82
				if (width & 1)
82
				    	width++;
83
				    	width++;
83
				x = (adjusted_mode->hdisplay - width + 1) / 2;
84
				x = (adjusted_mode->hdisplay - width + 1) / 2;
84
				y = 0;
85
				y = 0;
85
				height = adjusted_mode->vdisplay;
86
				height = adjusted_mode->vdisplay;
86
			} else if (scaled_width < scaled_height) { /* letter */
87
			} else if (scaled_width < scaled_height) { /* letter */
87
				height = scaled_width / mode->hdisplay;
88
				height = scaled_width / pipe_config->pipe_src_w;
Line 169... Line 170...
169
#define FACTOR (1 << ACCURACY)
170
#define FACTOR (1 << ACCURACY)
170
	u32 ratio = source * FACTOR / target;
171
	u32 ratio = source * FACTOR / target;
171
	return (FACTOR * ratio + FACTOR/2) / FACTOR;
172
	return (FACTOR * ratio + FACTOR/2) / FACTOR;
172
}
173
}
Line 173... Line -...
173
 
-
 
174
void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
174
 
175
			      struct intel_crtc_config *pipe_config,
175
static void i965_scale_aspect(struct intel_crtc_config *pipe_config,
176
			      int fitting_mode)
176
			      u32 *pfit_control)
177
{
-
 
178
	struct drm_device *dev = intel_crtc->base.dev;
-
 
179
	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
177
{
180
	struct drm_display_mode *mode, *adjusted_mode;
-
 
181
 
-
 
182
	mode = &pipe_config->requested_mode;
-
 
183
	adjusted_mode = &pipe_config->adjusted_mode;
-
 
184
 
-
 
185
	/* Native modes don't need fitting */
-
 
186
	if (adjusted_mode->hdisplay == mode->hdisplay &&
-
 
187
	    adjusted_mode->vdisplay == mode->vdisplay)
-
 
188
		goto out;
-
 
189
 
-
 
190
	switch (fitting_mode) {
-
 
191
	case DRM_MODE_SCALE_CENTER:
-
 
192
		/*
-
 
193
		 * For centered modes, we have to calculate border widths &
-
 
194
		 * heights and modify the values programmed into the CRTC.
-
 
195
		 */
-
 
196
		centre_horizontally(adjusted_mode, mode->hdisplay);
-
 
197
		centre_vertically(adjusted_mode, mode->vdisplay);
-
 
198
		border = LVDS_BORDER_ENABLE;
-
 
199
		break;
-
 
200
	case DRM_MODE_SCALE_ASPECT:
-
 
201
		/* Scale but preserve the aspect ratio */
-
 
202
		if (INTEL_INFO(dev)->gen >= 4) {
178
	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
203
			u32 scaled_width = adjusted_mode->hdisplay *
179
			u32 scaled_width = adjusted_mode->hdisplay *
204
				mode->vdisplay;
180
		pipe_config->pipe_src_h;
205
			u32 scaled_height = mode->hdisplay *
181
	u32 scaled_height = pipe_config->pipe_src_w *
Line 206... Line 182...
206
				adjusted_mode->vdisplay;
182
				adjusted_mode->vdisplay;
207
 
183
 
208
			/* 965+ is easy, it does everything in hw */
184
			/* 965+ is easy, it does everything in hw */
209
			if (scaled_width > scaled_height)
185
			if (scaled_width > scaled_height)
210
				pfit_control |= PFIT_ENABLE |
186
		*pfit_control |= PFIT_ENABLE |
211
					PFIT_SCALING_PILLAR;
187
					PFIT_SCALING_PILLAR;
212
			else if (scaled_width < scaled_height)
188
			else if (scaled_width < scaled_height)
213
				pfit_control |= PFIT_ENABLE |
189
		*pfit_control |= PFIT_ENABLE |
214
					PFIT_SCALING_LETTER;
190
					PFIT_SCALING_LETTER;
-
 
191
	else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w)
-
 
192
		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
-
 
193
}
-
 
194
 
215
			else if (adjusted_mode->hdisplay != mode->hdisplay)
195
static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config,
-
 
196
			      u32 *pfit_control, u32 *pfit_pgm_ratios,
-
 
197
			      u32 *border)
216
				pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
198
{
217
		} else {
199
	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
218
			u32 scaled_width = adjusted_mode->hdisplay *
200
			u32 scaled_width = adjusted_mode->hdisplay *
219
				mode->vdisplay;
201
		pipe_config->pipe_src_h;
-
 
202
	u32 scaled_height = pipe_config->pipe_src_w *
-
 
203
				adjusted_mode->vdisplay;
220
			u32 scaled_height = mode->hdisplay *
204
	u32 bits;
221
				adjusted_mode->vdisplay;
205
 
222
			/*
206
			/*
223
			 * For earlier chips we have to calculate the scaling
207
			 * For earlier chips we have to calculate the scaling
224
			 * ratio by hand and program it into the
208
			 * ratio by hand and program it into the
225
			 * PFIT_PGM_RATIO register
209
			 * PFIT_PGM_RATIO register
226
			 */
210
			 */
227
			if (scaled_width > scaled_height) { /* pillar */
211
			if (scaled_width > scaled_height) { /* pillar */
228
				centre_horizontally(adjusted_mode,
212
				centre_horizontally(adjusted_mode,
Line 229... Line 213...
229
						    scaled_height /
213
						    scaled_height /
230
						    mode->vdisplay);
214
				    pipe_config->pipe_src_h);
231
 
215
 
-
 
216
		*border = LVDS_BORDER_ENABLE;
-
 
217
		if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) {
232
				border = LVDS_BORDER_ENABLE;
218
			bits = panel_fitter_scaling(pipe_config->pipe_src_h,
233
				if (mode->vdisplay != adjusted_mode->vdisplay) {
219
						    adjusted_mode->vdisplay);
234
					u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay);
220
 
235
					pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
221
			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
236
							    bits << PFIT_VERT_SCALE_SHIFT);
222
							    bits << PFIT_VERT_SCALE_SHIFT);
237
					pfit_control |= (PFIT_ENABLE |
223
			*pfit_control |= (PFIT_ENABLE |
238
							 VERT_INTERP_BILINEAR |
224
							 VERT_INTERP_BILINEAR |
239
							 HORIZ_INTERP_BILINEAR);
225
							 HORIZ_INTERP_BILINEAR);
240
				}
226
				}
241
			} else if (scaled_width < scaled_height) { /* letter */
227
			} else if (scaled_width < scaled_height) { /* letter */
Line 242... Line 228...
242
				centre_vertically(adjusted_mode,
228
				centre_vertically(adjusted_mode,
243
						  scaled_width /
229
						  scaled_width /
244
						  mode->hdisplay);
230
				  pipe_config->pipe_src_w);
-
 
231
 
-
 
232
		*border = LVDS_BORDER_ENABLE;
245
 
233
		if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
246
				border = LVDS_BORDER_ENABLE;
234
			bits = panel_fitter_scaling(pipe_config->pipe_src_w,
247
				if (mode->hdisplay != adjusted_mode->hdisplay) {
235
						    adjusted_mode->hdisplay);
248
					u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay);
236
 
249
					pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
237
			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
250
							    bits << PFIT_VERT_SCALE_SHIFT);
238
							    bits << PFIT_VERT_SCALE_SHIFT);
251
					pfit_control |= (PFIT_ENABLE |
239
			*pfit_control |= (PFIT_ENABLE |
252
							 VERT_INTERP_BILINEAR |
240
							 VERT_INTERP_BILINEAR |
253
							 HORIZ_INTERP_BILINEAR);
241
							 HORIZ_INTERP_BILINEAR);
254
				}
242
				}
255
			} else {
243
			} else {
256
				/* Aspects match, Let hw scale both directions */
244
				/* Aspects match, Let hw scale both directions */
257
				pfit_control |= (PFIT_ENABLE |
245
		*pfit_control |= (PFIT_ENABLE |
258
						 VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
246
						 VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
-
 
247
						 VERT_INTERP_BILINEAR |
-
 
248
						 HORIZ_INTERP_BILINEAR);
-
 
249
			}
-
 
250
}
-
 
251
 
-
 
252
void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
-
 
253
			      struct intel_crtc_config *pipe_config,
-
 
254
			      int fitting_mode)
-
 
255
{
-
 
256
	struct drm_device *dev = intel_crtc->base.dev;
-
 
257
	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
-
 
258
	struct drm_display_mode *adjusted_mode;
-
 
259
 
-
 
260
	adjusted_mode = &pipe_config->adjusted_mode;
-
 
261
 
-
 
262
	/* Native modes don't need fitting */
-
 
263
	if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
-
 
264
	    adjusted_mode->vdisplay == pipe_config->pipe_src_h)
-
 
265
		goto out;
-
 
266
 
-
 
267
	switch (fitting_mode) {
-
 
268
	case DRM_MODE_SCALE_CENTER:
-
 
269
		/*
-
 
270
		 * For centered modes, we have to calculate border widths &
-
 
271
		 * heights and modify the values programmed into the CRTC.
-
 
272
		 */
-
 
273
		centre_horizontally(adjusted_mode, pipe_config->pipe_src_w);
-
 
274
		centre_vertically(adjusted_mode, pipe_config->pipe_src_h);
-
 
275
		border = LVDS_BORDER_ENABLE;
-
 
276
		break;
-
 
277
	case DRM_MODE_SCALE_ASPECT:
-
 
278
		/* Scale but preserve the aspect ratio */
-
 
279
		if (INTEL_INFO(dev)->gen >= 4)
259
						 VERT_INTERP_BILINEAR |
280
			i965_scale_aspect(pipe_config, &pfit_control);
260
						 HORIZ_INTERP_BILINEAR);
281
		else
261
			}
282
			i9xx_scale_aspect(pipe_config, &pfit_control,
262
		}
283
					  &pfit_pgm_ratios, &border);
263
		break;
284
		break;
264
	case DRM_MODE_SCALE_FULLSCREEN:
285
	case DRM_MODE_SCALE_FULLSCREEN:
265
		/*
286
		/*
266
		 * Full scaling, even if it changes the aspect ratio.
287
		 * Full scaling, even if it changes the aspect ratio.
267
		 * Fortunately this is all done for us in hw.
288
		 * Fortunately this is all done for us in hw.
268
		 */
289
		 */
269
		if (mode->vdisplay != adjusted_mode->vdisplay ||
290
		if (pipe_config->pipe_src_h != adjusted_mode->vdisplay ||
270
		    mode->hdisplay != adjusted_mode->hdisplay) {
291
		    pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
271
			pfit_control |= PFIT_ENABLE;
292
			pfit_control |= PFIT_ENABLE;
Line 302... Line 323...
302
	pipe_config->gmch_pfit.control = pfit_control;
323
	pipe_config->gmch_pfit.control = pfit_control;
303
	pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
324
	pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
304
	pipe_config->gmch_pfit.lvds_border_bits = border;
325
	pipe_config->gmch_pfit.lvds_border_bits = border;
305
}
326
}
Line 306... Line -...
306
 
-
 
307
static int is_backlight_combination_mode(struct drm_device *dev)
-
 
308
{
-
 
309
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
310
 
-
 
311
	if (INTEL_INFO(dev)->gen >= 4)
-
 
312
		return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
-
 
313
 
-
 
314
	if (IS_GEN2(dev))
-
 
315
		return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE;
-
 
316
 
-
 
317
	return 0;
-
 
318
}
-
 
319
 
-
 
320
/* XXX: query mode clock or hardware clock and program max PWM appropriately
-
 
321
 * when it's 0.
-
 
322
 */
-
 
323
static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
-
 
324
{
-
 
325
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
326
	u32 val;
-
 
327
 
-
 
328
//   WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight.lock));
-
 
329
 
-
 
330
	/* Restore the CTL value if it lost, e.g. GPU reset */
-
 
331
 
-
 
332
	if (HAS_PCH_SPLIT(dev_priv->dev)) {
-
 
333
		val = I915_READ(BLC_PWM_PCH_CTL2);
-
 
334
		if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
-
 
335
			dev_priv->regfile.saveBLC_PWM_CTL2 = val;
-
 
336
		} else if (val == 0) {
-
 
337
			val = dev_priv->regfile.saveBLC_PWM_CTL2;
-
 
338
			I915_WRITE(BLC_PWM_PCH_CTL2, val);
-
 
339
		}
-
 
340
	} else {
-
 
341
		val = I915_READ(BLC_PWM_CTL);
-
 
342
		if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
-
 
343
			dev_priv->regfile.saveBLC_PWM_CTL = val;
-
 
344
			if (INTEL_INFO(dev)->gen >= 4)
-
 
345
				dev_priv->regfile.saveBLC_PWM_CTL2 =
-
 
346
					I915_READ(BLC_PWM_CTL2);
-
 
347
		} else if (val == 0) {
-
 
348
			val = dev_priv->regfile.saveBLC_PWM_CTL;
-
 
349
			I915_WRITE(BLC_PWM_CTL, val);
-
 
350
			if (INTEL_INFO(dev)->gen >= 4)
-
 
351
			I915_WRITE(BLC_PWM_CTL2,
-
 
352
					   dev_priv->regfile.saveBLC_PWM_CTL2);
-
 
353
		}
-
 
354
	}
-
 
355
 
-
 
356
	return val;
-
 
357
}
-
 
358
 
-
 
359
static u32 intel_panel_get_max_backlight(struct drm_device *dev)
-
 
360
{
-
 
361
	u32 max;
-
 
362
 
-
 
363
	max = i915_read_blc_pwm_ctl(dev);
-
 
364
 
-
 
365
	if (HAS_PCH_SPLIT(dev)) {
-
 
366
		max >>= 16;
-
 
367
	} else {
-
 
368
		if (INTEL_INFO(dev)->gen < 4)
-
 
369
			max >>= 17;
-
 
370
		else
-
 
371
			max >>= 16;
-
 
372
 
-
 
373
		if (is_backlight_combination_mode(dev))
-
 
374
			max *= 0xff;
-
 
375
	}
-
 
376
 
-
 
377
	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
-
 
378
 
-
 
379
	return max;
-
 
380
}
-
 
381
 
327
 
382
static int i915_panel_invert_brightness;
328
static int i915_panel_invert_brightness;
383
MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
329
MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
384
	"(-1 force normal, 0 machine defaults, 1 force inversion), please "
330
	"(-1 force normal, 0 machine defaults, 1 force inversion), please "
385
	"report PCI device ID, subsystem vendor and subsystem device ID "
331
	"report PCI device ID, subsystem vendor and subsystem device ID "
386
	"to dri-devel@lists.freedesktop.org, if your machine needs it. "
332
	"to dri-devel@lists.freedesktop.org, if your machine needs it. "
387
	"It will then be included in an upcoming module version.");
333
	"It will then be included in an upcoming module version.");
388
module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
334
module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
-
 
335
static u32 intel_panel_compute_brightness(struct intel_connector *connector,
389
static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
336
					  u32 val)
-
 
337
{
390
{
338
	struct drm_device *dev = connector->base.dev;
-
 
339
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
340
	struct intel_panel *panel = &connector->panel;
-
 
341
 
Line 391... Line 342...
391
	struct drm_i915_private *dev_priv = dev->dev_private;
342
	WARN_ON(panel->backlight.max == 0);
392
 
343
 
Line 393... Line 344...
393
	if (i915_panel_invert_brightness < 0)
344
	if (i915_panel_invert_brightness < 0)
394
		return val;
345
		return val;
395
 
-
 
396
	if (i915_panel_invert_brightness > 0 ||
-
 
397
	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
346
 
398
		u32 max = intel_panel_get_max_backlight(dev);
347
	if (i915_panel_invert_brightness > 0 ||
Line 399... Line 348...
399
		if (max)
348
	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
400
			return max - val;
349
		return panel->backlight.max - val;
Line 401... Line 350...
401
	}
350
	}
402
 
351
 
-
 
352
	return val;
403
	return val;
353
}
404
}
-
 
405
 
-
 
Line -... Line 354...
-
 
354
 
-
 
355
static u32 bdw_get_backlight(struct intel_connector *connector)
-
 
356
{
-
 
357
	struct drm_device *dev = connector->base.dev;
-
 
358
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
359
 
406
static u32 intel_panel_get_backlight(struct drm_device *dev)
360
	return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
-
 
361
}
-
 
362
 
-
 
363
static u32 pch_get_backlight(struct intel_connector *connector)
-
 
364
{
-
 
365
	struct drm_device *dev = connector->base.dev;
-
 
366
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
367
 
-
 
368
	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
-
 
369
}
-
 
370
 
Line 407... Line -...
407
{
-
 
408
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
409
	u32 val;
-
 
410
	unsigned long flags;
371
static u32 i9xx_get_backlight(struct intel_connector *connector)
411
 
372
{
412
	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
373
	struct drm_device *dev = connector->base.dev;
Line 413... Line 374...
413
 
374
	struct drm_i915_private *dev_priv = dev->dev_private;
414
	if (HAS_PCH_SPLIT(dev)) {
375
	struct intel_panel *panel = &connector->panel;
Line 415... Line 376...
415
		val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
376
	u32 val;
416
	} else {
377
 
417
		val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
378
	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
-
 
379
	if (INTEL_INFO(dev)->gen < 4)
-
 
380
		val >>= 1;
-
 
381
 
-
 
382
	if (panel->backlight.combination_mode) {
-
 
383
		u8 lbpc;
-
 
384
 
-
 
385
		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
-
 
386
		val *= lbpc;
-
 
387
	}
418
		if (INTEL_INFO(dev)->gen < 4)
388
 
Line -... Line 389...
-
 
389
	return val;
-
 
390
}
-
 
391
 
-
 
392
static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe)
-
 
393
{
-
 
394
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
395
 
-
 
396
	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
-
 
397
}
-
 
398
 
-
 
399
static u32 vlv_get_backlight(struct intel_connector *connector)
-
 
400
{
-
 
401
	struct drm_device *dev = connector->base.dev;
-
 
402
	enum pipe pipe = intel_get_pipe_from_connector(connector);
-
 
403
 
-
 
404
	return _vlv_get_backlight(dev, pipe);
-
 
405
}
-
 
406
 
419
			val >>= 1;
407
static u32 intel_panel_get_backlight(struct intel_connector *connector)
Line 420... Line 408...
420
 
408
{
Line 421... Line 409...
421
		if (is_backlight_combination_mode(dev)) {
409
	struct drm_device *dev = connector->base.dev;
422
			u8 lbpc;
410
	struct drm_i915_private *dev_priv = dev->dev_private;
423
 
411
	u32 val;
Line 424... Line 412...
424
			pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
412
	unsigned long flags;
425
			val *= lbpc;
413
 
-
 
414
	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
426
		}
415
 
427
	}
416
	val = dev_priv->display.get_backlight(connector);
428
 
417
	val = intel_panel_compute_brightness(connector, val);
429
	val = intel_panel_compute_brightness(dev, val);
418
 
Line 430... Line 419...
430
 
419
	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
431
	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
420
 
-
 
421
	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
432
 
422
	return val;
433
	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
423
}
Line 434... Line 424...
434
	return val;
424
 
435
}
425
static void bdw_set_backlight(struct intel_connector *connector, u32 level)
-
 
426
{
Line -... Line 427...
-
 
427
	struct drm_device *dev = connector->base.dev;
-
 
428
	struct drm_i915_private *dev_priv = dev->dev_private;
436
 
429
	u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-
 
430
	I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
437
static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
431
}
-
 
432
 
Line 438... Line -...
438
{
-
 
439
	struct drm_i915_private *dev_priv = dev->dev_private;
433
static void pch_set_backlight(struct intel_connector *connector, u32 level)
440
	u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-
 
Line 441... Line 434...
441
	I915_WRITE(BLC_PWM_CPU_CTL, val | level);
434
{
442
}
435
	struct drm_device *dev = connector->base.dev;
443
 
-
 
Line 444... Line 436...
444
static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level)
436
	struct drm_i915_private *dev_priv = dev->dev_private;
445
{
437
	u32 tmp;
446
	struct drm_i915_private *dev_priv = dev->dev_private;
438
 
447
	u32 tmp;
439
	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
Line 448... Line 440...
448
 
440
	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
449
	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
441
}
-
 
442
 
450
	level = intel_panel_compute_brightness(dev, level);
443
static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
451
 
444
{
-
 
445
	struct drm_device *dev = connector->base.dev;
-
 
446
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
447
	struct intel_panel *panel = &connector->panel;
452
	if (HAS_PCH_SPLIT(dev))
448
	u32 tmp, mask;
453
		return intel_pch_panel_set_backlight(dev, level);
449
 
Line -... Line 450...
-
 
450
	WARN_ON(panel->backlight.max == 0);
-
 
451
 
-
 
452
	if (panel->backlight.combination_mode) {
-
 
453
		u8 lbpc;
-
 
454
 
-
 
455
		lbpc = level * 0xfe / panel->backlight.max + 1;
-
 
456
		level /= lbpc;
-
 
457
		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
-
 
458
	}
-
 
459
 
-
 
460
	if (IS_GEN4(dev)) {
-
 
461
		mask = BACKLIGHT_DUTY_CYCLE_MASK;
-
 
462
	} else {
-
 
463
		level <<= 1;
-
 
464
		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
-
 
465
	}
-
 
466
 
-
 
467
	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
-
 
468
	I915_WRITE(BLC_PWM_CTL, tmp | level);
-
 
469
}
-
 
470
 
-
 
471
static void vlv_set_backlight(struct intel_connector *connector, u32 level)
-
 
472
{
454
 
473
	struct drm_device *dev = connector->base.dev;
455
	if (is_backlight_combination_mode(dev)) {
474
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
475
	enum pipe pipe = intel_get_pipe_from_connector(connector);
-
 
476
	u32 tmp;
-
 
477
 
-
 
478
	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-
 
479
	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
-
 
480
}
-
 
481
 
-
 
482
static void
-
 
483
intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
-
 
484
{
-
 
485
	struct drm_device *dev = connector->base.dev;
-
 
486
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
487
 
-
 
488
	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
-
 
489
 
-
 
490
	level = intel_panel_compute_brightness(connector, level);
-
 
491
	dev_priv->display.set_backlight(connector, level);
-
 
492
}
-
 
493
 
-
 
494
/* set backlight brightness to level in range [0..max] */
-
 
495
void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
-
 
496
			       u32 max)
-
 
497
{
-
 
498
	struct drm_device *dev = connector->base.dev;
-
 
499
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
500
	struct intel_panel *panel = &connector->panel;
-
 
501
	enum pipe pipe = intel_get_pipe_from_connector(connector);
-
 
502
	u32 freq;
-
 
503
	unsigned long flags;
-
 
504
 
-
 
505
	if (!panel->backlight.present || pipe == INVALID_PIPE)
-
 
506
		return;
-
 
507
 
-
 
508
	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
-
 
509
 
-
 
510
	WARN_ON(panel->backlight.max == 0);
-
 
511
 
-
 
512
	/* scale to hardware max, but be careful to not overflow */
-
 
513
	freq = panel->backlight.max;
-
 
514
	if (freq < max)
-
 
515
		level = level * freq / max;
-
 
516
	else
-
 
517
		level = freq / max * level;
-
 
518
 
-
 
519
	panel->backlight.level = level;
-
 
520
//	if (panel->backlight.device)
-
 
521
//		panel->backlight.device->props.brightness = level;
-
 
522
 
-
 
523
	if (panel->backlight.enabled)
456
		u32 max = intel_panel_get_max_backlight(dev);
524
		intel_panel_actually_set_backlight(connector, level);
-
 
525
 
-
 
526
	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
-
 
527
}
-
 
528
 
-
 
529
static void pch_disable_backlight(struct intel_connector *connector)
-
 
530
{
457
		u8 lbpc;
531
	struct drm_device *dev = connector->base.dev;
-
 
532
	struct drm_i915_private *dev_priv = dev->dev_private;
Line 458... Line 533...
458
 
533
	u32 tmp;
459
		/* we're screwed, but keep behaviour backwards compatible */
-
 
460
		if (!max)
-
 
Line 461... Line 534...
461
			max = 1;
534
 
462
 
535
	intel_panel_actually_set_backlight(connector, 0);
463
		lbpc = level * 0xfe / max + 1;
536
 
Line 464... Line 537...
464
		level /= lbpc;
537
	tmp = I915_READ(BLC_PWM_CPU_CTL2);
465
		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
538
	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
-
 
539
 
466
	}
540
	tmp = I915_READ(BLC_PWM_PCH_CTL1);
-
 
541
	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
-
 
542
}
-
 
543
 
-
 
544
static void i9xx_disable_backlight(struct intel_connector *connector)
-
 
545
{
-
 
546
	intel_panel_actually_set_backlight(connector, 0);
-
 
547
}
-
 
548
 
-
 
549
static void i965_disable_backlight(struct intel_connector *connector)
-
 
550
{
-
 
551
	struct drm_device *dev = connector->base.dev;
-
 
552
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
553
	u32 tmp;
-
 
554
 
-
 
555
	intel_panel_actually_set_backlight(connector, 0);
467
 
556
 
Line -... Line 557...
-
 
557
	tmp = I915_READ(BLC_PWM_CTL2);
-
 
558
	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
-
 
559
}
468
	tmp = I915_READ(BLC_PWM_CTL);
560
 
469
	if (INTEL_INFO(dev)->gen < 4)
561
static void vlv_disable_backlight(struct intel_connector *connector)
470
		level <<= 1;
562
{
471
		tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
563
	struct drm_device *dev = connector->base.dev;
472
	I915_WRITE(BLC_PWM_CTL, tmp | level);
564
	struct drm_i915_private *dev_priv = dev->dev_private;
Line 499... Line 591...
499
	if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) {
591
	if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) {
500
		DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
592
		DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
501
		return;
593
		return;
502
	}
594
	}
Line 503... Line 595...
503
 
595
 
504
	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
-
 
505
 
-
 
506
	dev_priv->backlight.enabled = false;
-
 
Line 507... Line 596...
507
	intel_panel_actually_set_backlight(dev, 0);
596
	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
508
 
597
 
Line 509... Line 598...
509
	if (INTEL_INFO(dev)->gen >= 4) {
598
	panel->backlight.enabled = false;
-
 
599
	dev_priv->display.disable_backlight(connector);
Line -... Line 600...
-
 
600
 
-
 
601
	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
-
 
602
}
510
		uint32_t reg, tmp;
603
 
-
 
604
static void bdw_enable_backlight(struct intel_connector *connector)
-
 
605
{
Line -... Line 606...
-
 
606
	struct drm_device *dev = connector->base.dev;
511
 
607
	struct drm_i915_private *dev_priv = dev->dev_private;
512
		reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
608
	struct intel_panel *panel = &connector->panel;
513
 
609
	u32 pch_ctl1, pch_ctl2;
514
		I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
610
 
515
 
-
 
516
		if (HAS_PCH_SPLIT(dev)) {
611
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
Line -... Line 612...
-
 
612
	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
-
 
613
		DRM_DEBUG_KMS("pch backlight already enabled\n");
-
 
614
		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
-
 
615
		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
-
 
616
	}
-
 
617
 
-
 
618
	pch_ctl2 = panel->backlight.max << 16;
-
 
619
	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
-
 
620
 
-
 
621
	pch_ctl1 = 0;
-
 
622
	if (panel->backlight.active_low_pwm)
-
 
623
		pch_ctl1 |= BLM_PCH_POLARITY;
-
 
624
 
-
 
625
	/* BDW always uses the pch pwm controls. */
-
 
626
	pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
517
			tmp = I915_READ(BLC_PWM_PCH_CTL1);
627
 
518
			tmp &= ~BLM_PCH_PWM_ENABLE;
628
	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
Line 519... Line 629...
519
			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
629
	POSTING_READ(BLC_PWM_PCH_CTL1);
520
		}
-
 
521
	}
630
	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
-
 
631
 
522
 
632
	/* This won't stick until the above enable. */
-
 
633
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
 
634
}
523
	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
635
 
524
}
636
static void pch_enable_backlight(struct intel_connector *connector)
525
 
637
{
Line -... Line 638...
-
 
638
	struct drm_device *dev = connector->base.dev;
-
 
639
	struct drm_i915_private *dev_priv = dev->dev_private;
526
void intel_panel_enable_backlight(struct drm_device *dev,
640
	struct intel_panel *panel = &connector->panel;
-
 
641
	enum pipe pipe = intel_get_pipe_from_connector(connector);
-
 
642
	enum transcoder cpu_transcoder =
-
 
643
		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
Line 527... Line 644...
527
				  enum pipe pipe)
644
	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
528
{
645
 
529
	struct drm_i915_private *dev_priv = dev->dev_private;
646
	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
530
	enum transcoder cpu_transcoder =
647
	if (cpu_ctl2 & BLM_PWM_ENABLE) {
531
		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
648
		WARN(1, "cpu backlight already enabled\n");
532
	unsigned long flags;
649
		cpu_ctl2 &= ~BLM_PWM_ENABLE;
Line 533... Line 650...
533
 
650
		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
534
	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
651
	}
-
 
652
 
-
 
653
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
-
 
654
	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
-
 
655
		DRM_DEBUG_KMS("pch backlight already enabled\n");
-
 
656
		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
-
 
657
		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
-
 
658
	}
-
 
659
 
Line -... Line 660...
-
 
660
	if (cpu_transcoder == TRANSCODER_EDP)
535
 
661
		cpu_ctl2 = BLM_TRANSCODER_EDP;
Line -... Line 662...
-
 
662
	else
-
 
663
		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
-
 
664
	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
Line -... Line 665...
-
 
665
	POSTING_READ(BLC_PWM_CPU_CTL2);
536
	if (dev_priv->backlight.level == 0) {
666
	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
-
 
667
 
-
 
668
	/* This won't stick until the above enable. */
Line 537... Line 669...
537
		dev_priv->backlight.level = intel_panel_get_max_backlight(dev);
669
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
 
670
 
538
//       if (dev_priv->backlight.device)
671
	pch_ctl2 = panel->backlight.max << 16;
539
//           dev_priv->backlight.device->props.brightness =
672
	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
540
//               dev_priv->backlight.level;
673
 
541
	}
674
	pch_ctl1 = 0;
Line 542... Line 675...
542
 
675
	if (panel->backlight.active_low_pwm)
543
	if (INTEL_INFO(dev)->gen >= 4) {
676
		pch_ctl1 |= BLM_PCH_POLARITY;
544
		uint32_t reg, tmp;
677
 
545
 
678
	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
-
 
679
	POSTING_READ(BLC_PWM_PCH_CTL1);
Line 546... Line -...
546
		reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
-
 
547
 
680
	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
548
 
-
 
549
		tmp = I915_READ(reg);
681
}
550
 
682
 
Line 551... Line 683...
551
		/* Note that this can also get called through dpms changes. And
683
static void i9xx_enable_backlight(struct intel_connector *connector)
-
 
684
{
552
		 * we don't track the backlight dpms state, hence check whether
685
	struct drm_device *dev = connector->base.dev;
-
 
686
	struct drm_i915_private *dev_priv = dev->dev_private;
553
		 * we have to do anything first. */
687
	struct intel_panel *panel = &connector->panel;
Line 554... Line 688...
554
		if (tmp & BLM_PWM_ENABLE)
688
	u32 ctl, freq;
-
 
689
 
-
 
690
	ctl = I915_READ(BLC_PWM_CTL);
-
 
691
	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
-
 
692
		WARN(1, "backlight already enabled\n");
-
 
693
		I915_WRITE(BLC_PWM_CTL, 0);
-
 
694
	}
-
 
695
 
-
 
696
	freq = panel->backlight.max;
-
 
697
	if (panel->backlight.combination_mode)
555
			goto set_level;
698
		freq /= 0xff;
-
 
699
 
-
 
700
	ctl = freq << 17;
-
 
701
	if (IS_GEN2(dev) && panel->backlight.combination_mode)
-
 
702
		ctl |= BLM_LEGACY_MODE;
556
 
703
	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
557
		if (INTEL_INFO(dev)->num_pipes == 3)
704
		ctl |= BLM_POLARITY_PNV;
-
 
705
 
558
			tmp &= ~BLM_PIPE_SELECT_IVB;
706
	I915_WRITE(BLC_PWM_CTL, ctl);
559
		else
707
	POSTING_READ(BLC_PWM_CTL);
560
			tmp &= ~BLM_PIPE_SELECT;
708
 
-
 
709
	/* XXX: combine this into above write? */
-
 
710
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
 
711
}
-
 
712
 
-
 
713
static void i965_enable_backlight(struct intel_connector *connector)
-
 
714
{
-
 
715
	struct drm_device *dev = connector->base.dev;
-
 
716
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
717
	struct intel_panel *panel = &connector->panel;
-
 
718
	enum pipe pipe = intel_get_pipe_from_connector(connector);
-
 
719
	u32 ctl, ctl2, freq;
-
 
720
 
-
 
721
	ctl2 = I915_READ(BLC_PWM_CTL2);
-
 
722
	if (ctl2 & BLM_PWM_ENABLE) {
-
 
723
		WARN(1, "backlight already enabled\n");
-
 
724
		ctl2 &= ~BLM_PWM_ENABLE;
-
 
725
		I915_WRITE(BLC_PWM_CTL2, ctl2);
-
 
726
		}
-
 
727
 
561
 
728
	freq = panel->backlight.max;
Line 562... Line -...
562
		if (cpu_transcoder == TRANSCODER_EDP)
-
 
563
			tmp |= BLM_TRANSCODER_EDP;
729
	if (panel->backlight.combination_mode)
-
 
730
		freq /= 0xff;
564
		else
731
 
565
			tmp |= BLM_PIPE(cpu_transcoder);
732
	ctl = freq << 16;
566
		tmp &= ~BLM_PWM_ENABLE;
-
 
567
 
733
	I915_WRITE(BLC_PWM_CTL, ctl);
568
		I915_WRITE(reg, tmp);
734
 
-
 
735
	/* XXX: combine this into above write? */
Line -... Line 736...
-
 
736
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
 
737
 
569
		POSTING_READ(reg);
738
	ctl2 = BLM_PIPE(pipe);
-
 
739
	if (panel->backlight.combination_mode)
-
 
740
		ctl2 |= BLM_COMBINATION_MODE;
570
		I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
741
	if (panel->backlight.active_low_pwm)
Line -... Line 742...
-
 
742
		ctl2 |= BLM_POLARITY_I965;
-
 
743
	I915_WRITE(BLC_PWM_CTL2, ctl2);
-
 
744
	POSTING_READ(BLC_PWM_CTL2);
-
 
745
	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
-
 
746
}
-
 
747
 
-
 
748
static void vlv_enable_backlight(struct intel_connector *connector)
-
 
749
{
-
 
750
	struct drm_device *dev = connector->base.dev;
-
 
751
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
752
	struct intel_panel *panel = &connector->panel;
-
 
753
	enum pipe pipe = intel_get_pipe_from_connector(connector);
-
 
754
	u32 ctl, ctl2;
-
 
755
 
571
 
756
	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
572
		if (HAS_PCH_SPLIT(dev) &&
757
	if (ctl2 & BLM_PWM_ENABLE) {
-
 
758
		WARN(1, "backlight already enabled\n");
573
		    !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
759
		ctl2 &= ~BLM_PWM_ENABLE;
-
 
760
		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
-
 
761
	}
-
 
762
 
-
 
763
	ctl = panel->backlight.max << 16;
-
 
764
	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
-
 
765
 
-
 
766
	/* XXX: combine this into above write? */
-
 
767
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
 
768
 
-
 
769
	ctl2 = 0;
-
 
770
	if (panel->backlight.active_low_pwm)
-
 
771
		ctl2 |= BLM_POLARITY_I965;
-
 
772
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
-
 
773
	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
-
 
774
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
-
 
775
}
-
 
776
 
-
 
777
void intel_panel_enable_backlight(struct intel_connector *connector)
-
 
778
{
-
 
779
	struct drm_device *dev = connector->base.dev;
-
 
780
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
781
	struct intel_panel *panel = &connector->panel;
Line 574... Line -...
574
			tmp = I915_READ(BLC_PWM_PCH_CTL1);
-
 
575
			tmp |= BLM_PCH_PWM_ENABLE;
782
	enum pipe pipe = intel_get_pipe_from_connector(connector);
576
			tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
783
	unsigned long flags;
Line 577... Line 784...
577
			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
784
 
578
		}
785
	if (!panel->backlight.present || pipe == INVALID_PIPE)
579
	}
786
		return;
Line 617... Line 824...
617
	default:
824
	default:
618
	return connector_status_unknown;
825
	return connector_status_unknown;
619
	}
826
	}
620
}
827
}
Line 621... Line 828...
621
 
828
 
622
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
829
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
623
static int intel_panel_update_status(struct backlight_device *bd)
830
static int intel_backlight_device_update_status(struct backlight_device *bd)
-
 
831
{
624
{
832
	struct intel_connector *connector = bl_get_data(bd);
-
 
833
	struct drm_device *dev = connector->base.dev;
-
 
834
 
-
 
835
	mutex_lock(&dev->mode_config.mutex);
-
 
836
	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
625
	struct drm_device *dev = bl_get_data(bd);
837
		      bd->props.brightness, bd->props.max_brightness);
626
	intel_panel_set_backlight(dev, bd->props.brightness,
838
	intel_panel_set_backlight(connector, bd->props.brightness,
-
 
839
				  bd->props.max_brightness);
627
				  bd->props.max_brightness);
840
	mutex_unlock(&dev->mode_config.mutex);
628
	return 0;
841
	return 0;
Line 629... Line 842...
629
}
842
}
630
 
843
 
-
 
844
static int intel_backlight_device_get_brightness(struct backlight_device *bd)
631
static int intel_panel_get_brightness(struct backlight_device *bd)
845
{
-
 
846
	struct intel_connector *connector = bl_get_data(bd);
-
 
847
	struct drm_device *dev = connector->base.dev;
-
 
848
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
849
	int ret;
-
 
850
 
632
{
851
	intel_runtime_pm_get(dev_priv);
-
 
852
	mutex_lock(&dev->mode_config.mutex);
-
 
853
	ret = intel_panel_get_backlight(connector);
-
 
854
	mutex_unlock(&dev->mode_config.mutex);
-
 
855
	intel_runtime_pm_put(dev_priv);
633
	struct drm_device *dev = bl_get_data(bd);
856
 
Line 634... Line 857...
634
	return intel_panel_get_backlight(dev);
857
	return ret;
635
}
858
}
636
 
859
 
637
static const struct backlight_ops intel_panel_bl_ops = {
860
static const struct backlight_ops intel_backlight_device_ops = {
Line 638... Line 861...
638
	.update_status = intel_panel_update_status,
861
	.update_status = intel_backlight_device_update_status,
639
	.get_brightness = intel_panel_get_brightness,
862
	.get_brightness = intel_backlight_device_get_brightness,
640
};
863
};
641
 
-
 
642
int intel_panel_setup_backlight(struct drm_connector *connector)
864
 
643
{
-
 
644
	struct drm_device *dev = connector->dev;
-
 
645
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
Line 646... Line 865...
646
	struct backlight_properties props;
865
static int intel_backlight_device_register(struct intel_connector *connector)
647
	unsigned long flags;
866
{
Line -... Line 867...
-
 
867
	struct intel_panel *panel = &connector->panel;
-
 
868
	struct backlight_properties props;
648
 
869
 
649
	intel_panel_init_backlight(dev);
870
	if (WARN_ON(panel->backlight.device))
650
 
871
		return -ENODEV;
-
 
872
 
Line -... Line 873...
-
 
873
	BUG_ON(panel->backlight.max == 0);
-
 
874
 
651
	if (WARN_ON(dev_priv->backlight.device))
875
	memset(&props, 0, sizeof(props));
-
 
876
	props.type = BACKLIGHT_RAW;
-
 
877
	props.brightness = panel->backlight.level;
652
		return -ENODEV;
878
	props.max_brightness = panel->backlight.max;
-
 
879
 
-
 
880
	/*
653
 
881
	 * Note: using the same name independent of the connector prevents
Line 654... Line 882...
654
	memset(&props, 0, sizeof(props));
882
	 * registration of multiple backlight devices in the driver.
655
	props.type = BACKLIGHT_RAW;
883
	 */
-
 
884
	panel->backlight.device =
-
 
885
		backlight_device_register("intel_backlight",
656
	props.brightness = dev_priv->backlight.level;
886
					  connector->base.kdev,
657
 
887
					  connector,
658
	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
-
 
659
	props.max_brightness = intel_panel_get_max_backlight(dev);
-
 
660
	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
888
					  &intel_backlight_device_ops, &props);
661
 
-
 
-
 
889
 
Line -... Line 890...
-
 
890
	if (IS_ERR(panel->backlight.device)) {
-
 
891
		DRM_ERROR("Failed to register backlight: %ld\n",
-
 
892
			  PTR_ERR(panel->backlight.device));
-
 
893
		panel->backlight.device = NULL;
662
	if (props.max_brightness == 0) {
894
		return -ENODEV;
663
		DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
895
	}
664
		return -ENODEV;
896
	return 0;
-
 
897
}
-
 
898
 
-
 
899
static void intel_backlight_device_unregister(struct intel_connector *connector)
-
 
900
{
-
 
901
	struct intel_panel *panel = &connector->panel;
-
 
902
 
-
 
903
	if (panel->backlight.device) {
-
 
904
		backlight_device_unregister(panel->backlight.device);
-
 
905
		panel->backlight.device = NULL;
-
 
906
	}
-
 
907
}
-
 
908
#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
-
 
909
static int intel_backlight_device_register(struct intel_connector *connector)
-
 
910
{
-
 
911
	return 0;
-
 
912
}
-
 
913
static void intel_backlight_device_unregister(struct intel_connector *connector)
-
 
914
{
-
 
915
}
-
 
916
#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
-
 
917
 
-
 
918
/*
-
 
919
 * Note: The setup hooks can't assume pipe is set!
-
 
920
 *
-
 
921
 * XXX: Query mode clock or hardware clock and program PWM modulation frequency
-
 
922
 * appropriately when it's 0. Use VBT and/or sane defaults.
-
 
923
 */
-
 
924
static int bdw_setup_backlight(struct intel_connector *connector)
-
 
925
{
-
 
926
	struct drm_device *dev = connector->base.dev;
-
 
927
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
928
	struct intel_panel *panel = &connector->panel;
-
 
929
	u32 pch_ctl1, pch_ctl2, val;
-
 
930
 
-
 
931
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
-
 
932
	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
-
 
933
 
665
	}
934
	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
-
 
935
	panel->backlight.max = pch_ctl2 >> 16;
-
 
936
	if (!panel->backlight.max)
-
 
937
		return -ENODEV;
-
 
938
 
-
 
939
	val = bdw_get_backlight(connector);
-
 
940
	panel->backlight.level = intel_panel_compute_brightness(connector, val);
-
 
941
 
-
 
942
	panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) &&
-
 
943
		panel->backlight.level != 0;
-
 
944
 
-
 
945
	return 0;
-
 
946
}
-
 
947
 
-
 
948
static int pch_setup_backlight(struct intel_connector *connector)
-
 
949
{
-
 
950
	struct drm_device *dev = connector->base.dev;
-
 
951
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
952
	struct intel_panel *panel = &connector->panel;
-
 
953
	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
-
 
954
 
-
 
955
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
-
 
956
	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
-
 
957
 
-
 
958
	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
-
 
959
	panel->backlight.max = pch_ctl2 >> 16;
-
 
960
	if (!panel->backlight.max)
-
 
961
		return -ENODEV;
-
 
962
 
-
 
963
	val = pch_get_backlight(connector);
-
 
964
	panel->backlight.level = intel_panel_compute_brightness(connector, val);
-
 
965
 
-
 
966
	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
-
 
967
	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
-
 
968
		(pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;
-
 
969
 
-
 
970
	return 0;
-
 
971
}
-
 
972
 
-
 
973
static int i9xx_setup_backlight(struct intel_connector *connector)
-
 
974
{
-
 
975
	struct drm_device *dev = connector->base.dev;
-
 
976
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
977
	struct intel_panel *panel = &connector->panel;
-
 
978
	u32 ctl, val;
-
 
979
 
-
 
980
	ctl = I915_READ(BLC_PWM_CTL);
-
 
981
 
-
 
982
	if (IS_GEN2(dev))
-
 
983
		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
666
	dev_priv->backlight.device =
984
 
-
 
985
	if (IS_PINEVIEW(dev))
-
 
986
		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
-
 
987
 
-
 
988
	panel->backlight.max = ctl >> 17;
-
 
989
	if (panel->backlight.combination_mode)
-
 
990
		panel->backlight.max *= 0xff;
-
 
991
 
667
		backlight_device_register("intel_backlight",
992
	if (!panel->backlight.max)
-
 
993
		return -ENODEV;
-
 
994
 
-
 
995
	val = i9xx_get_backlight(connector);
-
 
996
	panel->backlight.level = intel_panel_compute_brightness(connector, val);
-
 
997
 
-
 
998
	panel->backlight.enabled = panel->backlight.level != 0;
-
 
999
 
-
 
1000
	return 0;
-
 
1001
}
-
 
1002
 
-
 
1003
static int i965_setup_backlight(struct intel_connector *connector)
-
 
1004
{
-
 
1005
	struct drm_device *dev = connector->base.dev;
-
 
1006
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1007
	struct intel_panel *panel = &connector->panel;
-
 
1008
	u32 ctl, ctl2, val;
-
 
1009
 
-
 
1010
	ctl2 = I915_READ(BLC_PWM_CTL2);
-
 
1011
	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
-
 
1012
	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
-
 
1013
 
-
 
1014
	ctl = I915_READ(BLC_PWM_CTL);
-
 
1015
	panel->backlight.max = ctl >> 16;
-
 
1016
	if (panel->backlight.combination_mode)
-
 
1017
		panel->backlight.max *= 0xff;
-
 
1018
 
668
					  &connector->kdev, dev,
1019
	if (!panel->backlight.max)
669
					  &intel_panel_bl_ops, &props);
1020
		return -ENODEV;
Line 670... Line 1021...
670
 
1021
 
671
	if (IS_ERR(dev_priv->backlight.device)) {
1022
	val = i9xx_get_backlight(connector);
-
 
1023
	panel->backlight.level = intel_panel_compute_brightness(connector, val);
672
		DRM_ERROR("Failed to register backlight: %ld\n",
1024
 
-
 
1025
	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
-
 
1026
		panel->backlight.level != 0;
-
 
1027
 
-
 
1028
	return 0;
673
			  PTR_ERR(dev_priv->backlight.device));
1029
}
-
 
1030
 
-
 
1031
static int vlv_setup_backlight(struct intel_connector *connector)
674
		dev_priv->backlight.device = NULL;
1032
{
-
 
1033
	struct drm_device *dev = connector->base.dev;
-
 
1034
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1035
	struct intel_panel *panel = &connector->panel;
675
		return -ENODEV;
1036
	enum pipe pipe;
-
 
1037
	u32 ctl, ctl2, val;
-
 
1038
 
676
	}
1039
	for_each_pipe(pipe) {
-
 
1040
		u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
-
 
1041
 
-
 
1042
		/* Skip if the modulation freq is already set */
-
 
1043
		if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
-
 
1044
			continue;
-
 
1045
 
-
 
1046
		cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
-
 
1047
		I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) |
-
 
1048
			   cur_val);
-
 
1049
	}
-
 
1050
 
-
 
1051
	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
-
 
1052
	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
-
 
1053
 
-
 
1054
	ctl = I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
-
 
1055
	panel->backlight.max = ctl >> 16;
677
	return 0;
1056
	if (!panel->backlight.max)
678
}
1057
		return -ENODEV;
679
 
1058
 
680
void intel_panel_destroy_backlight(struct drm_device *dev)
1059
	val = _vlv_get_backlight(dev, PIPE_A);
-
 
1060
	panel->backlight.level = intel_panel_compute_brightness(connector, val);
-
 
1061
 
-
 
1062
	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
681
{
1063
		panel->backlight.level != 0;
-
 
1064
 
-
 
1065
	return 0;
-
 
1066
}
-
 
1067
 
-
 
1068
int intel_panel_setup_backlight(struct drm_connector *connector)
-
 
1069
{
-
 
1070
	struct drm_device *dev = connector->dev;
-
 
1071
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1072
	struct intel_connector *intel_connector = to_intel_connector(connector);
-
 
1073
	struct intel_panel *panel = &intel_connector->panel;
-
 
1074
	unsigned long flags;
-
 
1075
	int ret;
-
 
1076
 
-
 
1077
	/* set level and max in panel struct */
-
 
1078
	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
-
 
1079
	ret = dev_priv->display.setup_backlight(intel_connector);
-
 
1080
	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
-
 
1081
 
-
 
1082
	if (ret) {
-
 
1083
		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
-
 
1084
			      drm_get_connector_name(connector));
-
 
1085
		return ret;
-
 
1086
	}
-
 
1087
 
682
	struct drm_i915_private *dev_priv = dev->dev_private;
1088
	intel_backlight_device_register(intel_connector);
683
	if (dev_priv->backlight.device) {
1089
 
Line 684... Line 1090...
684
		backlight_device_unregister(dev_priv->backlight.device);
1090
	panel->backlight.present = true;
685
		dev_priv->backlight.device = NULL;
1091
 
-
 
1092
	DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, "
-
 
1093
		      "sysfs interface %sregistered\n",
-
 
1094
		      panel->backlight.enabled ? "enabled" : "disabled",
-
 
1095
		      panel->backlight.level, panel->backlight.max,
-
 
1096
		      panel->backlight.device ? "" : "not ");
-
 
1097
 
-
 
1098
	return 0;
-
 
1099
}
-
 
1100
 
-
 
1101
void intel_panel_destroy_backlight(struct drm_connector *connector)
-
 
1102
{
-
 
1103
	struct intel_connector *intel_connector = to_intel_connector(connector);
-
 
1104
	struct intel_panel *panel = &intel_connector->panel;
-
 
1105
 
-
 
1106
	panel->backlight.present = false;
-
 
1107
	intel_backlight_device_unregister(intel_connector);
-
 
1108
}
-
 
1109
 
-
 
1110
/**
-
 
1111
 * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID
-
 
1112
 * @dev: drm device
-
 
1113
 * @fixed_mode : panel native mode
-
 
1114
 * @connector: LVDS/eDP connector
-
 
1115
 *
-
 
1116
 * Return downclock_avail
-
 
1117
 * Find the reduced downclock for LVDS/eDP in EDID.
-
 
1118
 */
-
 
1119
struct drm_display_mode *
-
 
1120
intel_find_panel_downclock(struct drm_device *dev,
-
 
1121
			struct drm_display_mode *fixed_mode,
-
 
1122
			struct drm_connector *connector)
-
 
1123
{
-
 
1124
	struct drm_display_mode *scan, *tmp_mode;
-
 
1125
	int temp_downclock;
-
 
1126
 
-
 
1127
	temp_downclock = fixed_mode->clock;
-
 
1128
	tmp_mode = NULL;
-
 
1129
 
-
 
1130
	list_for_each_entry(scan, &connector->probed_modes, head) {
-
 
1131
		/*
-
 
1132
		 * If one mode has the same resolution with the fixed_panel
-
 
1133
		 * mode while they have the different refresh rate, it means
-
 
1134
		 * that the reduced downclock is found. In such
-
 
1135
		 * case we can set the different FPx0/1 to dynamically select
-
 
1136
		 * between low and high frequency.
-
 
1137
		 */
-
 
1138
		if (scan->hdisplay == fixed_mode->hdisplay &&
-
 
1139
		    scan->hsync_start == fixed_mode->hsync_start &&
-
 
1140
		    scan->hsync_end == fixed_mode->hsync_end &&
-
 
1141
		    scan->htotal == fixed_mode->htotal &&
-
 
1142
		    scan->vdisplay == fixed_mode->vdisplay &&
-
 
1143
		    scan->vsync_start == fixed_mode->vsync_start &&
-
 
1144
		    scan->vsync_end == fixed_mode->vsync_end &&
-
 
1145
		    scan->vtotal == fixed_mode->vtotal) {
-
 
1146
			if (scan->clock < temp_downclock) {
-
 
1147
				/*
-
 
1148
				 * The downclock is already found. But we
686
	}
1149
				 * expect to find the lower downclock.
-
 
1150
				 */
-
 
1151
				temp_downclock = scan->clock;
-
 
1152
				tmp_mode = scan;
-
 
1153
			}
-
 
1154
		}
-
 
1155
	}
-
 
1156
 
-
 
1157
	if (temp_downclock < fixed_mode->clock)
-
 
1158
		return drm_mode_duplicate(dev, tmp_mode);
-
 
1159
	else
-
 
1160
		return NULL;
-
 
1161
}
-
 
1162
 
-
 
1163
/* Set up chip specific backlight functions */
-
 
1164
void intel_panel_init_backlight_funcs(struct drm_device *dev)
-
 
1165
{
-
 
1166
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1167
 
-
 
1168
	if (IS_BROADWELL(dev)) {
-
 
1169
		dev_priv->display.setup_backlight = bdw_setup_backlight;
-
 
1170
		dev_priv->display.enable_backlight = bdw_enable_backlight;
-
 
1171
		dev_priv->display.disable_backlight = pch_disable_backlight;
-
 
1172
		dev_priv->display.set_backlight = bdw_set_backlight;
-
 
1173
		dev_priv->display.get_backlight = bdw_get_backlight;
-
 
1174
	} else if (HAS_PCH_SPLIT(dev)) {
-
 
1175
		dev_priv->display.setup_backlight = pch_setup_backlight;
-
 
1176
		dev_priv->display.enable_backlight = pch_enable_backlight;
-
 
1177
		dev_priv->display.disable_backlight = pch_disable_backlight;
-
 
1178
		dev_priv->display.set_backlight = pch_set_backlight;
-
 
1179
		dev_priv->display.get_backlight = pch_get_backlight;
-
 
1180
	} else if (IS_VALLEYVIEW(dev)) {
-
 
1181
		dev_priv->display.setup_backlight = vlv_setup_backlight;
-
 
1182
		dev_priv->display.enable_backlight = vlv_enable_backlight;
-
 
1183
		dev_priv->display.disable_backlight = vlv_disable_backlight;
-
 
1184
		dev_priv->display.set_backlight = vlv_set_backlight;
-
 
1185
		dev_priv->display.get_backlight = vlv_get_backlight;
-
 
1186
	} else if (IS_GEN4(dev)) {
-
 
1187
		dev_priv->display.setup_backlight = i965_setup_backlight;
687
}
1188
		dev_priv->display.enable_backlight = i965_enable_backlight;
688
#else
-
 
Line 689... Line 1189...
689
int intel_panel_setup_backlight(struct drm_connector *connector)
1189
		dev_priv->display.disable_backlight = i965_disable_backlight;
690
{
1190
		dev_priv->display.set_backlight = i9xx_set_backlight;
691
	intel_panel_init_backlight(connector->dev);
1191
		dev_priv->display.get_backlight = i9xx_get_backlight;
692
	return 0;
1192
	} else {
Line 711... Line 1211...
711
	struct intel_connector *intel_connector =
1211
	struct intel_connector *intel_connector =
712
		container_of(panel, struct intel_connector, panel);
1212
		container_of(panel, struct intel_connector, panel);
Line 713... Line 1213...
713
 
1213
 
714
	if (panel->fixed_mode)
1214
	if (panel->fixed_mode)
-
 
1215
		drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
-
 
1216
 
-
 
1217
	if (panel->downclock_mode)
-
 
1218
		drm_mode_destroy(intel_connector->base.dev,
715
		drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
1219
				panel->downclock_mode);