Subversion Repositories Kolibri OS

Rev

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

Rev 5354 Rev 6084
Line 28... Line 28...
28
 *      Chris Wilson 
28
 *      Chris Wilson 
29
 */
29
 */
Line 30... Line 30...
30
 
30
 
Line -... Line 31...
-
 
31
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32
 
-
 
33
#include 
32
 
34
#include 
Line -... Line 35...
-
 
35
#include 
-
 
36
#include "intel_drv.h"
33
#include 
37
 
34
#include "intel_drv.h"
38
#define CRC_PMIC_PWM_PERIOD_NS	21333
35
 
39
 
36
void
40
void
37
intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
41
intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
Line 96... Line 100...
96
}
100
}
Line 97... Line 101...
97
 
101
 
98
/* adjusted_mode has been preset to be the panel's fixed mode */
102
/* adjusted_mode has been preset to be the panel's fixed mode */
99
void
103
void
100
intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
104
intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
101
			struct intel_crtc_config *pipe_config,
105
			struct intel_crtc_state *pipe_config,
102
			int fitting_mode)
106
			int fitting_mode)
103
{
-
 
104
	struct drm_display_mode *adjusted_mode;
-
 
105
	int x, y, width, height;
-
 
106
 
107
{
107
	adjusted_mode = &pipe_config->adjusted_mode;
-
 
108
 
108
	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
Line 109... Line 109...
109
	x = y = width = height = 0;
109
	int x = 0, y = 0, width = 0, height = 0;
110
 
110
 
111
	/* Native modes don't need fitting */
111
	/* Native modes don't need fitting */
112
	if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
112
	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
Line 113... Line 113...
113
	    adjusted_mode->vdisplay == pipe_config->pipe_src_h)
113
	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
114
		goto done;
114
		goto done;
115
 
115
 
116
	switch (fitting_mode) {
116
	switch (fitting_mode) {
117
	case DRM_MODE_SCALE_CENTER:
117
	case DRM_MODE_SCALE_CENTER:
118
		width = pipe_config->pipe_src_w;
118
		width = pipe_config->pipe_src_w;
119
		height = pipe_config->pipe_src_h;
119
		height = pipe_config->pipe_src_h;
Line 120... Line 120...
120
		x = (adjusted_mode->hdisplay - width + 1)/2;
120
		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
121
		y = (adjusted_mode->vdisplay - height + 1)/2;
121
		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
122
		break;
122
		break;
123
 
123
 
124
	case DRM_MODE_SCALE_ASPECT:
124
	case DRM_MODE_SCALE_ASPECT:
125
		/* Scale but preserve the aspect ratio */
125
		/* Scale but preserve the aspect ratio */
126
		{
126
		{
127
			u32 scaled_width = adjusted_mode->hdisplay
127
			u32 scaled_width = adjusted_mode->crtc_hdisplay
128
				* pipe_config->pipe_src_h;
128
				* pipe_config->pipe_src_h;
129
			u32 scaled_height = pipe_config->pipe_src_w
129
			u32 scaled_height = pipe_config->pipe_src_w
130
				* adjusted_mode->vdisplay;
130
				* adjusted_mode->crtc_vdisplay;
131
			if (scaled_width > scaled_height) { /* pillar */
131
			if (scaled_width > scaled_height) { /* pillar */
132
				width = scaled_height / pipe_config->pipe_src_h;
132
				width = scaled_height / pipe_config->pipe_src_h;
133
				if (width & 1)
133
				if (width & 1)
134
				    	width++;
134
					width++;
135
				x = (adjusted_mode->hdisplay - width + 1) / 2;
135
				x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
136
				y = 0;
136
				y = 0;
137
				height = adjusted_mode->vdisplay;
137
				height = adjusted_mode->crtc_vdisplay;
138
			} else if (scaled_width < scaled_height) { /* letter */
138
			} else if (scaled_width < scaled_height) { /* letter */
139
				height = scaled_width / pipe_config->pipe_src_w;
139
				height = scaled_width / pipe_config->pipe_src_w;
140
				if (height & 1)
140
				if (height & 1)
141
				    height++;
141
				    height++;
142
				y = (adjusted_mode->vdisplay - height + 1) / 2;
142
				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
143
				x = 0;
143
				x = 0;
144
				width = adjusted_mode->hdisplay;
144
				width = adjusted_mode->crtc_hdisplay;
145
			} else {
145
			} else {
146
				x = y = 0;
146
				x = y = 0;
147
				width = adjusted_mode->hdisplay;
147
				width = adjusted_mode->crtc_hdisplay;
Line 148... Line 148...
148
				height = adjusted_mode->vdisplay;
148
				height = adjusted_mode->crtc_vdisplay;
149
			}
149
			}
150
		}
150
		}
151
		break;
151
		break;
152
 
152
 
Line 153... Line 153...
153
	case DRM_MODE_SCALE_FULLSCREEN:
153
	case DRM_MODE_SCALE_FULLSCREEN:
154
		x = y = 0;
154
		x = y = 0;
155
		width = adjusted_mode->hdisplay;
155
		width = adjusted_mode->crtc_hdisplay;
Line 166... Line 166...
166
	pipe_config->pch_pfit.size = (width << 16) | height;
166
	pipe_config->pch_pfit.size = (width << 16) | height;
167
	pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
167
	pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
168
}
168
}
Line 169... Line 169...
169
 
169
 
170
static void
170
static void
171
centre_horizontally(struct drm_display_mode *mode,
171
centre_horizontally(struct drm_display_mode *adjusted_mode,
172
		    int width)
172
		    int width)
173
{
173
{
Line 174... Line 174...
174
	u32 border, sync_pos, blank_width, sync_width;
174
	u32 border, sync_pos, blank_width, sync_width;
175
 
175
 
176
	/* keep the hsync and hblank widths constant */
176
	/* keep the hsync and hblank widths constant */
177
	sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start;
177
	sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
Line 178... Line 178...
178
	blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start;
178
	blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
179
	sync_pos = (blank_width - sync_width + 1) / 2;
179
	sync_pos = (blank_width - sync_width + 1) / 2;
Line 180... Line 180...
180
 
180
 
181
	border = (mode->hdisplay - width + 1) / 2;
181
	border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
182
	border += border & 1; /* make the border even */
182
	border += border & 1; /* make the border even */
Line 183... Line 183...
183
 
183
 
184
	mode->crtc_hdisplay = width;
184
	adjusted_mode->crtc_hdisplay = width;
185
	mode->crtc_hblank_start = width + border;
185
	adjusted_mode->crtc_hblank_start = width + border;
Line 186... Line 186...
186
	mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width;
186
	adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
187
 
187
 
188
	mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
188
	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
189
	mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
189
	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
190
}
190
}
Line 191... Line 191...
191
 
191
 
192
static void
192
static void
193
centre_vertically(struct drm_display_mode *mode,
193
centre_vertically(struct drm_display_mode *adjusted_mode,
194
		  int height)
194
		  int height)
Line 195... Line 195...
195
{
195
{
Line 196... Line 196...
196
	u32 border, sync_pos, blank_width, sync_width;
196
	u32 border, sync_pos, blank_width, sync_width;
197
 
197
 
198
	/* keep the vsync and vblank widths constant */
198
	/* keep the vsync and vblank widths constant */
Line 199... Line 199...
199
	sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start;
199
	sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
200
	blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start;
200
	blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
201
	sync_pos = (blank_width - sync_width + 1) / 2;
201
	sync_pos = (blank_width - sync_width + 1) / 2;
Line 202... Line 202...
202
 
202
 
203
	border = (mode->vdisplay - height + 1) / 2;
203
	border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
204
 
204
 
Line 221... Line 221...
221
#define FACTOR (1 << ACCURACY)
221
#define FACTOR (1 << ACCURACY)
222
	u32 ratio = source * FACTOR / target;
222
	u32 ratio = source * FACTOR / target;
223
	return (FACTOR * ratio + FACTOR/2) / FACTOR;
223
	return (FACTOR * ratio + FACTOR/2) / FACTOR;
224
}
224
}
Line 225... Line 225...
225
 
225
 
226
static void i965_scale_aspect(struct intel_crtc_config *pipe_config,
226
static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
227
			      u32 *pfit_control)
227
			      u32 *pfit_control)
