forked from mirrors/linux
		
	drm/i915/skl: Buffer translation improvements
This patch adds support for 0.85V VccIO on Skylake Y, separate buffer translation tables for Skylake U, and support for I_boost for the entries that needs this. Changes in v2: * Refactored the code a bit to move all DDI signal level setup to intel_ddi.c Issue: VIZ-5677 Signed-off-by: David Weinehall <david.weinehall@linux.intel.com> Reviewed-by: Antti Koskipää <antti.koskipaa@linux.intel.com> [danvet: Apply style polish checkpatch suggested.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
		
							parent
							
								
									2cb389b7e4
								
							
						
					
					
						commit
						f8896f5d58
					
				
					 5 changed files with 423 additions and 213 deletions
				
			
		| 
						 | 
					@ -2436,6 +2436,14 @@ struct drm_i915_cmd_table {
 | 
				
			||||||
/* ULX machines are also considered ULT. */
 | 
					/* ULX machines are also considered ULT. */
 | 
				
			||||||
#define IS_HSW_ULX(dev)		(INTEL_DEVID(dev) == 0x0A0E || \
 | 
					#define IS_HSW_ULX(dev)		(INTEL_DEVID(dev) == 0x0A0E || \
 | 
				
			||||||
				 INTEL_DEVID(dev) == 0x0A1E)
 | 
									 INTEL_DEVID(dev) == 0x0A1E)
 | 
				
			||||||
 | 
					#define IS_SKL_ULT(dev)		(INTEL_DEVID(dev) == 0x1906 || \
 | 
				
			||||||
 | 
									 INTEL_DEVID(dev) == 0x1913 || \
 | 
				
			||||||
 | 
									 INTEL_DEVID(dev) == 0x1916 || \
 | 
				
			||||||
 | 
									 INTEL_DEVID(dev) == 0x1921 || \
 | 
				
			||||||
 | 
									 INTEL_DEVID(dev) == 0x1926)
 | 
				
			||||||
 | 
					#define IS_SKL_ULX(dev)		(INTEL_DEVID(dev) == 0x190E || \
 | 
				
			||||||
 | 
									 INTEL_DEVID(dev) == 0x1915 || \
 | 
				
			||||||
 | 
									 INTEL_DEVID(dev) == 0x191E)
 | 
				
			||||||
#define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
 | 
					#define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SKL_REVID_A0		(0x0)
 | 
					#define SKL_REVID_A0		(0x0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1384,6 +1384,18 @@ enum skl_disp_power_wells {
 | 
				
			||||||
							_PORT_TX_DW14_LN0_C) + \
 | 
												_PORT_TX_DW14_LN0_C) + \
 | 
				
			||||||
					 _BXT_LANE_OFFSET(lane))
 | 
										 _BXT_LANE_OFFSET(lane))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* UAIMI scratch pad register 1 */
 | 
				
			||||||
 | 
					#define UAIMI_SPR1			0x4F074
 | 
				
			||||||
 | 
					/* SKL VccIO mask */
 | 
				
			||||||
 | 
					#define SKL_VCCIO_MASK			0x1
 | 
				
			||||||
 | 
					/* SKL balance leg register */
 | 
				
			||||||
 | 
					#define DISPIO_CR_TX_BMU_CR0		0x6C00C
 | 
				
			||||||
 | 
					/* I_boost values */
 | 
				
			||||||
 | 
					#define BALANCE_LEG_SHIFT(port)		(8+3*(port))
 | 
				
			||||||
 | 
					#define BALANCE_LEG_MASK(port)		(7<<(8+3*(port)))
 | 
				
			||||||
 | 
					/* Balance leg disable bits */
 | 
				
			||||||
 | 
					#define BALANCE_LEG_DISABLE_SHIFT	23
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Fence registers
 | 
					 * Fence registers
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@
 | 
				
			||||||
struct ddi_buf_trans {
 | 
					struct ddi_buf_trans {
 | 
				
			||||||
	u32 trans1;	/* balance leg enable, de-emph level */
 | 
						u32 trans1;	/* balance leg enable, de-emph level */
 | 
				
			||||||
	u32 trans2;	/* vref sel, vswing */
 | 
						u32 trans2;	/* vref sel, vswing */
 | 
				
