Subversion Repositories Kolibri OS

Rev

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

Rev 5060 Rev 6084
Line 20... Line 20...
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
21
 * DEALINGS IN THE SOFTWARE.
22
 *
22
 *
23
 * Authors:
23
 * Authors:
24
 *    Eric Anholt 
24
 *    Eric Anholt 
-
 
25
 *    Thomas Richter 
-
 
26
 *
-
 
27
 * Minor modifications (Dithering enable):
-
 
28
 *    Thomas Richter 
25
 *
29
 *
26
 */
30
 */
Line 27... Line 31...
27
 
31
 
Line 57... Line 61...
57
# define VR01_LCD_ENABLE		(1 << 2)
61
# define VR01_LCD_ENABLE		(1 << 2)
58
/** Enables the DVO repeater. */
62
/** Enables the DVO repeater. */
59
# define VR01_DVO_BYPASS_ENABLE		(1 << 1)
63
# define VR01_DVO_BYPASS_ENABLE		(1 << 1)
60
/** Enables the DVO clock */
64
/** Enables the DVO clock */
61
# define VR01_DVO_ENABLE		(1 << 0)
65
# define VR01_DVO_ENABLE		(1 << 0)
-
 
66
/** Enable dithering for 18bpp panels. Not documented. */
-
 
67
# define VR01_DITHER_ENABLE             (1 << 4)
Line 62... Line 68...
62
 
68
 
63
/*
69
/*
64
 * LCD Interface Format
70
 * LCD Interface Format
65
 */
71
 */
Line 72... Line 78...
72
# define VR10_INTERFACE_1X24		(1 << 2)
78
# define VR10_INTERFACE_1X24		(1 << 2)
73
/** Enables 2x18-bit LVDS or CMOS output. */
79
/** Enables 2x18-bit LVDS or CMOS output. */
74
# define VR10_INTERFACE_2X18		(2 << 2)
80
# define VR10_INTERFACE_2X18		(2 << 2)
75
/** Enables 2x24-bit LVDS output */
81
/** Enables 2x24-bit LVDS output */
76
# define VR10_INTERFACE_2X24		(3 << 2)
82
# define VR10_INTERFACE_2X24		(3 << 2)
-
 
83
/** Mask that defines the depth of the pipeline */
-
 
84
# define VR10_INTERFACE_DEPTH_MASK      (3 << 2)
Line 77... Line 85...
77
 
85
 
78
/*
86
/*
79
 * VR20 LCD Horizontal Display Size
87
 * VR20 LCD Horizontal Display Size
80
 */
88
 */
Line 81... Line 89...
81
#define VR20	0x20
89
#define VR20	0x20
82
 
90
 
83
/*
91
/*
84
 * LCD Vertical Display Size
92
 * LCD Vertical Display Size
Line 85... Line 93...
85
 */
93
 */
86
#define VR21	0x20
94
#define VR21	0x21
87
 
95
 
88
/*
96
/*
Line 146... Line 154...
146
# define VR8F_VCH_PRESENT		(1 << 0)
154
# define VR8F_VCH_PRESENT		(1 << 0)
147
# define VR8F_DISPLAY_CONN		(1 << 1)
155
# define VR8F_DISPLAY_CONN		(1 << 1)
148
# define VR8F_POWER_MASK		(0x3c)
156
# define VR8F_POWER_MASK		(0x3c)
149
# define VR8F_POWER_POS			(2)
157
# define VR8F_POWER_POS			(2)
Line -... Line 158...
-
 
158
 
-
 
159
/* Some Bios implementations do not restore the DVO state upon
-
 
160
 * resume from standby. Thus, this driver has to handle it
-
 
161
 * instead. The following list contains all registers that
-
 
162
 * require saving.
-
 
163
 */
-
 
164
static const uint16_t backup_addresses[] = {
-
 
165
	0x11, 0x12,
-
 
166
	0x18, 0x19, 0x1a, 0x1f,
-
 
167
	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-
 
168
	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-
 
169
	0x8e, 0x8f,
-
 
170
	0x10		/* this must come last */
-
 
171
};
Line 150... Line 172...
150
 
172
 
151
 
173
 
Line 152... Line 174...
152
struct ivch_priv {
174
struct ivch_priv {
-
 
175
	bool quiet;
-
 
176
 
-
 
177
	uint16_t width, height;
-
 
178
 
153
	bool quiet;
179
	/* Register backup */
Line 154... Line 180...
154
 
180
 
155
	uint16_t width, height;
-
 
156
};
181
	uint16_t reg_backup[ARRAY_SIZE(backup_addresses)];
157
 
182
};
158
 
183
 
159
static void ivch_dump_regs(struct intel_dvo_device *dvo);
184
 
160
 