228
{
228
{
229
	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
229
	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
230
			u32 scaled_width = adjusted_mode->hdisplay *
230
	u32 scaled_width = adjusted_mode->crtc_hdisplay *
231
		pipe_config->pipe_src_h;
231
		pipe_config->pipe_src_h;
232
	u32 scaled_height = pipe_config->pipe_src_w *
232
	u32 scaled_height = pipe_config->pipe_src_w *
Line 233... Line 233...
233
				adjusted_mode->vdisplay;
233
		adjusted_mode->crtc_vdisplay;
234
 
234
 
235
			/* 965+ is easy, it does everything in hw */
235
	/* 965+ is easy, it does everything in hw */
236
			if (scaled_width > scaled_height)
236
	if (scaled_width > scaled_height)
237
		*pfit_control |= PFIT_ENABLE |
237
		*pfit_control |= PFIT_ENABLE |
238
					PFIT_SCALING_PILLAR;
238
			PFIT_SCALING_PILLAR;
239
			else if (scaled_width < scaled_height)
239
	else if (scaled_width < scaled_height)
240
		*pfit_control |= PFIT_ENABLE |
240
		*pfit_control |= PFIT_ENABLE |
241
					PFIT_SCALING_LETTER;
241
			PFIT_SCALING_LETTER;
242
	else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w)
242
	else if (adjusted_mode->crtc_hdisplay != pipe_config->pipe_src_w)
Line 243... Line 243...
243
		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
243
		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
244
}
244
}
245
 
245
 
246
static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config,
246
static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
247
			      u32 *pfit_control, u32 *pfit_pgm_ratios,
247
			      u32 *pfit_control, u32 *pfit_pgm_ratios,
248
			      u32 *border)
248
			      u32 *border)
249
{
249
{
250
	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
250
	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
251
			u32 scaled_width = adjusted_mode->hdisplay *
251
	u32 scaled_width = adjusted_mode->crtc_hdisplay *
252
		pipe_config->pipe_src_h;
252
		pipe_config->pipe_src_h;
Line 253... Line 253...
253
	u32 scaled_height = pipe_config->pipe_src_w *
253
	u32 scaled_height = pipe_config->pipe_src_w *
254
				adjusted_mode->vdisplay;
254
		adjusted_mode->crtc_vdisplay;
255
	u32 bits;
255
	u32 bits;
Line 263... Line 263...
263
				centre_horizontally(adjusted_mode,
263
		centre_horizontally(adjusted_mode,
264
						    scaled_height /
264
				    scaled_height /
265
				    pipe_config->pipe_src_h);
265
				    pipe_config->pipe_src_h);
Line 266... Line 266...
266
 
266
 
267
		*border = LVDS_BORDER_ENABLE;
267
		*border = LVDS_BORDER_ENABLE;
268
		if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) {
268
		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay) {
269
			bits = panel_fitter_scaling(pipe_config->pipe_src_h,
269
			bits = panel_fitter_scaling(pipe_config->pipe_src_h,
Line 270... Line 270...
270
						    adjusted_mode->vdisplay);
270
						    adjusted_mode->crtc_vdisplay);
271
 
271
 
272
			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
272
			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
273
							    bits << PFIT_VERT_SCALE_SHIFT);
273
					     bits << PFIT_VERT_SCALE_SHIFT);
Line 279... Line 279...
279
				centre_vertically(adjusted_mode,
279
		centre_vertically(adjusted_mode,
280
						  scaled_width /
280
				  scaled_width /
281
				  pipe_config->pipe_src_w);
281
				  pipe_config->pipe_src_w);
Line 282... Line 282...
282
 
282
 
283
		*border = LVDS_BORDER_ENABLE;
283
		*border = LVDS_BORDER_ENABLE;
284
		if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
284
		if (pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
285
			bits = panel_fitter_scaling(pipe_config->pipe_src_w,
285
			bits = panel_fitter_scaling(pipe_config->pipe_src_w,
Line 286... Line 286...
286
						    adjusted_mode->hdisplay);
286
						    adjusted_mode->crtc_hdisplay);
287
 
287
 
288
			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
288
			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
289
							    bits << PFIT_VERT_SCALE_SHIFT);
289
					     bits << PFIT_VERT_SCALE_SHIFT);
Line 299... Line 299...
299
						 HORIZ_INTERP_BILINEAR);
299
				  HORIZ_INTERP_BILINEAR);
300
			}
300
	}
301
}
301
}
Line 302... Line 302...
302
 
302
 
303
void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
303
void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
304
			      struct intel_crtc_config *pipe_config,
304
			      struct intel_crtc_state *pipe_config,
305
			      int fitting_mode)
305
			      int fitting_mode)
306
{
306
{
307
	struct drm_device *dev = intel_crtc->base.dev;
307
	struct drm_device *dev = intel_crtc->base.dev;
308
	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
-
 
309
	struct drm_display_mode *adjusted_mode;
-
 
310
 
308
	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
Line 311... Line 309...
311
	adjusted_mode = &pipe_config->adjusted_mode;
309
	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
312
 
310
 
313
	/* Native modes don't need fitting */
311
	/* Native modes don't need fitting */
314
	if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
312
	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
Line 315... Line 313...
315
	    adjusted_mode->vdisplay == pipe_config->pipe_src_h)
313
	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
316
		goto out;
314
		goto out;
317
 
315
 
Line 336... Line 334...
336
	case DRM_MODE_SCALE_FULLSCREEN:
334
	case DRM_MODE_SCALE_FULLSCREEN:
337
		/*
335
		/*
338
		 * Full scaling, even if it changes the aspect ratio.
336
		 * Full scaling, even if it changes the aspect ratio.
339
		 * Fortunately this is all done for us in hw.
337
		 * Fortunately this is all done for us in hw.
340
		 */
338
		 */
341
		if (pipe_config->pipe_src_h != adjusted_mode->vdisplay ||
339
		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay ||
342
		    pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
340
		    pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
343
			pfit_control |= PFIT_ENABLE;
341
			pfit_control |= PFIT_ENABLE;
344
			if (INTEL_INFO(dev)->gen >= 4)
342
			if (INTEL_INFO(dev)->gen >= 4)
345
				pfit_control |= PFIT_SCALING_AUTO;
343
				pfit_control |= PFIT_SCALING_AUTO;
346
			else
344
			else
347
				pfit_control |= (VERT_AUTO_SCALE |
345
				pfit_control |= (VERT_AUTO_SCALE |
Line 381... Line 379...
381
{
379
{
382
	struct drm_i915_private *dev_priv = dev->dev_private;
380
	struct drm_i915_private *dev_priv = dev->dev_private;
Line 383... Line 381...
383
 
381
 
384
	/* Assume that the BIOS does not lie through the OpRegion... */
382
	/* Assume that the BIOS does not lie through the OpRegion... */
385
	if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) {
383
	if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) {
386
		return ioread32(dev_priv->opregion.lid_state) & 0x1 ?
384
		return *dev_priv->opregion.lid_state & 0x1 ?
387
			connector_status_connected :
385
			connector_status_connected :
388
			connector_status_disconnected;
386
			connector_status_disconnected;
Line 389... Line 387...
389
	}
387
	}
Line 478... Line 476...
478
	}
476
	}
Line 479... Line 477...
479
 
477
 
480
	return val;
478
	return val;
Line 481... Line 479...
481
}
479
}
482
 