			||||||
 | 
						u8 i_boost;	/* SKL: I_boost; valid: 0x0, 0x1, 0x3, 0x7 */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* HDMI/DVI modes ignore everything but the last 2 items. So we share
 | 
					/* HDMI/DVI modes ignore everything but the last 2 items. So we share
 | 
				
			||||||
| 
						 | 
					@ -38,134 +39,213 @@ struct ddi_buf_trans {
 | 
				
			||||||
 * automatically adapt to HDMI connections as well
 | 
					 * automatically adapt to HDMI connections as well
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
 | 
					static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0006000E },
 | 
						{ 0x00FFFFFF, 0x0006000E, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x0005000A },
 | 
						{ 0x00D75FFF, 0x0005000A, 0x0 },
 | 
				
			||||||
	{ 0x00C30FFF, 0x00040006 },
 | 
						{ 0x00C30FFF, 0x00040006, 0x0 },
 | 
				
			||||||
	{ 0x80AAAFFF, 0x000B0000 },
 | 
						{ 0x80AAAFFF, 0x000B0000, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0005000A },
 | 
						{ 0x00FFFFFF, 0x0005000A, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x000C0004 },
 | 
						{ 0x00D75FFF, 0x000C0004, 0x0 },
 | 
				
			||||||
	{ 0x80C30FFF, 0x000B0000 },
 | 
						{ 0x80C30FFF, 0x000B0000, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x00040006 },
 | 
						{ 0x00FFFFFF, 0x00040006, 0x0 },
 | 
				
			||||||
	{ 0x80D75FFF, 0x000B0000 },
 | 
						{ 0x80D75FFF, 0x000B0000, 0x0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
 | 
					static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0007000E },
 | 
						{ 0x00FFFFFF, 0x0007000E, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x000F000A },
 | 
						{ 0x00D75FFF, 0x000F000A, 0x0 },
 | 
				
			||||||
	{ 0x00C30FFF, 0x00060006 },
 | 
						{ 0x00C30FFF, 0x00060006, 0x0 },
 | 
				
			||||||
	{ 0x00AAAFFF, 0x001E0000 },
 | 
						{ 0x00AAAFFF, 0x001E0000, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x000F000A },
 | 
						{ 0x00FFFFFF, 0x000F000A, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x00160004 },
 | 
						{ 0x00D75FFF, 0x00160004, 0x0 },
 | 
				
			||||||
	{ 0x00C30FFF, 0x001E0000 },
 | 
						{ 0x00C30FFF, 0x001E0000, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x00060006 },
 | 
						{ 0x00FFFFFF, 0x00060006, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x001E0000 },
 | 
						{ 0x00D75FFF, 0x001E0000, 0x0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
 | 
					static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
 | 
				
			||||||
					/* Idx	NT mV d	T mV d	db	*/
 | 
										/* Idx	NT mV d	T mV d	db	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0006000E },	/* 0:	400	400	0	*/
 | 
						{ 0x00FFFFFF, 0x0006000E, 0x0 },/* 0:	400	400	0	*/
 | 
				
			||||||
	{ 0x00E79FFF, 0x000E000C },	/* 1:	400	500	2	*/
 | 
						{ 0x00E79FFF, 0x000E000C, 0x0 },/* 1:	400	500	2	*/
 | 
				
			||||||
	{ 0x00D75FFF, 0x0005000A },	/* 2:	400	600	3.5	*/
 | 
						{ 0x00D75FFF, 0x0005000A, 0x0 },/* 2:	400	600	3.5	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0005000A },	/* 3:	600	600	0	*/
 | 
						{ 0x00FFFFFF, 0x0005000A, 0x0 },/* 3:	600	600	0	*/
 | 
				
			||||||
	{ 0x00E79FFF, 0x001D0007 },	/* 4:	600	750	2	*/
 | 
						{ 0x00E79FFF, 0x001D0007, 0x0 },/* 4:	600	750	2	*/
 | 
				
			||||||
	{ 0x00D75FFF, 0x000C0004 },	/* 5:	600	900	3.5	*/
 | 
						{ 0x00D75FFF, 0x000C0004, 0x0 },/* 5:	600	900	3.5	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x00040006 },	/* 6:	800	800	0	*/
 | 
						{ 0x00FFFFFF, 0x00040006, 0x0 },/* 6:	800	800	0	*/
 | 
				
			||||||
	{ 0x80E79FFF, 0x00030002 },	/* 7:	800	1000	2	*/
 | 
						{ 0x80E79FFF, 0x00030002, 0x0 },/* 7:	800	1000	2	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x00140005 },	/* 8:	850	850	0	*/
 | 
						{ 0x00FFFFFF, 0x00140005, 0x0 },/* 8:	850	850	0	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x000C0004 },	/* 9:	900	900	0	*/
 | 
						{ 0x00FFFFFF, 0x000C0004, 0x0 },/* 9:	900	900	0	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x001C0003 },	/* 10:	950	950	0	*/
 | 
						{ 0x00FFFFFF, 0x001C0003, 0x0 },/* 10:	950	950	0	*/
 | 
				
			||||||
	{ 0x80FFFFFF, 0x00030002 },	/* 11:	1000	1000	0	*/
 | 
						{ 0x80FFFFFF, 0x00030002, 0x0 },/* 11:	1000	1000	0	*/
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
 | 
					static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
 | 
				
			||||||
	{ 0x00FFFFFF, 0x00000012 },
 | 
						{ 0x00FFFFFF, 0x00000012, 0x0 },
 | 
				
			||||||
	{ 0x00EBAFFF, 0x00020011 },
 | 
						{ 0x00EBAFFF, 0x00020011, 0x0 },
 | 
				
			||||||
	{ 0x00C71FFF, 0x0006000F },
 | 
						{ 0x00C71FFF, 0x0006000F, 0x0 },
 | 
				