185
static void ivch_dump_regs(struct intel_dvo_device *dvo);
Line 237... Line 262...
237
static bool ivch_init(struct intel_dvo_device *dvo,
262
static bool ivch_init(struct intel_dvo_device *dvo,
238
		      struct i2c_adapter *adapter)
263
		      struct i2c_adapter *adapter)
239
{
264
{
240
	struct ivch_priv *priv;
265
	struct ivch_priv *priv;
241
	uint16_t temp;
266
	uint16_t temp;
-
 
267
	int i;
Line 242... Line 268...
242
 
268
 
243
	priv = kzalloc(sizeof(struct ivch_priv), GFP_KERNEL);
269
	priv = kzalloc(sizeof(struct ivch_priv), GFP_KERNEL);
244
	if (priv == NULL)
270
	if (priv == NULL)
Line 264... Line 290...
264
	}
290
	}
Line 265... Line 291...
265
 
291
 
266
	ivch_read(dvo, VR20, &priv->width);
292
	ivch_read(dvo, VR20, &priv->width);
Line -... Line 293...
-
 
293
	ivch_read(dvo, VR21, &priv->height);
-
 
294
 
-
 
295
	/* Make a backup of the registers to be able to restore them
-
 
296
	 * upon suspend.
-
 
297
	 */
-
 
298
	for (i = 0; i < ARRAY_SIZE(backup_addresses); i++)
-
 
299
		ivch_read(dvo, backup_addresses[i], priv->reg_backup + i);
-
 
300
 
267
	ivch_read(dvo, VR21, &priv->height);
301
	ivch_dump_regs(dvo);
Line 268... Line 302...
268
 
302
 
269
	return true;
303
	return true;
270
 
304
 
Line 285... Line 319...
285
		return MODE_CLOCK_HIGH;
319
		return MODE_CLOCK_HIGH;
Line 286... Line 320...
286
 
320
 
287
	return MODE_OK;
321
	return MODE_OK;
Line -... Line 322...
-
 
322
}
-
 
323
 
-
 
324
/* Restore the DVO registers after a resume
-
 
325
 * from RAM. Registers have been saved during
-
 
326
 * the initialization.
-
 
327
 */
-
 
328
static void ivch_reset(struct intel_dvo_device *dvo)
-
 
329
{
-
 
330
	struct ivch_priv *priv = dvo->dev_priv;
-
 
331
	int i;
-
 
332
 
-
 
333
	DRM_DEBUG_KMS("Resetting the IVCH registers\n");
-
 
334
 
-
 
335
	ivch_write(dvo, VR10, 0x0000);
-
 
336
 
-
 
337
	for (i = 0; i < ARRAY_SIZE(backup_addresses); i++)
-
 
338
		ivch_write(dvo, backup_addresses[i], priv->reg_backup[i]);
288
}
339
}
289
 
340
 