480
 
483
static u32 bdw_get_backlight(struct intel_connector *connector)
481
static u32 lpt_get_backlight(struct intel_connector *connector)
484
{
482
{
Line 485... Line 483...
485
	struct drm_device *dev = connector->base.dev;
483
	struct drm_device *dev = connector->base.dev;
Line 533... Line 531...
533
	enum pipe pipe = intel_get_pipe_from_connector(connector);
531
	enum pipe pipe = intel_get_pipe_from_connector(connector);
Line 534... Line 532...
534
 
532
 
535
	return _vlv_get_backlight(dev, pipe);
533
	return _vlv_get_backlight(dev, pipe);
Line -... Line 534...
-
 
534
}
-
 
535
 
-
 
536
static u32 bxt_get_backlight(struct intel_connector *connector)
-
 
537
{
-
 
538
	struct drm_device *dev = connector->base.dev;
-
 
539
	struct intel_panel *panel = &connector->panel;
-
 
540
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
541
 
-
 
542
	return I915_READ(BXT_BLC_PWM_DUTY(panel->backlight.controller));
-
 
543
}
-
 
544
 
-
 
545
static u32 pwm_get_backlight(struct intel_connector *connector)
-
 
546
{
-
 
547
	struct intel_panel *panel = &connector->panel;
-
 
548
	int duty_ns;
-
 
549
 
-
 
550
	duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
-
 
551
	return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
536
}
552
}
537
 
553
 
538
static u32 intel_panel_get_backlight(struct intel_connector *connector)
554
static u32 intel_panel_get_backlight(struct intel_connector *connector)
539
{
555
{
540
	struct drm_device *dev = connector->base.dev;
556
	struct drm_device *dev = connector->base.dev;
541
	struct drm_i915_private *dev_priv = dev->dev_private;
557
	struct drm_i915_private *dev_priv = dev->dev_private;
Line 542... Line 558...
542
	struct intel_panel *panel = &connector->panel;
558
	struct intel_panel *panel = &connector->panel;
Line 543... Line 559...
543
	u32 val = 0;
559
	u32 val = 0;
544
 
560
 
545
	mutex_lock(&dev_priv->backlight_lock);
561
	mutex_lock(&dev_priv->backlight_lock);
546
 
562
 
Line 547... Line 563...
547
	if (panel->backlight.enabled) {
563
	if (panel->backlight.enabled) {
Line 548... Line 564...
548
	val = dev_priv->display.get_backlight(connector);
564
		val = panel->backlight.get(connector);
549
	val = intel_panel_compute_brightness(connector, val);
565
		val = intel_panel_compute_brightness(connector, val);
550
	}
566
	}
Line 551... Line 567...
551
 
567
 
552
	mutex_unlock(&dev_priv->backlight_lock);
568
	mutex_unlock(&dev_priv->backlight_lock);
553
 
569
 
554
	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
570
	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
555
	return val;
571
	return val;
556
}
572
}
Line 613... Line 629...
613
 
629
 
614
	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
630
	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
615
	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
631
	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
Line 616... Line -...
616
}
-
 
617
 
632
}
618
static void
633
 
619
intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
634
static void bxt_set_backlight(struct intel_connector *connector, u32 level)
620
{
635
{
-
 
636
	struct drm_device *dev = connector->base.dev;
-
 
637
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
638
	struct intel_panel *panel = &connector->panel;
-
 
639
 
-
 
640
	I915_WRITE(BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
-
 
641
}
-
 
642
 
-
 
643
static void pwm_set_backlight(struct intel_connector *connector, u32 level)
-
 
644
{
-
 
645
	struct intel_panel *panel = &connector->panel;
-
 
646
	int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
-
 
647
 
-
 
648
	pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
-
 
649
}
-
 
650
 
-
 
651
static void
-
 
652
intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
Line 621... Line 653...
621
	struct drm_device *dev = connector->base.dev;
653
{
Line 622... Line 654...
622
	struct drm_i915_private *dev_priv = dev->dev_private;
654
	struct intel_panel *panel = &connector->panel;
623
 
655
 
624
	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
656
	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
Line 625... Line 657...
625
 
657
 
626
	level = intel_panel_compute_brightness(connector, level);
658
	level = intel_panel_compute_brightness(connector, level);
627
	dev_priv->display.set_backlight(connector, level);
659
	panel->backlight.set(connector, level);
Line 678... Line 710...
678
	WARN_ON(panel->backlight.max == 0);
710
	WARN_ON(panel->backlight.max == 0);
Line 679... Line 711...
679
 
711
 
680
	hw_level = clamp_user_to_hw(connector, user_level, user_max);
712
	hw_level = clamp_user_to_hw(connector, user_level, user_max);
Line -... Line 713...
-
 
713
	panel->backlight.level = hw_level;
-
 
714
 
Line 681... Line 715...
681
	panel->backlight.level = hw_level;
715
	mutex_unlock(&dev_priv->backlight_lock);
-
 
716
}
682
 
717
 
-
 
718
static void lpt_disable_backlight(struct intel_connector *connector)
-
 
719
{
Line 683... Line 720...
683
 
720
	struct drm_device *dev = connector->base.dev;
-
 
721
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
722
	u32 tmp;
-
 
723
 
-
 
724
	intel_panel_actually_set_backlight(connector, 0);
-
 
725
 
-
 
726
	/*
-
 
727
	 * Although we don't support or enable CPU PWM with LPT/SPT based
-
 
728
	 * systems, it may have been enabled prior to loading the
-
 
729
	 * driver. Disable to avoid warnings on LCPLL disable.
-
 
730
	 *
-
 
731
	 * This needs rework if we need to add support for CPU PWM on PCH split
-
 
732
	 * platforms.
-
 
733
	 */
-
 
734
	tmp = I915_READ(BLC_PWM_CPU_CTL2);
-
 
735
	if (tmp & BLM_PWM_ENABLE) {
-
 
736
		DRM_DEBUG_KMS("cpu backlight was enabled, disabling\n");
-
 
737
		I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
684
	if (panel->backlight.enabled)
738
	}
Line 685... Line 739...
685
		intel_panel_actually_set_backlight(connector, hw_level);
739
 
686
 
740
	tmp = I915_READ(BLC_PWM_PCH_CTL1);
687
	mutex_unlock(&dev_priv->backlight_lock);
741
	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
Line 733... Line 787...
733
 
787
 
734
	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
788
	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
735
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
789
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
Line -... Line 790...
-
 
790
}
-
 
791
 
-
 
792
static void bxt_disable_backlight(struct intel_connector *connector)
-
 
793
{
-
 
794
	struct drm_device *dev = connector->base.dev;
-
 
795
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
796
	struct intel_panel *panel = &connector->panel;
-
 
797
	u32 tmp, val;
-
 
798
 
-
 
799
	intel_panel_actually_set_backlight(connector, 0);
-
 
800
 
-
 
801
	tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
-
 
802
	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
-
 
803
			tmp & ~BXT_BLC_PWM_ENABLE);
-
 
804
 
-
 
805
	if (panel->backlight.controller == 1) {
-
 
806
		val = I915_READ(UTIL_PIN_CTL);
-
 
807
		val &= ~UTIL_PIN_ENABLE;
-
 
808
		I915_WRITE(UTIL_PIN_CTL, val);
-
 
809
	}
-
 
810
}
-
 
811
 
-
 
812
static void pwm_disable_backlight(struct intel_connector *connector)
-
 
813
{
-
 
814
	struct intel_panel *panel = &connector->panel;
-
 
815
 
-
 
816
	/* Disable the backlight */
-
 
817
	pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS);
-
 
818
	usleep_range(2000, 3000);
-
 
819
	pwm_disable(panel->backlight.pwm);
736
}
820
}
737
 
821
 
738
void intel_panel_disable_backlight(struct intel_connector *connector)
822
void intel_panel_disable_backlight(struct intel_connector *connector)
739
{
823
{
740
	struct drm_device *dev = connector->base.dev;
824
	struct drm_device *dev = connector->base.dev;
Line 741... Line 825...
741
	struct drm_i915_private *dev_priv = dev->dev_private;
825
	struct drm_i915_private *dev_priv = dev->dev_private;
742
	struct intel_panel *panel = &connector->panel;
826
	struct intel_panel *panel = &connector->panel;
Line 743... Line 827...
743
 
827
 
744
	if (!panel->backlight.present)
828
	if (!panel->backlight.present)
745
		return;
829
		return;
746
 
830
 
747
	/*
831
	/*
748
	 * Do not disable backlight on the vgaswitcheroo path. When switching
832
	 * Do not disable backlight on the vga_switcheroo path. When switching
749
	 * away from i915, the other client may depend on i915 to handle the
833
	 * away from i915, the other client may depend on i915 to handle the
Line 756... Line 840...
756
	}
840
	}
Line 757... Line 841...
757
 
841
 
Line 758... Line 842...
758
	mutex_lock(&dev_priv->backlight_lock);
842
	mutex_lock(&dev_priv->backlight_lock);
759
 
843
 
Line 760... Line 844...
760
	panel->backlight.enabled = false;
844
    panel->backlight.enabled = false;
761
	dev_priv->display.disable_backlight(connector);
845
	panel->backlight.disable(connector);
Line 762... Line 846...
762
 
846
 
763
	mutex_unlock(&dev_priv->backlight_lock);
847
	mutex_unlock(&dev_priv->backlight_lock);
764
}
848
}
765
 
849
 
766
static void bdw_enable_backlight(struct intel_connector *connector)
850
static void lpt_enable_backlight(struct intel_connector *connector)
767
{
851
{
Line 869... Line 953...
869
	I915_WRITE(BLC_PWM_CTL, ctl);
953
	I915_WRITE(BLC_PWM_CTL, ctl);
870
	POSTING_READ(BLC_PWM_CTL);
954
	POSTING_READ(BLC_PWM_CTL);
Line 871... Line 955...
871
 
955
 
872
	/* XXX: combine this into above write? */
956
	/* XXX: combine this into above write? */
-
 
957
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
 
958
 
-
 
959
	/*
-
 
960
	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
-
 
961
	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
-
 
962
	 * that has backlight.
-
 
963
	 */
-
 
964
	if (IS_GEN2(dev))
873
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
965
		I915_WRITE(BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
Line 874... Line 966...
874
}
966
}
875
 
967
 
876
static void i965_enable_backlight(struct intel_connector *connector)
968
static void i965_enable_backlight(struct intel_connector *connector)
Line 937... Line 1029...
937
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
1029
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
938
	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
1030
	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
939
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
1031
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
940
}
1032
}
Line -... Line 1033...
-
 
1033
 
-
 
1034
static void bxt_enable_backlight(struct intel_connector *connector)
-
 
1035
{
-
 
1036
	struct drm_device *dev = connector->base.dev;
-
 
1037
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1038
	struct intel_panel *panel = &connector->panel;
-
 
1039
	enum pipe pipe = intel_get_pipe_from_connector(connector);
-
 
1040
	u32 pwm_ctl, val;
-
 
1041
 
-
 
1042
	/* To use 2nd set of backlight registers, utility pin has to be
-
 
1043
	 * enabled with PWM mode.
-
 
1044
	 * The field should only be changed when the utility pin is disabled
-
 
1045
	 */
-
 
1046
	if (panel->backlight.controller == 1) {
-
 
1047
		val = I915_READ(UTIL_PIN_CTL);
-
 
1048
		if (val & UTIL_PIN_ENABLE) {
-
 
1049
			DRM_DEBUG_KMS("util pin already enabled\n");
-
 
1050
			val &= ~UTIL_PIN_ENABLE;
-
 
1051
			I915_WRITE(UTIL_PIN_CTL, val);
-
 
1052
		}
-
 
1053
 
-
 
1054
		val = 0;
-
 
1055
		if (panel->backlight.util_pin_active_low)
-
 
1056
			val |= UTIL_PIN_POLARITY;
-
 
1057
		I915_WRITE(UTIL_PIN_CTL, val | UTIL_PIN_PIPE(pipe) |
-
 
1058
				UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
-
 
1059
	}
-
 
1060
 
-
 
1061
	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
-
 
1062
	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
-
 
1063
		DRM_DEBUG_KMS("backlight already enabled\n");
-
 
1064
		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
-
 
1065
		I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
-
 
1066
				pwm_ctl);
-
 
1067
	}
-
 
1068
 
-
 
1069
	I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller),
-
 
1070
			panel->backlight.max);
-
 
1071
 
-
 
1072
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
 
1073
 
-
 
1074
	pwm_ctl = 0;
-
 
1075
	if (panel->backlight.active_low_pwm)
-
 
1076
		pwm_ctl |= BXT_BLC_PWM_POLARITY;
-
 
1077
 
-
 
1078
	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl);
-
 
1079
	POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
-
 
1080
	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
-
 
1081
			pwm_ctl | BXT_BLC_PWM_ENABLE);
-
 
1082
}
-
 
1083
 
-
 
1084
static void pwm_enable_backlight(struct intel_connector *connector)
-
 
1085
{
-
 
1086
	struct intel_panel *panel = &connector->panel;
-
 
1087
 
-
 
1088
	pwm_enable(panel->backlight.pwm);
-
 
1089
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
-
 
1090
}
941
 
1091
 
942
void intel_panel_enable_backlight(struct intel_connector *connector)
1092
void intel_panel_enable_backlight(struct intel_connector *connector)
943
{
1093
{
944
	struct drm_device *dev = connector->base.dev;
1094
	struct drm_device *dev = connector->base.dev;
945
	struct drm_i915_private *dev_priv = dev->dev_private;
1095
	struct drm_i915_private *dev_priv = dev->dev_private;
Line 953... Line 1103...
953
 
1103
 
Line 954... Line 1104...
954
	mutex_lock(&dev_priv->backlight_lock);
1104
	mutex_lock(&dev_priv->backlight_lock);
Line 955... Line 1105...
955
 
1105
 
956
	WARN_ON(panel->backlight.max == 0);
-
 
957
 
-
 
958
	if (panel->backlight.level == 0) {
-
 
959
		panel->backlight.level = panel->backlight.max;
-
 
960
	}
1106
	WARN_ON(panel->backlight.max == 0);
Line 961... Line 1107...
961
 
1107
 
962
	dev_priv->display.enable_backlight(connector);
1108
	panel->backlight.enable(connector);
Line 975... Line 1121...
975
	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1121
	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
976
	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
1122
	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
977
		      bd->props.brightness, bd->props.max_brightness);
1123
		      bd->props.brightness, bd->props.max_brightness);
978
	intel_panel_set_backlight(connector, bd->props.brightness,
1124
	intel_panel_set_backlight(connector, bd->props.brightness,
979
				  bd->props.max_brightness);
1125
				  bd->props.max_brightness);
-
 
1126
 
-
 
1127
	/*
-
 
1128
	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
-
 
1129
	 * backlight class device does not make it easy to to differentiate
-
 
1130
	 * between callbacks for brightness and bl_power, so our backlight_power
-
 
1131
	 * callback needs to take this into account.
-
 
1132
	 */
-
 
1133
	if (panel->backlight.enabled) {
-
 
1134
		if (panel->backlight.power) {
-
 
1135
			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
-
 
1136
				bd->props.brightness != 0;
-
 
1137
			panel->backlight.power(connector, enable);
-
 
1138
		}
-
 
1139
	} else {
-
 
1140
		bd->props.power = FB_BLANK_POWERDOWN;
-
 
1141
	}
-
 
1142
 
980
	drm_modeset_unlock(&dev->mode_config.connection_mutex);
1143
	drm_modeset_unlock(&dev->mode_config.connection_mutex);
981
	return 0;
1144
	return 0;
982
}
1145
}
Line 983... Line 1146...
983
 
1146
 
Line 1077... Line 1240...
1077
{
1240
{
1078
}
1241
}
1079
#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
1242
#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
Line 1080... Line 1243...
1080
 
1243
 
-
 
1244
/*
-
 
1245
 * SPT: This value represents the period of the PWM stream in clock periods
-
 
1246
 * multiplied by 16 (default increment) or 128 (alternate increment selected in
-
 
1247
 * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
-
 
1248
 */
-
 
1249
static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-
 
1250
{
-
 
1251
	struct drm_device *dev = connector->base.dev;
-
 
1252
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1253
	u32 mul, clock;
-
 
1254
 
-
 
1255
	if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY)
-
 
1256
		mul = 128;
-
 
1257
	else
-
 
1258
		mul = 16;
-
 
1259
 
-
 
1260
	clock = MHz(24);
-
 
1261
 
-
 
1262
	return clock / (pwm_freq_hz * mul);
-
 
1263
}
-
 
1264
 
-
 
1265
/*
-
 
1266
 * LPT: This value represents the period of the PWM stream in clock periods
-
 
1267
 * multiplied by 128 (default increment) or 16 (alternate increment, selected in
-
 
1268
 * LPT SOUTH_CHICKEN2 register bit 5).
-
 
1269
 */
-
 
1270
static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-
 
1271
{
-
 
1272
	struct drm_device *dev = connector->base.dev;
-
 
1273
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1274
	u32 mul, clock;
-
 
1275
 
-
 
1276
	if (I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY)
-
 
1277
		mul = 16;
-
 
1278
	else
-
 
1279
		mul = 128;
-
 
1280
 
-
 
1281
	if (dev_priv->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE)
-
 
1282
		clock = MHz(135); /* LPT:H */
-
 
1283
	else
-
 
1284
		clock = MHz(24); /* LPT:LP */
-
 
1285
 
-
 
1286
	return clock / (pwm_freq_hz * mul);
-
 
1287
}
-
 
1288
 
-
 
1289
/*
1081
/*
1290
 * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
-
 
1291
 * display raw clocks multiplied by 128.
-
 
1292
 */
-
 
1293
static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-
 
1294
{
-
 
1295
	struct drm_device *dev = connector->base.dev;
-
 
1296
	int clock = MHz(intel_pch_rawclk(dev));
-
 
1297
 
-
 
1298
	return clock / (pwm_freq_hz * 128);
-
 
1299
}
-
 
1300
 
-
 
1301
/*
-
 
1302
 * Gen2: This field determines the number of time base events (display core
-
 
1303
 * clock frequency/32) in total for a complete cycle of modulated backlight
1082
 * Note: The setup hooks can't assume pipe is set!
1304
 * control.
-
 
1305
 *
-
 
1306
 * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
-
 
1307
 * divided by 32.
-
 
1308
 */
-
 
1309
static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-
 
1310
{
-
 
1311
	struct drm_device *dev = connector->base.dev;
-
 
1312
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1313
	int clock;
-
 
1314
 
-
 
1315
	if (IS_PINEVIEW(dev))
-
 
1316
		clock = intel_hrawclk(dev);
-
 
1317
	else
-
 
1318
		clock = 1000 * dev_priv->display.get_display_clock_speed(dev);
-
 
1319
 
-
 
1320
	return clock / (pwm_freq_hz * 32);
-
 
1321
}
-
 
1322
 
-
 
1323
/*
-
 
1324
 * Gen4: This value represents the period of the PWM stream in display core
-
 
1325
 * clocks multiplied by 128.
-
 
1326
 */
-
 
1327
static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-
 
1328
{
-
 
1329
	struct drm_device *dev = connector->base.dev;
-
 
1330
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1331
	int clock = 1000 * dev_priv->display.get_display_clock_speed(dev);
-
 
1332
 
-
 
1333
	return clock / (pwm_freq_hz * 128);
-
 
1334
}
-
 
1335
 
1083
 *
1336
/*
-
 
1337
 * VLV: This value represents the period of the PWM stream in display core
-
 
1338
 * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
-
 
1339
 * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
-
 
1340
 */
-
 
1341
static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
-
 
1342
{
-
 
1343
	struct drm_device *dev = connector->base.dev;
-
 
1344
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1345
	int clock;
-
 
1346
 
-
 
1347
	if ((I915_READ(CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
-
 
1348
		if (IS_CHERRYVIEW(dev))
-
 
1349
			return KHz(19200) / (pwm_freq_hz * 16);
-
 
1350
		else
-
 
1351
			return MHz(25) / (pwm_freq_hz * 16);
-
 
1352
	} else {
-
 
1353
		clock = intel_hrawclk(dev);
-
 
1354
		return MHz(clock) / (pwm_freq_hz * 128);
-
 
1355
	}
-
 
1356
}
-
 
1357
 
-
 
1358
static u32 get_backlight_max_vbt(struct intel_connector *connector)
-
 
1359
{
-
 
1360
	struct drm_device *dev = connector->base.dev;
-
 
1361
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1362
	struct intel_panel *panel = &connector->panel;
-
 
1363
	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
-
 
1364
	u32 pwm;
-
 
1365
 
-
 
1366
	if (!pwm_freq_hz) {
-
 
1367
		DRM_DEBUG_KMS("backlight frequency not specified in VBT\n");
-
 
1368
		return 0;
-
 
1369
	}
-
 
1370
 
-
 
1371
	if (!panel->backlight.hz_to_pwm) {
-
 
1372
		DRM_DEBUG_KMS("backlight frequency setting from VBT currently not supported on this platform\n");
-
 
1373
		return 0;
-
 
1374
	}
-
 
1375
 
-
 
1376
	pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz);
-
 
1377
	if (!pwm) {
-
 
1378
		DRM_DEBUG_KMS("backlight frequency conversion failed\n");
-
 
1379
		return 0;
-
 
1380
	}
-
 
1381
 
-
 
1382
	DRM_DEBUG_KMS("backlight frequency %u Hz from VBT\n", pwm_freq_hz);
-
 
1383
 
-
 
1384
	return pwm;
-
 
1385
}
-
 
1386
 
1084
 * XXX: Query mode clock or hardware clock and program PWM modulation frequency
1387
/*
1085
 * appropriately when it's 0. Use VBT and/or sane defaults.
1388
 * Note: The setup hooks can't assume pipe is set!
1086
 */
1389
 */
1087
static u32 get_backlight_min_vbt(struct intel_connector *connector)
1390
static u32 get_backlight_min_vbt(struct intel_connector *connector)
1088
{
1391
{
1089
	struct drm_device *dev = connector->base.dev;
1392
	struct drm_device *dev = connector->base.dev;
Line 1108... Line 1411...
1108
 
1411
 
1109
	/* vbt value is a coefficient in range [0..255] */
1412
	/* vbt value is a coefficient in range [0..255] */
1110
	return scale(min, 0, 255, 0, panel->backlight.max);
1413
	return scale(min, 0, 255, 0, panel->backlight.max);
Line 1111... Line 1414...
1111
}
1414
}
1112
 
1415
 
1113
static int bdw_setup_backlight(struct intel_connector *connector, enum pipe unused)
1416
static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
1114
{
1417
{
1115
	struct drm_device *dev = connector->base.dev;
1418
	struct drm_device *dev = connector->base.dev;
1116
	struct drm_i915_private *dev_priv = dev->dev_private;
1419
	struct drm_i915_private *dev_priv = dev->dev_private;
Line 1120... Line 1423...
1120
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
1423
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
1121
	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
1424
	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
Line 1122... Line 1425...
1122
 
1425
 
1123
	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
1426
	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
-
 
1427
	panel->backlight.max = pch_ctl2 >> 16;
-
 
1428
 
-
 
1429
	if (!panel->backlight.max)
-
 
1430
		panel->backlight.max = get_backlight_max_vbt(connector);
1124
	panel->backlight.max = pch_ctl2 >> 16;
1431
 
1125
	if (!panel->backlight.max)
1432
	if (!panel->backlight.max)
Line 1126... Line 1433...
1126
		return -ENODEV;
1433
		return -ENODEV;
Line 1127... Line 1434...
1127
 
1434
 
1128
	panel->backlight.min = get_backlight_min_vbt(connector);
1435
	panel->backlight.min = get_backlight_min_vbt(connector);
Line 1129... Line 1436...
1129
 
1436
 
1130
	val = bdw_get_backlight(connector);
1437
	val = lpt_get_backlight(connector);
Line 1146... Line 1453...
1146
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
1453
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
1147
	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
1454
	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
Line 1148... Line 1455...
1148
 
1455
 
1149
	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
1456
	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
-
 
1457
	panel->backlight.max = pch_ctl2 >> 16;
-
 
1458
 
-
 
1459
	if (!panel->backlight.max)
-
 
1460
		panel->backlight.max = get_backlight_max_vbt(connector);
1150
	panel->backlight.max = pch_ctl2 >> 16;
1461
 
1151
	if (!panel->backlight.max)
1462
	if (!panel->backlight.max)
Line 1152... Line 1463...
1152
		return -ENODEV;
1463
		return -ENODEV;
Line 1177... Line 1488...
1177
 
1488
 
1178
	if (IS_PINEVIEW(dev))
1489
	if (IS_PINEVIEW(dev))
Line 1179... Line 1490...
1179
		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
1490
		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
-
 
1491
 
1180
 
1492
	panel->backlight.max = ctl >> 17;
-
 
1493
 
1181
	panel->backlight.max = ctl >> 17;
1494
	if (!panel->backlight.max) {
-
 
1495
		panel->backlight.max = get_backlight_max_vbt(connector);
Line 1182... Line 1496...
1182
	if (panel->backlight.combination_mode)
1496
		panel->backlight.max >>= 1;
1183
		panel->backlight.max *= 0xff;
1497
	}
Line -... Line 1498...
-
 
1498
 
-
 
1499
	if (!panel->backlight.max)
-
 
1500
		return -ENODEV;
1184
 
1501
 
Line 1185... Line 1502...
1185
	if (!panel->backlight.max)
1502
	if (panel->backlight.combination_mode)
1186
		return -ENODEV;
1503
		panel->backlight.max *= 0xff;
Line 1206... Line 1523...
1206
	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
1523
	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
1207
	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
1524
	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
Line 1208... Line 1525...
1208
 
1525
 
1209
	ctl = I915_READ(BLC_PWM_CTL);
1526
	ctl = I915_READ(BLC_PWM_CTL);
-
 
1527
	panel->backlight.max = ctl >> 16;
1210
	panel->backlight.max = ctl >> 16;
1528
 
1211
	if (panel->backlight.combination_mode)
1529
	if (!panel->backlight.max)
Line 1212... Line 1530...
1212
		panel->backlight.max *= 0xff;
1530
		panel->backlight.max = get_backlight_max_vbt(connector);
1213
 
1531
 
Line -... Line 1532...
-
 
1532
	if (!panel->backlight.max)
-
 
1533
		return -ENODEV;
-
 
1534
 
1214
	if (!panel->backlight.max)
1535
	if (panel->backlight.combination_mode)
Line 1215... Line 1536...
1215
		return -ENODEV;
1536
		panel->backlight.max *= 0xff;
1216
 
1537
 
Line 1228... Line 1549...
1228
static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
1549
static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
1229
{
1550
{
1230
	struct drm_device *dev = connector->base.dev;
1551
	struct drm_device *dev = connector->base.dev;
1231
	struct drm_i915_private *dev_priv = dev->dev_private;
1552
	struct drm_i915_private *dev_priv = dev->dev_private;
1232
	struct intel_panel *panel = &connector->panel;
1553
	struct intel_panel *panel = &connector->panel;
1233
	enum pipe p;
-
 
1234
	u32 ctl, ctl2, val;
1554
	u32 ctl, ctl2, val;
Line 1235... Line -...
1235
 
-
 
1236
	for_each_pipe(dev_priv, p) {
-
 
1237
		u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(p));
-
 
1238
 
-
 
1239
		/* Skip if the modulation freq is already set */
-
 
1240
		if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
-
 
1241
			continue;
-
 
1242
 
-
 
1243
		cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
-
 
1244
		I915_WRITE(VLV_BLC_PWM_CTL(p), (0xf42 << 16) |
-
 
1245
			   cur_val);
-
 
1246
	}
-
 
1247
 
1555
 
1248
	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
1556
	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
Line 1249... Line 1557...
1249
		return -ENODEV;
1557
		return -ENODEV;
1250
 
1558
 
Line 1251... Line 1559...
1251
	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
1559
	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
1252
	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
1560
	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
-
 
1561
 
-
 
1562
	ctl = I915_READ(VLV_BLC_PWM_CTL(pipe));
-
 
1563
	panel->backlight.max = ctl >> 16;
-
 
1564
 
1253
 
1565
	if (!panel->backlight.max)
1254
	ctl = I915_READ(VLV_BLC_PWM_CTL(pipe));
1566
		panel->backlight.max = get_backlight_max_vbt(connector);
Line 1255... Line 1567...
1255
	panel->backlight.max = ctl >> 16;
1567
 
Line 1265... Line 1577...
1265
		panel->backlight.level != 0;
1577
		panel->backlight.level != 0;
Line 1266... Line 1578...
1266
 
1578
 
1267
	return 0;
1579
	return 0;
Line -... Line 1580...
-
 
1580
}
-
 
1581
 
-
 
1582
static int
-
 
1583
bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
-
 
1584
{
-
 
1585
	struct drm_device *dev = connector->base.dev;
-
 
1586
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1587
	struct intel_panel *panel = &connector->panel;
-
 
1588
	u32 pwm_ctl, val;
-
 
1589
 
-
 
1590
	/*
-
 
1591
	 * For BXT hard coding the Backlight controller to 0.
-
 
1592
	 * TODO : Read the controller value from VBT and generalize
-
 
1593
	 */
-
 
1594
	panel->backlight.controller = 0;
-
 
1595
 
-
 
1596
	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
-
 
1597
 
-
 
1598
	/* Keeping the check if controller 1 is to be programmed.
-
 
1599
	 * This will come into affect once the VBT parsing
-
 
1600
	 * is fixed for controller selection, and controller 1 is used
-
 
1601
	 * for a prticular display configuration.
-
 
1602
	 */
-
 
1603
	if (panel->backlight.controller == 1) {
-
 
1604
		val = I915_READ(UTIL_PIN_CTL);
-
 
1605
		panel->backlight.util_pin_active_low =
-
 
1606
					val & UTIL_PIN_POLARITY;
-
 
1607
	}
-
 
1608
 
-
 
1609
	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
-
 
1610
	panel->backlight.max =
-
 
1611
		I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller));
-
 
1612
 
-
 
1613
	if (!panel->backlight.max)
-
 
1614
		panel->backlight.max = get_backlight_max_vbt(connector);
-
 
1615
 
-
 
1616
	if (!panel->backlight.max)
-
 
1617
		return -ENODEV;
-
 
1618
 
-
 
1619
	val = bxt_get_backlight(connector);
-
 
1620
	panel->backlight.level = intel_panel_compute_brightness(connector, val);
-
 
1621
 
-
 
1622
	panel->backlight.enabled = (pwm_ctl & BXT_BLC_PWM_ENABLE) &&
-
 
1623
		panel->backlight.level != 0;
-
 
1624
 
-
 
1625
	return 0;
-
 
1626
}
-
 
1627
 
-
 
1628
static int pwm_setup_backlight(struct intel_connector *connector,
-
 
1629
			       enum pipe pipe)
-
 
1630
{
-
 
1631
	struct drm_device *dev = connector->base.dev;
-
 
1632
	struct intel_panel *panel = &connector->panel;
-
 
1633
	int retval;
-
 
1634
 
-
 
1635
	/* Get the PWM chip for backlight control */
-
 
1636
	panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
-
 
1637
	if (IS_ERR(panel->backlight.pwm)) {
-
 
1638
		DRM_ERROR("Failed to own the pwm chip\n");
-
 
1639
		panel->backlight.pwm = NULL;
-
 
1640
		return -ENODEV;
-
 
1641
	}
-
 
1642
 
-
 
1643
	retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS,
-
 
1644
			    CRC_PMIC_PWM_PERIOD_NS);
-
 
1645
	if (retval < 0) {
-
 
1646
		DRM_ERROR("Failed to configure the pwm chip\n");
-
 
1647
		pwm_put(panel->backlight.pwm);
-
 
1648
		panel->backlight.pwm = NULL;
-
 
1649
		return retval;
-
 
1650
	}
-
 
1651
 
-
 
1652
	panel->backlight.min = 0; /* 0% */
-
 
1653
	panel->backlight.max = 100; /* 100% */
-
 
1654
	panel->backlight.level = DIV_ROUND_UP(
-
 
1655
				 pwm_get_duty_cycle(panel->backlight.pwm) * 100,
-
 
1656
				 CRC_PMIC_PWM_PERIOD_NS);
-
 
1657
	panel->backlight.enabled = panel->backlight.level != 0;
-
 
1658
 
-
 
1659
	return 0;
1268
}
1660
}
1269
 
1661
 
1270
int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
1662
int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
1271
{
1663
{
1272
	struct drm_device *dev = connector->dev;
1664
	struct drm_device *dev = connector->dev;
Line 1282... Line 1674...
1282
			DRM_DEBUG_KMS("no backlight present per VBT\n");
1674
			DRM_DEBUG_KMS("no backlight present per VBT\n");
1283
		return 0;
1675
			return 0;
1284
	}
1676
		}
1285
	}
1677
	}
Line -... Line 1678...
-
 
1678
 
-
 
1679
	/* ensure intel_panel has been initialized first */
-
 
1680
	if (WARN_ON(!panel->backlight.setup))
-
 
1681
		return -ENODEV;
1286
 
1682
 
1287
	/* set level and max in panel struct */
1683
	/* set level and max in panel struct */
1288
	mutex_lock(&dev_priv->backlight_lock);
1684
	mutex_lock(&dev_priv->backlight_lock);
1289
	ret = dev_priv->display.setup_backlight(intel_connector, pipe);
1685
	ret = panel->backlight.setup(intel_connector, pipe);
Line 1290... Line 1686...
1290
	mutex_unlock(&dev_priv->backlight_lock);
1686
	mutex_unlock(&dev_priv->backlight_lock);
1291
 
1687
 
1292
	if (ret) {
1688
	if (ret) {
Line 1308... Line 1704...
1308
void intel_panel_destroy_backlight(struct drm_connector *connector)
1704
void intel_panel_destroy_backlight(struct drm_connector *connector)
1309
{
1705
{
1310
	struct intel_connector *intel_connector = to_intel_connector(connector);
1706
	struct intel_connector *intel_connector = to_intel_connector(connector);
1311
	struct intel_panel *panel = &intel_connector->panel;
1707
	struct intel_panel *panel = &intel_connector->panel;
Line -... Line 1708...
-
 
1708
 
-
 
1709
	/* dispose of the pwm */
-
 
1710
	if (panel->backlight.pwm)
-
 
1711
		pwm_put(panel->backlight.pwm);
1312
 
1712
 
1313
	panel->backlight.present = false;
1713
	panel->backlight.present = false;
Line 1314... Line 1714...
1314
}
1714
}
-
 
1715
 
1315
 
1716
/* Set up chip specific backlight functions */
1316
/* Set up chip specific backlight functions */
1717
static void
-
 
1718
intel_panel_init_backlight_funcs(struct intel_panel *panel)
-
 
1719
{
-
 
1720
	struct intel_connector *intel_connector =
1317
void intel_panel_init_backlight_funcs(struct drm_device *dev)
1721
		container_of(panel, struct intel_connector, panel);
1318
{
1722
	struct drm_device *dev = intel_connector->base.dev;
-
 
1723
	struct drm_i915_private *dev_priv = dev->dev_private;
-
 
1724
 
-
 
1725
	if (IS_BROXTON(dev)) {
-
 
1726
		panel->backlight.setup = bxt_setup_backlight;
-
 
1727
		panel->backlight.enable = bxt_enable_backlight;
-
 
1728
		panel->backlight.disable = bxt_disable_backlight;
1319
	struct drm_i915_private *dev_priv = dev->dev_private;
1729
		panel->backlight.set = bxt_set_backlight;
1320
 
1730
		panel->backlight.get = bxt_get_backlight;
1321
	if (IS_BROADWELL(dev) || (INTEL_INFO(dev)->gen >= 9)) {
1731
	} else if (HAS_PCH_LPT(dev) || HAS_PCH_SPT(dev)) {
1322
		dev_priv->display.setup_backlight = bdw_setup_backlight;
1732
		panel->backlight.setup = lpt_setup_backlight;
1323
		dev_priv->display.enable_backlight = bdw_enable_backlight;
1733
		panel->backlight.enable = lpt_enable_backlight;
1324
		dev_priv->display.disable_backlight = pch_disable_backlight;
1734
		panel->backlight.disable = lpt_disable_backlight;
-
 
1735
		panel->backlight.set = lpt_set_backlight;
-
 
1736
		panel->backlight.get = lpt_get_backlight;
-
 
1737
		if (HAS_PCH_LPT(dev))
-
 
1738
			panel->backlight.hz_to_pwm = lpt_hz_to_pwm;
1325
		dev_priv->display.set_backlight = bdw_set_backlight;
1739
		else
1326
		dev_priv->display.get_backlight = bdw_get_backlight;
1740
			panel->backlight.hz_to_pwm = spt_hz_to_pwm;
1327
	} else if (HAS_PCH_SPLIT(dev)) {
1741
	} else if (HAS_PCH_SPLIT(dev)) {
1328
		dev_priv->display.setup_backlight = pch_setup_backlight;
1742
		panel->backlight.setup = pch_setup_backlight;
1329
		dev_priv->display.enable_backlight = pch_enable_backlight;
1743
		panel->backlight.enable = pch_enable_backlight;
1330
		dev_priv->display.disable_backlight = pch_disable_backlight;
1744
		panel->backlight.disable = pch_disable_backlight;
-
 
1745
		panel->backlight.set = pch_set_backlight;
1331
		dev_priv->display.set_backlight = pch_set_backlight;
1746
		panel->backlight.get = pch_get_backlight;
-
 
1747
		panel->backlight.hz_to_pwm = pch_hz_to_pwm;
-
 
1748
	} else if (IS_VALLEYVIEW(dev)) {
-
 
1749
		if (dev_priv->vbt.has_mipi) {
-
 
1750
			panel->backlight.setup = pwm_setup_backlight;
-
 
1751
			panel->backlight.enable = pwm_enable_backlight;
-
 
1752
			panel->backlight.disable = pwm_disable_backlight;
-
 
1753
			panel->backlight.set = pwm_set_backlight;
1332
		dev_priv->display.get_backlight = pch_get_backlight;
1754
			panel->backlight.get = pwm_get_backlight;
1333
	} else if (IS_VALLEYVIEW(dev)) {
1755
		} else {
1334
		dev_priv->display.setup_backlight = vlv_setup_backlight;
1756
			panel->backlight.setup = vlv_setup_backlight;
1335
		dev_priv->display.enable_backlight = vlv_enable_backlight;
1757
			panel->backlight.enable = vlv_enable_backlight;
1336
		dev_priv->display.disable_backlight = vlv_disable_backlight;
1758
			panel->backlight.disable = vlv_disable_backlight;
-
 
1759
			panel->backlight.set = vlv_set_backlight;
-
 
1760
			panel->backlight.get = vlv_get_backlight;
1337
		dev_priv->display.set_backlight = vlv_set_backlight;
1761
			panel->backlight.hz_to_pwm = vlv_hz_to_pwm;
1338
		dev_priv->display.get_backlight = vlv_get_backlight;
1762
		}
1339
	} else if (IS_GEN4(dev)) {
1763
	} else if (IS_GEN4(dev)) {
1340
		dev_priv->display.setup_backlight = i965_setup_backlight;
1764
		panel->backlight.setup = i965_setup_backlight;
1341
		dev_priv->display.enable_backlight = i965_enable_backlight;
1765
		panel->backlight.enable = i965_enable_backlight;
1342
		dev_priv->display.disable_backlight = i965_disable_backlight;
1766
		panel->backlight.disable = i965_disable_backlight;
-
 
1767
		panel->backlight.set = i9xx_set_backlight;
1343
		dev_priv->display.set_backlight = i9xx_set_backlight;
1768
		panel->backlight.get = i9xx_get_backlight;
1344
		dev_priv->display.get_backlight = i9xx_get_backlight;
1769
		panel->backlight.hz_to_pwm = i965_hz_to_pwm;
1345
	} else {
1770
	} else {
1346
		dev_priv->display.setup_backlight = i9xx_setup_backlight;
1771
		panel->backlight.setup = i9xx_setup_backlight;
1347
		dev_priv->display.enable_backlight = i9xx_enable_backlight;
1772
		panel->backlight.enable = i9xx_enable_backlight;
1348
		dev_priv->display.disable_backlight = i9xx_disable_backlight;
1773
		panel->backlight.disable = i9xx_disable_backlight;
-
 
1774
		panel->backlight.set = i9xx_set_backlight;
1349
		dev_priv->display.set_backlight = i9xx_set_backlight;
1775
		panel->backlight.get = i9xx_get_backlight;
1350
		dev_priv->display.get_backlight = i9xx_get_backlight;
1776
		panel->backlight.hz_to_pwm = i9xx_hz_to_pwm;
Line 1351... Line 1777...
1351
	}
1777
	}
1352
}
1778
}
1353
 
1779
 
1354
int intel_panel_init(struct intel_panel *panel,
1780
int intel_panel_init(struct intel_panel *panel,
-
 
1781
		     struct drm_display_mode *fixed_mode,
-
 
1782
		     struct drm_display_mode *downclock_mode)
1355
		     struct drm_display_mode *fixed_mode,
1783
{
1356
		     struct drm_display_mode *downclock_mode)
1784
	intel_panel_init_backlight_funcs(panel);
Line 1357... Line 1785...
1357
{
1785
 
1358
	panel->fixed_mode = fixed_mode;
1786
	panel->fixed_mode = fixed_mode;