			||||||
	{ 0x00AAAFFF, 0x000E000A },
 | 
						{ 0x00AAAFFF, 0x000E000A, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x00020011 },
 | 
						{ 0x00FFFFFF, 0x00020011, 0x0 },
 | 
				
			||||||
	{ 0x00DB6FFF, 0x0005000F },
 | 
						{ 0x00DB6FFF, 0x0005000F, 0x0 },
 | 
				
			||||||
	{ 0x00BEEFFF, 0x000A000C },
 | 
						{ 0x00BEEFFF, 0x000A000C, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0005000F },
 | 
						{ 0x00FFFFFF, 0x0005000F, 0x0 },
 | 
				
			||||||
	{ 0x00DB6FFF, 0x000A000C },
 | 
						{ 0x00DB6FFF, 0x000A000C, 0x0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
 | 
					static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0007000E },
 | 
						{ 0x00FFFFFF, 0x0007000E, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x000E000A },
 | 
						{ 0x00D75FFF, 0x000E000A, 0x0 },
 | 
				
			||||||
	{ 0x00BEFFFF, 0x00140006 },
 | 
						{ 0x00BEFFFF, 0x00140006, 0x0 },
 | 
				
			||||||
	{ 0x80B2CFFF, 0x001B0002 },
 | 
						{ 0x80B2CFFF, 0x001B0002, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x000E000A },
 | 
						{ 0x00FFFFFF, 0x000E000A, 0x0 },
 | 
				
			||||||
	{ 0x00DB6FFF, 0x00160005 },
 | 
						{ 0x00DB6FFF, 0x00160005, 0x0 },
 | 
				
			||||||
	{ 0x80C71FFF, 0x001A0002 },
 | 
						{ 0x80C71FFF, 0x001A0002, 0x0 },
 | 
				
			||||||
	{ 0x00F7DFFF, 0x00180004 },
 | 
						{ 0x00F7DFFF, 0x00180004, 0x0 },
 | 
				
			||||||
	{ 0x80D75FFF, 0x001B0002 },
 | 
						{ 0x80D75FFF, 0x001B0002, 0x0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
 | 
					static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0001000E },
 | 
						{ 0x00FFFFFF, 0x0001000E, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x0004000A },
 | 
						{ 0x00D75FFF, 0x0004000A, 0x0 },
 | 
				
			||||||
	{ 0x00C30FFF, 0x00070006 },
 | 
						{ 0x00C30FFF, 0x00070006, 0x0 },
 | 
				
			||||||
	{ 0x00AAAFFF, 0x000C0000 },
 | 
						{ 0x00AAAFFF, 0x000C0000, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0004000A },
 | 
						{ 0x00FFFFFF, 0x0004000A, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x00090004 },
 | 
						{ 0x00D75FFF, 0x00090004, 0x0 },
 | 
				
			||||||
	{ 0x00C30FFF, 0x000C0000 },
 | 
						{ 0x00C30FFF, 0x000C0000, 0x0 },
 | 
				
			||||||
	{ 0x00FFFFFF, 0x00070006 },
 | 
						{ 0x00FFFFFF, 0x00070006, 0x0 },
 | 
				