290
/** Sets the power state of the panel connected to the ivch */
341
/** Sets the power state of the panel connected to the ivch */
291
static void ivch_dpms(struct intel_dvo_device *dvo, bool enable)
342
static void ivch_dpms(struct intel_dvo_device *dvo, bool enable)
292
{
343
{
Line -... Line 344...
-
 
344
	int i;
-
 
345
	uint16_t vr01, vr30, backlight;
293
	int i;
346
 
294
	uint16_t vr01, vr30, backlight;
347
	ivch_reset(dvo);
295
 
348
 
Line 296... Line 349...
296
	/* Set the new power state of the panel. */
349
	/* Set the new power state of the panel. */
297
	if (!ivch_read(dvo, VR01, &vr01))
350
	if (!ivch_read(dvo, VR01, &vr01))
298
		return;
351
		return;
299
 
352
 
-
 
353
	if (enable)
300
	if (enable)
354
		backlight = 1;
Line 301... Line 355...
301
		backlight = 1;
355
	else
302
	else
356
		backlight = 0;
303
		backlight = 0;
357
 
Line 325... Line 379...
325
 
379
 
326
static bool ivch_get_hw_state(struct intel_dvo_device *dvo)
380
static bool ivch_get_hw_state(struct intel_dvo_device *dvo)
327
{
381
{
Line -... Line 382...
-
 
382
	uint16_t vr01;
-
 
383
 
328
	uint16_t vr01;
384
	ivch_reset(dvo);
329
 
385
 
330
	/* Set the new power state of the panel. */
386
	/* Set the new power state of the panel. */
Line 331... Line 387...
331
	if (!ivch_read(dvo, VR01, &vr01))
387
	if (!ivch_read(dvo, VR01, &vr01))
Line 336... Line 392...
336
	else
392
	else
337
		return false;
393
		return false;
338
}
394
}
Line 339... Line 395...
339
 
395
 
340
static void ivch_mode_set(struct intel_dvo_device *dvo,
396
static void ivch_mode_set(struct intel_dvo_device *dvo,
341
			  struct drm_display_mode *mode,
397
			  const struct drm_display_mode *mode,
342
			  struct drm_display_mode *adjusted_mode)
398
			  const struct drm_display_mode *adjusted_mode)
-
 
399
{
343
{
400
	struct ivch_priv *priv = dvo->dev_priv;
-
 
401
	uint16_t vr40 = 0;
344
	uint16_t vr40 = 0;
402
	uint16_t vr01 = 0;
-
 
403
	uint16_t vr10;
-
 
404
 
-
 
405
	ivch_reset(dvo);
-
 
406
 
-
 
407
	vr10 = priv->reg_backup[ARRAY_SIZE(backup_addresses) - 1];
-
 
408
 
-
 
409
	/* Enable dithering for 18 bpp pipelines */
-
 
410
	vr10 &= VR10_INTERFACE_DEPTH_MASK;
-
 
411
	if (vr10 == VR10_INTERFACE_2X18 || vr10 == VR10_INTERFACE_1X18)
Line 345... Line -...
345
	uint16_t vr01;
-
 
346
 
412
		vr01 = VR01_DITHER_ENABLE;
347
	vr01 = 0;
413
 
Line 348... Line 414...
348
	vr40 = (VR40_STALL_ENABLE | VR40_VERTICAL_INTERP_ENABLE |
414
	vr40 = (VR40_STALL_ENABLE | VR40_VERTICAL_INTERP_ENABLE |
349
		VR40_HORIZONTAL_INTERP_ENABLE);
415
		VR40_HORIZONTAL_INTERP_ENABLE);
350
 
416
 
Line 351... Line 417...
351
	if (mode->hdisplay != adjusted_mode->hdisplay ||
417
	if (mode->hdisplay != adjusted_mode->crtc_hdisplay ||
352
	    mode->vdisplay != adjusted_mode->vdisplay) {
418
	    mode->vdisplay != adjusted_mode->crtc_vdisplay) {
353
		uint16_t x_ratio, y_ratio;
419
		uint16_t x_ratio, y_ratio;
354
 
420
 
355
		vr01 |= VR01_PANEL_FIT_ENABLE;
421
		vr01 |= VR01_PANEL_FIT_ENABLE;
356
		vr40 |= VR40_CLOCK_GATING_ENABLE;
422
		vr40 |= VR40_CLOCK_GATING_ENABLE;
357
		x_ratio = (((mode->hdisplay - 1) << 16) /
423
		x_ratio = (((mode->hdisplay - 1) << 16) /
358
			   (adjusted_mode->hdisplay - 1)) >> 2;
424
			   (adjusted_mode->crtc_hdisplay - 1)) >> 2;
359
		y_ratio = (((mode->vdisplay - 1) << 16) /
425
		y_ratio = (((mode->vdisplay - 1) << 16) /
360
			   (adjusted_mode->vdisplay - 1)) >> 2;
426
			   (adjusted_mode->crtc_vdisplay - 1)) >> 2;
361
		ivch_write(dvo, VR42, x_ratio);
427
		ivch_write(dvo, VR42, x_ratio);
362
		ivch_write(dvo, VR41, y_ratio);
428
		ivch_write(dvo, VR41, y_ratio);
363
	} else {
429
	} else {
Line 364... Line 430...
364
		vr01 &= ~VR01_PANEL_FIT_ENABLE;
430
		vr01 &= ~VR01_PANEL_FIT_ENABLE;
365
		vr40 &= ~VR40_CLOCK_GATING_ENABLE;
431
		vr40 &= ~VR40_CLOCK_GATING_ENABLE;
366
	}
-
 
367
	vr40 &= ~VR40_AUTO_RATIO_ENABLE;
-
 
368
 
432
	}
Line 369... Line 433...
369
	ivch_write(dvo, VR01, vr01);
433
	vr40 &= ~VR40_AUTO_RATIO_ENABLE;
370
	ivch_write(dvo, VR40, vr40);
434
 
371
 
435
	ivch_write(dvo, VR01, vr01);
Line 372... Line 436...
372
	ivch_dump_regs(dvo);
436
	ivch_write(dvo, VR40, vr40);
373
}
437
}
374
 
438
 
375
static void ivch_dump_regs(struct intel_dvo_device *dvo)
439
static void ivch_dump_regs(struct intel_dvo_device *dvo)
-
 
440
{
-
 
441
	uint16_t val;
376
{
442
 
377
	uint16_t val;
443
	ivch_read(dvo, VR00, &val);
378
 
444
	DRM_DEBUG_KMS("VR00: 0x%04x\n", val);
379
	ivch_read(dvo, VR00, &val);
445
	ivch_read(dvo, VR01, &val);