			||||||
	{ 0x00D75FFF, 0x000C0000 },
 | 
						{ 0x00D75FFF, 0x000C0000, 0x0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
 | 
					static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
 | 
				
			||||||
					/* Idx	NT mV d	T mV df	db	*/
 | 
										/* Idx	NT mV d	T mV df	db	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0007000E },	/* 0:	400	400	0	*/
 | 
						{ 0x00FFFFFF, 0x0007000E, 0x0 },/* 0:	400	400	0	*/
 | 
				
			||||||
	{ 0x00D75FFF, 0x000E000A },	/* 1:	400	600	3.5	*/
 | 
						{ 0x00D75FFF, 0x000E000A, 0x0 },/* 1:	400	600	3.5	*/
 | 
				
			||||||
	{ 0x00BEFFFF, 0x00140006 },	/* 2:	400	800	6	*/
 | 
						{ 0x00BEFFFF, 0x00140006, 0x0 },/* 2:	400	800	6	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x0009000D },	/* 3:	450	450	0	*/
 | 
						{ 0x00FFFFFF, 0x0009000D, 0x0 },/* 3:	450	450	0	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x000E000A },	/* 4:	600	600	0	*/
 | 
						{ 0x00FFFFFF, 0x000E000A, 0x0 },/* 4:	600	600	0	*/
 | 
				
			||||||
	{ 0x00D7FFFF, 0x00140006 },	/* 5:	600	800	2.5	*/
 | 
						{ 0x00D7FFFF, 0x00140006, 0x0 },/* 5:	600	800	2.5	*/
 | 
				
			||||||
	{ 0x80CB2FFF, 0x001B0002 },	/* 6:	600	1000	4.5	*/
 | 
						{ 0x80CB2FFF, 0x001B0002, 0x0 },/* 6:	600	1000	4.5	*/
 | 
				
			||||||
	{ 0x00FFFFFF, 0x00140006 },	/* 7:	800	800	0	*/
 | 
						{ 0x00FFFFFF, 0x00140006, 0x0 },/* 7:	800	800	0	*/
 | 
				
			||||||
	{ 0x80E79FFF, 0x001B0002 },	/* 8:	800	1000	2	*/
 | 
						{ 0x80E79FFF, 0x001B0002, 0x0 },/* 8:	800	1000	2	*/
 | 
				
			||||||
	{ 0x80FFFFFF, 0x001B0002 },	/* 9:	1000	1000	0	*/
 | 
						{ 0x80FFFFFF, 0x001B0002, 0x0 },/* 9:	1000	1000	0	*/
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Skylake H, S, and Skylake Y with 0.95V VccIO */
 | 
				
			||||||
static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
 | 
					static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
 | 
				
			||||||
	{ 0x00000018, 0x000000a2 },
 | 
						{ 0x00002016, 0x000000A0, 0x0 },
 | 
				
			||||||
	{ 0x00004014, 0x0000009B },
 | 
						{ 0x00005012, 0x0000009B, 0x0 },
 | 
				
			||||||
	{ 0x00006012, 0x00000088 },
 | 
						{ 0x00007011, 0x00000088, 0x0 },
 | 
				
			||||||
	{ 0x00008010, 0x00000087 },
 | 
						{ 0x00009010, 0x000000C7, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x0000009B },
 | 
						{ 0x00002016, 0x0000009B, 0x0 },
 | 
				
			||||||
	{ 0x00004014, 0x00000088 },
 | 
						{ 0x00005012, 0x00000088, 0x0 },
 | 
				
			||||||
	{ 0x00006012, 0x00000087 },
 | 
						{ 0x00007011, 0x000000C7, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x00000088 },
 | 
						{ 0x00002016, 0x000000DF, 0x0 },
 | 
				
			||||||
	{ 0x00004014, 0x00000087 },
 | 
						{ 0x00005012, 0x000000C7, 0x0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* eDP 1.4 low vswing translation parameters */
 | 
					/* Skylake U */
 | 
				
			||||||
 | 
					static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
 | 
				
			||||||
 | 
						{ 0x00002016, 0x000000A2, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00005012, 0x00000088, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x00000087, 0x0 },
 | 
				
			||||||
 | 
						{ 0x80009010, 0x000000C7, 0x1 },	/* Uses I_boost */
 | 
				
			||||||
 | 
						{ 0x00002016, 0x0000009D, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00005012, 0x000000C7, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x000000C7, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00002016, 0x00000088, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00005012, 0x000000C7, 0x0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Skylake Y with 0.85V VccIO */
 | 
				
			||||||
 | 
					static const struct ddi_buf_trans skl_y_085v_ddi_translations_dp[] = {
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000A2, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00005012, 0x00000088, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x00000087, 0x0 },
 | 
				
			||||||
 | 
						{ 0x80009010, 0x000000C7, 0x1 },	/* Uses I_boost */
 | 
				
			||||||
 | 
						{ 0x00000018, 0x0000009D, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00005012, 0x000000C7, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x000000C7, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x00000088, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00005012, 0x000000C7, 0x0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Skylake H and S, and Skylake Y with 0.95V VccIO
 | 
				
			||||||
 | 
					 * eDP 1.4 low vswing translation parameters
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
 | 
					static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
 | 
				
			||||||
	{ 0x00000018, 0x000000a8 },
 | 
						{ 0x00000018, 0x000000A8, 0x0 },
 | 
				
			||||||
	{ 0x00002016, 0x000000ab },
 | 
						{ 0x00004013, 0x000000A9, 0x0 },
 | 
				
			||||||
	{ 0x00006012, 0x000000a2 },
 | 
						{ 0x00007011, 0x000000A2, 0x0 },
 | 
				
			||||||
	{ 0x00008010, 0x00000088 },
 | 
						{ 0x00009010, 0x0000009C, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x000000ab },
 | 
						{ 0x00000018, 0x000000A9, 0x0 },
 | 
				
			||||||
	{ 0x00004014, 0x000000a2 },
 | 
						{ 0x00006013, 0x000000A2, 0x0 },
 | 
				
			||||||
	{ 0x00006012, 0x000000a6 },
 | 
						{ 0x00007011, 0x000000A6, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x000000a2 },
 | 
						{ 0x00000018, 0x000000AB, 0x0 },
 | 
				
			||||||
	{ 0x00005013, 0x0000009c },
 | 
						{ 0x00007013, 0x0000009F, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x00000088 },
 | 
						{ 0x00000018, 0x000000DF, 0x0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Skylake U
 | 
				
			||||||
 | 
					 * eDP 1.4 low vswing translation parameters
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000A8, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00004013, 0x000000A9, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x000000A2, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00009010, 0x0000009C, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000A9, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00006013, 0x000000A2, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x000000A6, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00002016, 0x000000AB, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00005013, 0x0000009F, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000DF, 0x0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Skylake Y with 0.95V VccIO
 | 
				
			||||||
 | 
					 * eDP 1.4 low vswing translation parameters
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const struct ddi_buf_trans skl_y_085v_ddi_translations_edp[] = {
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000A8, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00004013, 0x000000AB, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x000000A4, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00009010, 0x000000DF, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000AA, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00006013, 0x000000A4, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x0000009D, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000A0, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00006012, 0x000000DF, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x0000008A, 0x0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Skylake H, S and U, and Skylake Y with 0.95V VccIO */
 | 
				
			||||||
static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
 | 
					static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
 | 
				
			||||||
	{ 0x00000018, 0x000000ac },
 | 
						{ 0x00000018, 0x000000AC, 0x0 },
 | 
				
			||||||
	{ 0x00005012, 0x0000009d },
 | 
						{ 0x00005012, 0x0000009D, 0x0 },
 | 
				
			||||||
	{ 0x00007011, 0x00000088 },
 | 
						{ 0x00007011, 0x00000088, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x000000a1 },
 | 
						{ 0x00000018, 0x000000A1, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x00000098 },
 | 
						{ 0x00000018, 0x00000098, 0x0 },
 | 
				
			||||||
	{ 0x00004013, 0x00000088 },
 | 
						{ 0x00004013, 0x00000088, 0x0 },
 | 
				
			||||||
	{ 0x00006012, 0x00000087 },
 | 
						{ 0x00006012, 0x00000087, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x000000df },
 | 
						{ 0x00000018, 0x000000DF, 0x0 },
 | 
				
			||||||
	{ 0x00003015, 0x00000087 },
 | 
						{ 0x00003015, 0x00000087, 0x0 },	/* Default */
 | 
				
			||||||
	{ 0x00003015, 0x000000c7 },
 | 
						{ 0x00003015, 0x000000C7, 0x0 },
 | 
				
			||||||
	{ 0x00000018, 0x000000c7 },
 | 
						{ 0x00000018, 0x000000C7, 0x0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Skylake Y with 0.85V VccIO */
 | 
				
			||||||
 | 
					static const struct ddi_buf_trans skl_y_085v_ddi_translations_hdmi[] = {
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000A1, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00005012, 0x000000DF, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00007011, 0x00000084, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000A4, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x0000009D, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00004013, 0x00000080, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00006013, 0x000000C7, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00000018, 0x0000008A, 0x0 },
 | 
				
			||||||
 | 
						{ 0x00003015, 0x000000C7, 0x0 },	/* Default */
 | 
				
			||||||
 | 
						{ 0x80003015, 0x000000C7, 0x7 },	/* Uses I_boost */
 | 
				
			||||||
 | 
						{ 0x00000018, 0x000000C7, 0x0 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct bxt_ddi_buf_trans {
 | 
					struct bxt_ddi_buf_trans {
 | 
				
			||||||
| 
						 | 
					@ -190,7 +270,7 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
 | 
				
			||||||
	{ 154, 0x9A, 0, 64,  false },	/* 6:	600		6   */
 | 
						{ 154, 0x9A, 0, 64,  false },	/* 6:	600		6   */
 | 
				
			||||||
	{ 102, 0x9A, 0, 128, false },	/* 7:	800		0   */
 | 
						{ 102, 0x9A, 0, 128, false },	/* 7:	800		0   */
 | 
				
			||||||
	{ 154, 0x9A, 0, 85,  false },	/* 8:	800		3.5 */
 | 
						{ 154, 0x9A, 0, 85,  false },	/* 8:	800		3.5 */
 | 
				
			||||||
	{ 154, 0x9A, 1, 128, false },  /* 9:	1200		0   */
 | 
						{ 154, 0x9A, 1, 128, false },	/* 9:	1200		0   */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* BSpec has 2 recommended values - entries 0 and 8.
 | 
					/* BSpec has 2 recommended values - entries 0 and 8.
 | 
				
			||||||
| 
						 | 
					@ -210,6 +290,9 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
 | 
				
			||||||
	{ 154, 0x9A, 1, 128, true },	/* 9:	1200		0   */
 | 
						{ 154, 0x9A, 1, 128, true },	/* 9:	1200		0   */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 | 
				
			||||||
 | 
									    enum port port, int type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
 | 
					static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
 | 
				
			||||||
				 struct intel_digital_port **dig_port,
 | 
									 struct intel_digital_port **dig_port,
 | 
				
			||||||
				 enum port *port)
 | 
									 enum port *port)
 | 
				
			||||||
| 
						 | 
					@ -249,6 +332,102 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
 | 
				
			||||||
	return intel_dig_port->hdmi.hdmi_reg;
 | 
						return intel_dig_port->hdmi.hdmi_reg;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
 | 
				
			||||||
 | 
												int *n_entries)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_i915_private *dev_priv = dev->dev_private;
 | 
				
			||||||
 | 
						const struct ddi_buf_trans *ddi_translations;
 | 
				
			||||||
 | 
						static int is_095v = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (is_095v == -1) {
 | 
				
			||||||
 | 
							u32 spr1 = I915_READ(UAIMI_SPR1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							is_095v = spr1 & SKL_VCCIO_MASK;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (IS_SKL_ULX(dev) && !is_095v) {
 | 
				
			||||||
 | 
							ddi_translations = skl_y_085v_ddi_translations_dp;
 | 
				
			||||||
 | 
							*n_entries = ARRAY_SIZE(skl_y_085v_ddi_translations_dp);
 | 
				
			||||||
 | 
						} else if (IS_SKL_ULT(dev)) {
 | 
				
			||||||
 | 
							ddi_translations = skl_u_ddi_translations_dp;
 | 
				
			||||||
 | 
							*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ddi_translations = skl_ddi_translations_dp;
 | 
				
			||||||
 | 
							*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ddi_translations;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev,
 | 
				
			||||||
 | 
												 int *n_entries)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_i915_private *dev_priv = dev->dev_private;
 | 
				
			||||||
 | 
						const struct ddi_buf_trans *ddi_translations;
 | 
				
			||||||
 | 
						static int is_095v = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (is_095v == -1) {
 | 
				
			||||||
 | 
							u32 spr1 = I915_READ(UAIMI_SPR1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							is_095v = spr1 & SKL_VCCIO_MASK;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (IS_SKL_ULX(dev) && !is_095v) {
 | 
				
			||||||
 | 
							if (dev_priv->edp_low_vswing) {
 | 
				
			||||||
 | 
								ddi_translations = skl_y_085v_ddi_translations_edp;
 | 
				
			||||||
 | 
								*n_entries =
 | 
				
			||||||
 | 
									ARRAY_SIZE(skl_y_085v_ddi_translations_edp);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ddi_translations = skl_y_085v_ddi_translations_dp;
 | 
				
			||||||
 | 
								*n_entries =
 | 
				
			||||||
 | 
									ARRAY_SIZE(skl_y_085v_ddi_translations_dp);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (IS_SKL_ULT(dev)) {
 | 
				
			||||||
 | 
							if (dev_priv->edp_low_vswing) {
 | 
				
			||||||
 | 
								ddi_translations = skl_u_ddi_translations_edp;
 | 
				
			||||||
 | 
								*n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ddi_translations = skl_u_ddi_translations_dp;
 | 
				
			||||||
 | 
								*n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (dev_priv->edp_low_vswing) {
 | 
				
			||||||
 | 
								ddi_translations = skl_ddi_translations_edp;
 | 
				
			||||||
 | 
								*n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								ddi_translations = skl_ddi_translations_dp;
 | 
				
			||||||
 | 
								*n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ddi_translations;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct ddi_buf_trans *
 | 
				
			||||||
 | 
					skl_get_buf_trans_hdmi(struct drm_device *dev,
 | 
				
			||||||
 | 
							       int *n_entries)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_i915_private *dev_priv = dev->dev_private;
 | 
				
			||||||
 | 
						const struct ddi_buf_trans *ddi_translations;
 | 
				
			||||||
 | 
						static int is_095v = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (is_095v == -1) {
 | 
				
			||||||
 | 
							u32 spr1 = I915_READ(UAIMI_SPR1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							is_095v = spr1 & SKL_VCCIO_MASK;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (IS_SKL_ULX(dev) && !is_095v) {
 | 
				
			||||||
 | 
							ddi_translations = skl_y_085v_ddi_translations_hdmi;
 | 
				
			||||||
 | 
							*n_entries = ARRAY_SIZE(skl_y_085v_ddi_translations_hdmi);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ddi_translations = skl_ddi_translations_hdmi;
 | 
				
			||||||
 | 
							*n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ddi_translations;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Starting with Haswell, DDI port buffers must be programmed with correct
 | 
					 * Starting with Haswell, DDI port buffers must be programmed with correct
 | 
				
			||||||
 * values in advance. The buffer values are different for FDI and DP modes,
 | 
					 * values in advance. The buffer values are different for FDI and DP modes,
 | 
				
			||||||
| 
						 | 
					@ -279,20 +458,13 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
 | 
				
			||||||
					INTEL_OUTPUT_HDMI);
 | 
										INTEL_OUTPUT_HDMI);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	} else if (IS_SKYLAKE(dev)) {
 | 
						} else if (IS_SKYLAKE(dev)) {
 | 
				
			||||||
		ddi_translations_fdi = NULL;
 | 
							ddi_translations_dp =
 | 
				
			||||||
		ddi_translations_dp = skl_ddi_translations_dp;
 | 
									skl_get_buf_trans_dp(dev, &n_dp_entries);
 | 
				
			||||||
		n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
 | 
							ddi_translations_edp =
 | 
				
			||||||
		if (dev_priv->edp_low_vswing) {
 | 
									skl_get_buf_trans_edp(dev, &n_edp_entries);
 | 
				
			||||||
			ddi_translations_edp = skl_ddi_translations_edp;
 | 
							ddi_translations_hdmi =
 | 
				
			||||||
			n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp);
 | 
									skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
 | 
				
			||||||
		} else {
 | 
							hdmi_default_entry = 8;
 | 
				
			||||||
			ddi_translations_edp = skl_ddi_translations_dp;
 | 
					 | 
				
			||||||
			n_edp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ddi_translations_hdmi = skl_ddi_translations_hdmi;
 | 
					 | 
				
			||||||
		n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
 | 
					 | 
				
			||||||
		hdmi_default_entry = 7;
 | 
					 | 
				
			||||||
	} else if (IS_BROADWELL(dev)) {
 | 
						} else if (IS_BROADWELL(dev)) {
 | 
				
			||||||
		ddi_translations_fdi = bdw_ddi_translations_fdi;
 | 
							ddi_translations_fdi = bdw_ddi_translations_fdi;
 | 
				
			||||||
		ddi_translations_dp = bdw_ddi_translations_dp;
 | 
							ddi_translations_dp = bdw_ddi_translations_dp;
 | 
				
			||||||
| 
						 | 
					@ -1883,8 +2055,48 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
 | 
				
			||||||
			   TRANS_CLK_SEL_DISABLED);
 | 
								   TRANS_CLK_SEL_DISABLED);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 | 
					static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
 | 
				
			||||||
			     enum port port, int type)
 | 
								       enum port port, int type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct drm_i915_private *dev_priv = dev->dev_private;
 | 
				
			||||||
 | 
						const struct ddi_buf_trans *ddi_translations;
 | 
				
			||||||
 | 
						uint8_t iboost;
 | 
				
			||||||
 | 
						int n_entries;
 | 
				
			||||||
 | 
						u32 reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (type == INTEL_OUTPUT_DISPLAYPORT) {
 | 
				
			||||||
 | 
							ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
 | 
				
			||||||
 | 
							iboost = ddi_translations[port].i_boost;
 | 
				
			||||||
 | 
						} else if (type == INTEL_OUTPUT_EDP) {
 | 
				
			||||||
 | 
							ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
 | 
				
			||||||
 | 
							iboost = ddi_translations[port].i_boost;
 | 
				
			||||||
 | 
						} else if (type == INTEL_OUTPUT_HDMI) {
 | 
				
			||||||
 | 
							ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
 | 
				
			||||||
 | 
							iboost = ddi_translations[port].i_boost;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make sure that the requested I_boost is valid */
 | 
				
			||||||
 | 
						if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
 | 
				
			||||||
 | 
							DRM_ERROR("Invalid I_boost value %u\n", iboost);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
 | 
				
			||||||
 | 
						reg &= ~BALANCE_LEG_MASK(port);
 | 
				
			||||||
 | 
						reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (iboost)
 | 
				
			||||||
 | 
							reg |= iboost << BALANCE_LEG_SHIFT(port);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 | 
				
			||||||
 | 
									    enum port port, int type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct drm_i915_private *dev_priv = dev->dev_private;
 | 
						struct drm_i915_private *dev_priv = dev->dev_private;
 | 
				
			||||||
	const struct bxt_ddi_buf_trans *ddi_translations;
 | 
						const struct bxt_ddi_buf_trans *ddi_translations;
 | 
				
			||||||
| 
						 | 
					@ -1944,6 +2156,73 @@ void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 | 
				
			||||||
	I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
 | 
						I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t translate_signal_level(int signal_levels)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (signal_levels) {
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
 | 
				
			||||||
 | 
								      signal_levels);
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
				
			||||||
 | 
							level = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
				
			||||||
 | 
							level = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
 | 
				
			||||||
 | 
							level = 2;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
 | 
				
			||||||
 | 
							level = 3;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
				
			||||||
 | 
							level = 4;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
				
			||||||
 | 
							level = 5;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
 | 
				
			||||||
 | 
							level = 6;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
				
			||||||
 | 
							level = 7;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
				
			||||||
 | 
							level = 8;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
				
			||||||
 | 
							level = 9;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return level;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 | 
				
			||||||
 | 
						struct drm_device *dev = dport->base.base.dev;
 | 
				
			||||||
 | 
						struct intel_encoder *encoder = &dport->base;
 | 
				
			||||||
 | 
						uint8_t train_set = intel_dp->train_set[0];
 | 
				
			||||||
 | 
						int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
 | 
				
			||||||
 | 
										 DP_TRAIN_PRE_EMPHASIS_MASK);
 | 
				
			||||||
 | 
						enum port port = dport->port;
 | 
				
			||||||
 | 
						uint32_t level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						level = translate_signal_level(signal_levels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (IS_SKYLAKE(dev))
 | 
				
			||||||
 | 
							skl_ddi_set_iboost(dev, level, port, encoder->type);
 | 
				
			||||||
 | 
						else if (IS_BROXTON(dev))
 | 
				
			||||||
 | 
							bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return DDI_BUF_TRANS_SELECT(level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 | 
					static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct drm_encoder *encoder = &intel_encoder->base;
 | 
						struct drm_encoder *encoder = &intel_encoder->base;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3424,92 +3424,6 @@ gen7_edp_signal_levels(uint8_t train_set)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Gen7.5's (HSW) DP voltage swing and pre-emphasis control */
 | 
					 | 
				
			||||||
static uint32_t
 | 
					 | 
				
			||||||
hsw_signal_levels(uint8_t train_set)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
 | 
					 | 
				
			||||||
					 DP_TRAIN_PRE_EMPHASIS_MASK);
 | 
					 | 
				
			||||||
	switch (signal_levels) {
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(0);
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(1);
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(2);
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(3);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(4);
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(5);
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(6);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(7);
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(8);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(9);
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
 | 
					 | 
				
			||||||
			      "0x%x\n", signal_levels);
 | 
					 | 
				
			||||||
		return DDI_BUF_TRANS_SELECT(0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void bxt_signal_levels(struct intel_dp *intel_dp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 | 
					 | 
				
			||||||
	enum port port = dport->port;
 | 
					 | 
				
			||||||
	struct drm_device *dev = dport->base.base.dev;
 | 
					 | 
				
			||||||
	struct intel_encoder *encoder = &dport->base;
 | 
					 | 
				
			||||||
	uint8_t train_set = intel_dp->train_set[0];
 | 
					 | 
				
			||||||
	uint32_t level = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
 | 
					 | 
				
			||||||
					 DP_TRAIN_PRE_EMPHASIS_MASK);
 | 
					 | 
				
			||||||
	switch (signal_levels) {
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emph level\n");
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
					 | 
				
			||||||
		level = 0;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
					 | 
				
			||||||
		level = 1;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
 | 
					 | 
				
			||||||
		level = 2;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
 | 
					 | 
				
			||||||
		level = 3;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
					 | 
				
			||||||
		level = 4;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
					 | 
				
			||||||
		level = 5;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
 | 
					 | 
				
			||||||
		level = 6;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
					 | 
				
			||||||
		level = 7;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
 | 
					 | 
				
			||||||
		level = 8;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
 | 
					 | 
				
			||||||
		level = 9;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Properly updates "DP" with the correct signal levels. */
 | 
					/* Properly updates "DP" with the correct signal levels. */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
 | 
					intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
 | 
				
			||||||
| 
						 | 
					@ -3517,22 +3431,20 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
 | 
				
			||||||
	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 | 
						struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 | 
				
			||||||
	enum port port = intel_dig_port->port;
 | 
						enum port port = intel_dig_port->port;
 | 
				
			||||||
	struct drm_device *dev = intel_dig_port->base.base.dev;
 | 
						struct drm_device *dev = intel_dig_port->base.base.dev;
 | 
				
			||||||
	uint32_t signal_levels, mask;
 | 
						uint32_t signal_levels, mask = 0;
 | 
				
			||||||
	uint8_t train_set = intel_dp->train_set[0];
 | 
						uint8_t train_set = intel_dp->train_set[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (IS_BROXTON(dev)) {
 | 
						if (HAS_DDI(dev)) {
 | 
				
			||||||
		signal_levels = 0;
 | 
							signal_levels = ddi_signal_levels(intel_dp);
 | 
				
			||||||
		bxt_signal_levels(intel_dp);
 | 
					
 | 
				
			||||||
		mask = 0;
 | 
							if (IS_BROXTON(dev))
 | 
				
			||||||
	} else if (HAS_DDI(dev)) {
 | 
								signal_levels = 0;
 | 
				
			||||||
		signal_levels = hsw_signal_levels(train_set);
 | 
							else
 | 
				
			||||||
		mask = DDI_BUF_EMP_MASK;
 | 
								mask = DDI_BUF_EMP_MASK;
 | 
				
			||||||
	} else if (IS_CHERRYVIEW(dev)) {
 | 
						} else if (IS_CHERRYVIEW(dev)) {
 | 
				
			||||||
		signal_levels = chv_signal_levels(intel_dp);
 | 
							signal_levels = chv_signal_levels(intel_dp);
 | 
				
			||||||
		mask = 0;
 | 
					 | 
				
			||||||
	} else if (IS_VALLEYVIEW(dev)) {
 | 
						} else if (IS_VALLEYVIEW(dev)) {
 | 
				
			||||||
		signal_levels = vlv_signal_levels(intel_dp);
 | 
							signal_levels = vlv_signal_levels(intel_dp);
 | 
				
			||||||
		mask = 0;
 | 
					 | 
				
			||||||
	} else if (IS_GEN7(dev) && port == PORT_A) {
 | 
						} else if (IS_GEN7(dev) && port == PORT_A) {
 | 
				
			||||||
		signal_levels = gen7_edp_signal_levels(train_set);
 | 
							signal_levels = gen7_edp_signal_levels(train_set);
 | 
				
			||||||
		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
 | 
							mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -968,8 +968,7 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
 | 
				
			||||||
void intel_ddi_clock_get(struct intel_encoder *encoder,
 | 
					void intel_ddi_clock_get(struct intel_encoder *encoder,
 | 
				
			||||||
			 struct intel_crtc_state *pipe_config);
 | 
								 struct intel_crtc_state *pipe_config);
 | 
				
			||||||
void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
 | 
					void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
 | 
				
			||||||
void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 | 
					uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
 | 
				
			||||||
				enum port port, int type);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* intel_frontbuffer.c */
 | 
					/* intel_frontbuffer.c */
 | 
				
			||||||
void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
 | 
					void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue