All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915/skl: Buffer translation improvements
@ 2015-06-18  9:50 David Weinehall
  2015-06-18 10:10 ` Chris Wilson
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: David Weinehall @ 2015-06-18  9:50 UTC (permalink / raw)
  To: intel-gfx

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.

Issue: VIZ-5677
Signed-off-by: David Weinehall <david.weinehall@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |   8 +
 drivers/gpu/drm/i915/i915_reg.h  |  12 ++
 drivers/gpu/drm/i915/intel_ddi.c | 433 +++++++++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_dp.c  |  46 ++++-
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 5 files changed, 379 insertions(+), 122 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 491ef0cfcb0b..09a57a584f5f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2415,6 +2415,14 @@ struct drm_i915_cmd_table {
 /* ULX machines are also considered ULT. */
 #define IS_HSW_ULX(dev)		(INTEL_DEVID(dev) == 0x0A0E || \
 				 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 SKL_REVID_A0		(0x0)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0b979ad16d41..fb63ead2b8eb 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1382,6 +1382,18 @@ enum skl_disp_power_wells {
 							_PORT_TX_DW14_LN0_C) + \
 					 _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
  */
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 31b29e8781ac..3abcb43bec8b 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -31,6 +31,7 @@
 struct ddi_buf_trans {
 	u32 trans1;	/* balance leg enable, de-emph level */
 	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
@@ -38,134 +39,213 @@ struct ddi_buf_trans {
  * automatically adapt to HDMI connections as well
  */
 static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
-	{ 0x00FFFFFF, 0x0006000E },
-	{ 0x00D75FFF, 0x0005000A },
-	{ 0x00C30FFF, 0x00040006 },
-	{ 0x80AAAFFF, 0x000B0000 },
-	{ 0x00FFFFFF, 0x0005000A },
-	{ 0x00D75FFF, 0x000C0004 },
-	{ 0x80C30FFF, 0x000B0000 },
-	{ 0x00FFFFFF, 0x00040006 },
-	{ 0x80D75FFF, 0x000B0000 },
+	{ 0x00FFFFFF, 0x0006000E, 0x0 },
+	{ 0x00D75FFF, 0x0005000A, 0x0 },
+	{ 0x00C30FFF, 0x00040006, 0x0 },
+	{ 0x80AAAFFF, 0x000B0000, 0x0 },
+	{ 0x00FFFFFF, 0x0005000A, 0x0 },
+	{ 0x00D75FFF, 0x000C0004, 0x0 },
+	{ 0x80C30FFF, 0x000B0000, 0x0 },
+	{ 0x00FFFFFF, 0x00040006, 0x0 },
+	{ 0x80D75FFF, 0x000B0000, 0x0 },
 };
 
 static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
-	{ 0x00FFFFFF, 0x0007000E },
-	{ 0x00D75FFF, 0x000F000A },
-	{ 0x00C30FFF, 0x00060006 },
-	{ 0x00AAAFFF, 0x001E0000 },
-	{ 0x00FFFFFF, 0x000F000A },
-	{ 0x00D75FFF, 0x00160004 },
-	{ 0x00C30FFF, 0x001E0000 },
-	{ 0x00FFFFFF, 0x00060006 },
-	{ 0x00D75FFF, 0x001E0000 },
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },
+	{ 0x00D75FFF, 0x000F000A, 0x0 },
+	{ 0x00C30FFF, 0x00060006, 0x0 },
+	{ 0x00AAAFFF, 0x001E0000, 0x0 },
+	{ 0x00FFFFFF, 0x000F000A, 0x0 },
+	{ 0x00D75FFF, 0x00160004, 0x0 },
+	{ 0x00C30FFF, 0x001E0000, 0x0 },
+	{ 0x00FFFFFF, 0x00060006, 0x0 },
+	{ 0x00D75FFF, 0x001E0000, 0x0 },
 };
 
 static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
 					/* Idx	NT mV d	T mV d	db	*/
-	{ 0x00FFFFFF, 0x0006000E },	/* 0:	400	400	0	*/
-	{ 0x00E79FFF, 0x000E000C },	/* 1:	400	500	2	*/
-	{ 0x00D75FFF, 0x0005000A },	/* 2:	400	600	3.5	*/
-	{ 0x00FFFFFF, 0x0005000A },	/* 3:	600	600	0	*/
-	{ 0x00E79FFF, 0x001D0007 },	/* 4:	600	750	2	*/
-	{ 0x00D75FFF, 0x000C0004 },	/* 5:	600	900	3.5	*/
-	{ 0x00FFFFFF, 0x00040006 },	/* 6:	800	800	0	*/
-	{ 0x80E79FFF, 0x00030002 },	/* 7:	800	1000	2	*/
-	{ 0x00FFFFFF, 0x00140005 },	/* 8:	850	850	0	*/
-	{ 0x00FFFFFF, 0x000C0004 },	/* 9:	900	900	0	*/
-	{ 0x00FFFFFF, 0x001C0003 },	/* 10:	950	950	0	*/
-	{ 0x80FFFFFF, 0x00030002 },	/* 11:	1000	1000	0	*/
+	{ 0x00FFFFFF, 0x0006000E, 0x0 },/* 0:	400	400	0	*/
+	{ 0x00E79FFF, 0x000E000C, 0x0 },/* 1:	400	500	2	*/
+	{ 0x00D75FFF, 0x0005000A, 0x0 },/* 2:	400	600	3.5	*/
+	{ 0x00FFFFFF, 0x0005000A, 0x0 },/* 3:	600	600	0	*/
+	{ 0x00E79FFF, 0x001D0007, 0x0 },/* 4:	600	750	2	*/
+	{ 0x00D75FFF, 0x000C0004, 0x0 },/* 5:	600	900	3.5	*/
+	{ 0x00FFFFFF, 0x00040006, 0x0 },/* 6:	800	800	0	*/
+	{ 0x80E79FFF, 0x00030002, 0x0 },/* 7:	800	1000	2	*/
+	{ 0x00FFFFFF, 0x00140005, 0x0 },/* 8:	850	850	0	*/
+	{ 0x00FFFFFF, 0x000C0004, 0x0 },/* 9:	900	900	0	*/
+	{ 0x00FFFFFF, 0x001C0003, 0x0 },/* 10:	950	950	0	*/
+	{ 0x80FFFFFF, 0x00030002, 0x0 },/* 11:	1000	1000	0	*/
 };
 
 static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
-	{ 0x00FFFFFF, 0x00000012 },
-	{ 0x00EBAFFF, 0x00020011 },
-	{ 0x00C71FFF, 0x0006000F },
-	{ 0x00AAAFFF, 0x000E000A },
-	{ 0x00FFFFFF, 0x00020011 },
-	{ 0x00DB6FFF, 0x0005000F },
-	{ 0x00BEEFFF, 0x000A000C },
-	{ 0x00FFFFFF, 0x0005000F },
-	{ 0x00DB6FFF, 0x000A000C },
+	{ 0x00FFFFFF, 0x00000012, 0x0 },
+	{ 0x00EBAFFF, 0x00020011, 0x0 },
+	{ 0x00C71FFF, 0x0006000F, 0x0 },
+	{ 0x00AAAFFF, 0x000E000A, 0x0 },
+	{ 0x00FFFFFF, 0x00020011, 0x0 },
+	{ 0x00DB6FFF, 0x0005000F, 0x0 },
+	{ 0x00BEEFFF, 0x000A000C, 0x0 },
+	{ 0x00FFFFFF, 0x0005000F, 0x0 },
+	{ 0x00DB6FFF, 0x000A000C, 0x0 },
 };
 
 static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
-	{ 0x00FFFFFF, 0x0007000E },
-	{ 0x00D75FFF, 0x000E000A },
-	{ 0x00BEFFFF, 0x00140006 },
-	{ 0x80B2CFFF, 0x001B0002 },
-	{ 0x00FFFFFF, 0x000E000A },
-	{ 0x00DB6FFF, 0x00160005 },
-	{ 0x80C71FFF, 0x001A0002 },
-	{ 0x00F7DFFF, 0x00180004 },
-	{ 0x80D75FFF, 0x001B0002 },
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },
+	{ 0x00D75FFF, 0x000E000A, 0x0 },
+	{ 0x00BEFFFF, 0x00140006, 0x0 },
+	{ 0x80B2CFFF, 0x001B0002, 0x0 },
+	{ 0x00FFFFFF, 0x000E000A, 0x0 },
+	{ 0x00DB6FFF, 0x00160005, 0x0 },
+	{ 0x80C71FFF, 0x001A0002, 0x0 },
+	{ 0x00F7DFFF, 0x00180004, 0x0 },
+	{ 0x80D75FFF, 0x001B0002, 0x0 },
 };
 
 static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
-	{ 0x00FFFFFF, 0x0001000E },
-	{ 0x00D75FFF, 0x0004000A },
-	{ 0x00C30FFF, 0x00070006 },
-	{ 0x00AAAFFF, 0x000C0000 },
-	{ 0x00FFFFFF, 0x0004000A },
-	{ 0x00D75FFF, 0x00090004 },
-	{ 0x00C30FFF, 0x000C0000 },
-	{ 0x00FFFFFF, 0x00070006 },
-	{ 0x00D75FFF, 0x000C0000 },
+	{ 0x00FFFFFF, 0x0001000E, 0x0 },
+	{ 0x00D75FFF, 0x0004000A, 0x0 },
+	{ 0x00C30FFF, 0x00070006, 0x0 },
+	{ 0x00AAAFFF, 0x000C0000, 0x0 },
+	{ 0x00FFFFFF, 0x0004000A, 0x0 },
+	{ 0x00D75FFF, 0x00090004, 0x0 },
+	{ 0x00C30FFF, 0x000C0000, 0x0 },
+	{ 0x00FFFFFF, 0x00070006, 0x0 },
+	{ 0x00D75FFF, 0x000C0000, 0x0 },
 };
 
 static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
 					/* Idx	NT mV d	T mV df	db	*/
-	{ 0x00FFFFFF, 0x0007000E },	/* 0:	400	400	0	*/
-	{ 0x00D75FFF, 0x000E000A },	/* 1:	400	600	3.5	*/
-	{ 0x00BEFFFF, 0x00140006 },	/* 2:	400	800	6	*/
-	{ 0x00FFFFFF, 0x0009000D },	/* 3:	450	450	0	*/
-	{ 0x00FFFFFF, 0x000E000A },	/* 4:	600	600	0	*/
-	{ 0x00D7FFFF, 0x00140006 },	/* 5:	600	800	2.5	*/
-	{ 0x80CB2FFF, 0x001B0002 },	/* 6:	600	1000	4.5	*/
-	{ 0x00FFFFFF, 0x00140006 },	/* 7:	800	800	0	*/
-	{ 0x80E79FFF, 0x001B0002 },	/* 8:	800	1000	2	*/
-	{ 0x80FFFFFF, 0x001B0002 },	/* 9:	1000	1000	0	*/
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },/* 0:	400	400	0	*/
+	{ 0x00D75FFF, 0x000E000A, 0x0 },/* 1:	400	600	3.5	*/
+	{ 0x00BEFFFF, 0x00140006, 0x0 },/* 2:	400	800	6	*/
+	{ 0x00FFFFFF, 0x0009000D, 0x0 },/* 3:	450	450	0	*/
+	{ 0x00FFFFFF, 0x000E000A, 0x0 },/* 4:	600	600	0	*/
+	{ 0x00D7FFFF, 0x00140006, 0x0 },/* 5:	600	800	2.5	*/
+	{ 0x80CB2FFF, 0x001B0002, 0x0 },/* 6:	600	1000	4.5	*/
+	{ 0x00FFFFFF, 0x00140006, 0x0 },/* 7:	800	800	0	*/
+	{ 0x80E79FFF, 0x001B0002, 0x0 },/* 8:	800	1000	2	*/
+	{ 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[] = {
-	{ 0x00000018, 0x000000a2 },
-	{ 0x00004014, 0x0000009B },
-	{ 0x00006012, 0x00000088 },
-	{ 0x00008010, 0x00000087 },
-	{ 0x00000018, 0x0000009B },
-	{ 0x00004014, 0x00000088 },
-	{ 0x00006012, 0x00000087 },
-	{ 0x00000018, 0x00000088 },
-	{ 0x00004014, 0x00000087 },
+	{ 0x00002016, 0x000000A0, 0x0 },
+	{ 0x00005012, 0x0000009B, 0x0 },
+	{ 0x00007011, 0x00000088, 0x0 },
+	{ 0x00009010, 0x000000C7, 0x0 },
+	{ 0x00002016, 0x0000009B, 0x0 },
+	{ 0x00005012, 0x00000088, 0x0 },
+	{ 0x00007011, 0x000000C7, 0x0 },
+	{ 0x00002016, 0x000000DF, 0x0 },
+	{ 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[] = {
-	{ 0x00000018, 0x000000a8 },
-	{ 0x00002016, 0x000000ab },
-	{ 0x00006012, 0x000000a2 },
-	{ 0x00008010, 0x00000088 },
-	{ 0x00000018, 0x000000ab },
-	{ 0x00004014, 0x000000a2 },
-	{ 0x00006012, 0x000000a6 },
-	{ 0x00000018, 0x000000a2 },
-	{ 0x00005013, 0x0000009c },
-	{ 0x00000018, 0x00000088 },
+	{ 0x00000018, 0x000000A8, 0x0 },
+	{ 0x00004013, 0x000000A9, 0x0 },
+	{ 0x00007011, 0x000000A2, 0x0 },
+	{ 0x00009010, 0x0000009C, 0x0 },
+	{ 0x00000018, 0x000000A9, 0x0 },
+	{ 0x00006013, 0x000000A2, 0x0 },
+	{ 0x00007011, 0x000000A6, 0x0 },
+	{ 0x00000018, 0x000000AB, 0x0 },
+	{ 0x00007013, 0x0000009F, 0x0 },
+	{ 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[] = {
-	{ 0x00000018, 0x000000ac },
-	{ 0x00005012, 0x0000009d },
-	{ 0x00007011, 0x00000088 },
-	{ 0x00000018, 0x000000a1 },
-	{ 0x00000018, 0x00000098 },
-	{ 0x00004013, 0x00000088 },
-	{ 0x00006012, 0x00000087 },
-	{ 0x00000018, 0x000000df },
-	{ 0x00003015, 0x00000087 },
-	{ 0x00003015, 0x000000c7 },
-	{ 0x00000018, 0x000000c7 },
+	{ 0x00000018, 0x000000AC, 0x0 },
+	{ 0x00005012, 0x0000009D, 0x0 },
+	{ 0x00007011, 0x00000088, 0x0 },
+	{ 0x00000018, 0x000000A1, 0x0 },
+	{ 0x00000018, 0x00000098, 0x0 },
+	{ 0x00004013, 0x00000088, 0x0 },
+	{ 0x00006012, 0x00000087, 0x0 },
+	{ 0x00000018, 0x000000DF, 0x0 },
+	{ 0x00003015, 0x00000087, 0x0 },	/* Default */
+	{ 0x00003015, 0x000000C7, 0x0 },
+	{ 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 {
@@ -190,7 +270,7 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
 	{ 154, 0x9A, 0, 64,  false },	/* 6:	600		6   */
 	{ 102, 0x9A, 0, 128, false },	/* 7:	800		0   */
 	{ 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.
@@ -249,6 +329,99 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
 	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
  * values in advance. The buffer values are different for FDI and DP modes,
@@ -279,20 +452,13 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
 					INTEL_OUTPUT_HDMI);
 		return;
 	} else if (IS_SKYLAKE(dev)) {
-		ddi_translations_fdi = NULL;
-		ddi_translations_dp = skl_ddi_translations_dp;
-		n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
-		if (dev_priv->edp_low_vswing) {
-			ddi_translations_edp = skl_ddi_translations_edp;
-			n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp);
-		} else {
-			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;
+		ddi_translations_dp =
+				skl_get_buf_trans_dp(dev, &n_dp_entries);
+		ddi_translations_edp =
+				skl_get_buf_trans_edp(dev, &n_edp_entries);
+		ddi_translations_hdmi =
+				skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
+		hdmi_default_entry = 8;
 	} else if (IS_BROADWELL(dev)) {
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
@@ -1806,6 +1972,47 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
 			   TRANS_CLK_SEL_DISABLED);
 }
 
+void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
+			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);
+}
+
 void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 			     enum port port, int type)
 {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f52eef138247..807c77d8dabc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3454,17 +3454,10 @@ hsw_signal_levels(uint8_t train_set)
 	}
 }
 
-static void bxt_signal_levels(struct intel_dp *intel_dp)
+static uint32_t get_signal_level(int signal_levels)
 {
-	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;
+	uint32_t level;
 
-	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");
@@ -3500,6 +3493,38 @@ static void bxt_signal_levels(struct intel_dp *intel_dp)
 		break;
 	}
 
+	return level;
+}
+
+static void skl_set_iboost(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;
+
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	level = get_signal_level(signal_levels);
+
+	skl_ddi_set_iboost(dev, level, port, encoder->type);
+}
+
+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);
+	level = get_signal_level(signal_levels);
+
 	bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
 }
 
@@ -3520,6 +3545,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
 	} else if (HAS_DDI(dev)) {
 		signal_levels = hsw_signal_levels(train_set);
 		mask = DDI_BUF_EMP_MASK;
+
+		if (IS_SKYLAKE(dev))
+			skl_set_iboost(intel_dp);
 	} else if (IS_CHERRYVIEW(dev)) {
 		signal_levels = chv_signal_levels(intel_dp);
 		mask = 0;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bcafefcf048b..b2ebecef6dec 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -950,6 +950,8 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
 void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
+void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
+			enum port port, int type);
 void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 				enum port port, int type);
 
-- 
2.1.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-18  9:50 [PATCH] drm/i915/skl: Buffer translation improvements David Weinehall
@ 2015-06-18 10:10 ` Chris Wilson
  2015-06-18 10:47   ` David Weinehall
  2015-06-25  8:09   ` David Weinehall
  2015-06-18 15:05 ` Daniel Vetter
  2015-06-25  8:11 ` [PATCH v2] " David Weinehall
  2 siblings, 2 replies; 16+ messages in thread
From: Chris Wilson @ 2015-06-18 10:10 UTC (permalink / raw)
  To: intel-gfx

On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> +static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,

struct drm_i915_private not struct drm_device!

> +							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);
> +	}

These are static routing, but called fairly often. (Often enough that
you care to only read the reigster once.) Any reason not to preserve
these routing tables in dev_priv or, slightly more preferrable, intel_dp?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-18 10:10 ` Chris Wilson
@ 2015-06-18 10:47   ` David Weinehall
  2015-06-18 10:59     ` Chris Wilson
  2015-06-25  8:09   ` David Weinehall
  1 sibling, 1 reply; 16+ messages in thread
From: David Weinehall @ 2015-06-18 10:47 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On Thu, Jun 18, 2015 at 11:10:13AM +0100, Chris Wilson wrote:
> On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> > +static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
> 
> struct drm_i915_private not struct drm_device!

The device uses both dev and dev_priv; only passing in
drm_i915_private wouldn't provide access to dev,
or am I missing something?

> > +							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);
> > +	}
> 
> These are static routing, but called fairly often. (Often enough that
> you care to only read the reigster once.) Any reason not to preserve
> these routing tables in dev_priv or, slightly more preferrable, intel_dp?
> -Chris

No particularly good reason, so yes, it's a good proposal.
The reason I cached the register read was mostly because the less reads
from hardware the better (I was thinking of whether having the value
read more than once was too much already, but I figured that having
a global variable to hold a Skylake-specific value would be ugly).

I'll fix it on Monday (tomorrow is a public holiday here, so I'll
be traveling this weekend).


Kind regards, David
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-18 10:47   ` David Weinehall
@ 2015-06-18 10:59     ` Chris Wilson
  2015-06-23 10:28       ` David Weinehall
  0 siblings, 1 reply; 16+ messages in thread
From: Chris Wilson @ 2015-06-18 10:59 UTC (permalink / raw)
  To: intel-gfx

On Thu, Jun 18, 2015 at 01:47:30PM +0300, David Weinehall wrote:
> On Thu, Jun 18, 2015 at 11:10:13AM +0100, Chris Wilson wrote:
> > On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> > > +static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
> > 
> > struct drm_i915_private not struct drm_device!
> 
> The device uses both dev and dev_priv; only passing in
> drm_i915_private wouldn't provide access to dev,
> or am I missing something?

Hmm, Oh, you didn't set bits in intel_info for ult/ulx. Instead you have
large if chains hidden in macros.

So another task is to translate IS_*_UL? over to using a field in
intel_info to reduce the code size (at the expense of more intel_info
data).

#define IS_SKL_ULT(P) (IS_SKL(P) && INTEL_INFO(P)->is_ult)
#define IS_SKL_ULX(P) (IS_SKL(P) && INTEL_INFO(P)->is_ulx)
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-18  9:50 [PATCH] drm/i915/skl: Buffer translation improvements David Weinehall
  2015-06-18 10:10 ` Chris Wilson
@ 2015-06-18 15:05 ` Daniel Vetter
  2015-06-23 10:47   ` David Weinehall
  2015-06-23 11:12   ` David Weinehall
  2015-06-25  8:11 ` [PATCH v2] " David Weinehall
  2 siblings, 2 replies; 16+ messages in thread
From: Daniel Vetter @ 2015-06-18 15:05 UTC (permalink / raw)
  To: intel-gfx

On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> @@ -3520,6 +3545,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
>  	} else if (HAS_DDI(dev)) {
>  		signal_levels = hsw_signal_levels(train_set);
>  		mask = DDI_BUF_EMP_MASK;
> +
> +		if (IS_SKYLAKE(dev))
> +			skl_set_iboost(intel_dp);

Imo this should be put into hsw_signal_levels and then hsw_signal_levels
be moved into intel_ddi.c - that way everything related to low-level ddi
DP signal level code in intel_ddi.c.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-18 10:59     ` Chris Wilson
@ 2015-06-23 10:28       ` David Weinehall
  0 siblings, 0 replies; 16+ messages in thread
From: David Weinehall @ 2015-06-23 10:28 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On Thu, Jun 18, 2015 at 11:59:34AM +0100, Chris Wilson wrote:
> On Thu, Jun 18, 2015 at 01:47:30PM +0300, David Weinehall wrote:
> > On Thu, Jun 18, 2015 at 11:10:13AM +0100, Chris Wilson wrote:
> > > On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> > > > +static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
> > > 
> > > struct drm_i915_private not struct drm_device!
> > 
> > The device uses both dev and dev_priv; only passing in
> > drm_i915_private wouldn't provide access to dev,
> > or am I missing something?
> 
> Hmm, Oh, you didn't set bits in intel_info for ult/ulx. Instead you have
> large if chains hidden in macros.
> 
> So another task is to translate IS_*_UL? over to using a field in
> intel_info to reduce the code size (at the expense of more intel_info
> data).
> 
> #define IS_SKL_ULT(P) (IS_SKL(P) && INTEL_INFO(P)->is_ult)
> #define IS_SKL_ULX(P) (IS_SKL(P) && INTEL_INFO(P)->is_ulx)

I just followed the pattern of the existing IS_xxx_yyy macros.
Cleanup sounds sensible; this patch merely aims to add a missing
feature.


Kind regards, David
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-18 15:05 ` Daniel Vetter
@ 2015-06-23 10:47   ` David Weinehall
  2015-06-23 11:12   ` David Weinehall
  1 sibling, 0 replies; 16+ messages in thread
From: David Weinehall @ 2015-06-23 10:47 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Jun 18, 2015 at 05:05:21PM +0200, Daniel Vetter wrote:
> On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> > @@ -3520,6 +3545,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
> >  	} else if (HAS_DDI(dev)) {
> >  		signal_levels = hsw_signal_levels(train_set);
> >  		mask = DDI_BUF_EMP_MASK;
> > +
> > +		if (IS_SKYLAKE(dev))
> > +			skl_set_iboost(intel_dp);
> 
> Imo this should be put into hsw_signal_levels and then hsw_signal_levels
> be moved into intel_ddi.c - that way everything related to low-level ddi
> DP signal level code in intel_ddi.c.

I'll have a go at it.


Regards, David
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-18 15:05 ` Daniel Vetter
  2015-06-23 10:47   ` David Weinehall
@ 2015-06-23 11:12   ` David Weinehall
  2015-06-23 12:07     ` Daniel Vetter
  2015-06-24  4:47     ` Jindal, Sonika
  1 sibling, 2 replies; 16+ messages in thread
From: David Weinehall @ 2015-06-23 11:12 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, Jun 18, 2015 at 05:05:21PM +0200, Daniel Vetter wrote:
> On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> > @@ -3520,6 +3545,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
> >  	} else if (HAS_DDI(dev)) {
> >  		signal_levels = hsw_signal_levels(train_set);
> >  		mask = DDI_BUF_EMP_MASK;
> > +
> > +		if (IS_SKYLAKE(dev))
> > +			skl_set_iboost(intel_dp);
> 
> Imo this should be put into hsw_signal_levels and then hsw_signal_levels
> be moved into intel_ddi.c - that way everything related to low-level ddi
> DP signal level code in intel_ddi.c.

I'm guessing the BXT code should be moved there too
and preferably folded in under HAS_DDI(dev)?


Kind regards, David
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-23 11:12   ` David Weinehall
@ 2015-06-23 12:07     ` Daniel Vetter
  2015-06-24  4:47     ` Jindal, Sonika
  1 sibling, 0 replies; 16+ messages in thread
From: Daniel Vetter @ 2015-06-23 12:07 UTC (permalink / raw)
  To: Daniel Vetter, intel-gfx

On Tue, Jun 23, 2015 at 02:12:41PM +0300, David Weinehall wrote:
> On Thu, Jun 18, 2015 at 05:05:21PM +0200, Daniel Vetter wrote:
> > On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> > > @@ -3520,6 +3545,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
> > >  	} else if (HAS_DDI(dev)) {
> > >  		signal_levels = hsw_signal_levels(train_set);
> > >  		mask = DDI_BUF_EMP_MASK;
> > > +
> > > +		if (IS_SKYLAKE(dev))
> > > +			skl_set_iboost(intel_dp);
> > 
> > Imo this should be put into hsw_signal_levels and then hsw_signal_levels
> > be moved into intel_ddi.c - that way everything related to low-level ddi
> > DP signal level code in intel_ddi.c.
> 
> I'm guessing the BXT code should be moved there too
> and preferably folded in under HAS_DDI(dev)?

Yeah that would make sense. And given the long list of vfuncs probably
also time to add a vfunc for this? But that's a bit ouf of scope now,
perhaps a follow-up.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-23 11:12   ` David Weinehall
  2015-06-23 12:07     ` Daniel Vetter
@ 2015-06-24  4:47     ` Jindal, Sonika
  2015-06-25 10:18       ` David Weinehall
  1 sibling, 1 reply; 16+ messages in thread
From: Jindal, Sonika @ 2015-06-24  4:47 UTC (permalink / raw)
  To: David Weinehall, Daniel Vetter; +Cc: intel-gfx



On 6/23/2015 4:42 PM, David Weinehall wrote:
> On Thu, Jun 18, 2015 at 05:05:21PM +0200, Daniel Vetter wrote:
>> On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
>>> @@ -3520,6 +3545,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
>>>   	} else if (HAS_DDI(dev)) {
>>>   		signal_levels = hsw_signal_levels(train_set);
>>>   		mask = DDI_BUF_EMP_MASK;
>>> +
>>> +		if (IS_SKYLAKE(dev))
>>> +			skl_set_iboost(intel_dp);
>>
>> Imo this should be put into hsw_signal_levels and then hsw_signal_levels
>> be moved into intel_ddi.c - that way everything related to low-level ddi
>> DP signal level code in intel_ddi.c.
>
> I'm guessing the BXT code should be moved there too
> and preferably folded in under HAS_DDI(dev)?
No, it is not required. The Vswing programming for SKL and BXT is 
completely different. So, better keep it separate.

>
>
> Kind regards, David
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-18 10:10 ` Chris Wilson
  2015-06-18 10:47   ` David Weinehall
@ 2015-06-25  8:09   ` David Weinehall
  1 sibling, 0 replies; 16+ messages in thread
From: David Weinehall @ 2015-06-25  8:09 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On Thu, Jun 18, 2015 at 11:10:13AM +0100, Chris Wilson wrote:
> These are static routing, but called fairly often. (Often enough that
> you care to only read the register once.) Any reason not to preserve
> these routing tables in dev_priv or, slightly more preferrable, intel_dp?

Looking over this a bit, I realise that Broxton suffers from the same
problem, *but* uses a different struct.  I think it'd be best to leave
things the way they are for the time being and try to come up with a
good solution that would work for both platforms without introducing
separate struct pointers to dev_priv (intel_dp while logically the
better option, is trickier to use from intel_ddi, since the function
that would set this up doesn't use intel_dp currently).

Opinions?


Kind regards, David
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/i915/skl: Buffer translation improvements
  2015-06-18  9:50 [PATCH] drm/i915/skl: Buffer translation improvements David Weinehall
  2015-06-18 10:10 ` Chris Wilson
  2015-06-18 15:05 ` Daniel Vetter
@ 2015-06-25  8:11 ` David Weinehall
  2015-06-29 10:35   ` Antti Koskipää
  2 siblings, 1 reply; 16+ messages in thread
From: David Weinehall @ 2015-06-25  8:11 UTC (permalink / raw)
  To: intel-gfx

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>
---
 drivers/gpu/drm/i915/i915_drv.h  |   8 +
 drivers/gpu/drm/i915/i915_reg.h  |  12 +
 drivers/gpu/drm/i915/intel_ddi.c | 507 ++++++++++++++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_dp.c  | 104 +-------
 drivers/gpu/drm/i915/intel_drv.h |   3 +-
 5 files changed, 421 insertions(+), 213 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 491ef0cfcb0b..09a57a584f5f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2415,6 +2415,14 @@ struct drm_i915_cmd_table {
 /* ULX machines are also considered ULT. */
 #define IS_HSW_ULX(dev)		(INTEL_DEVID(dev) == 0x0A0E || \
 				 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 SKL_REVID_A0		(0x0)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0b979ad16d41..fb63ead2b8eb 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1382,6 +1382,18 @@ enum skl_disp_power_wells {
 							_PORT_TX_DW14_LN0_C) + \
 					 _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
  */
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 31b29e8781ac..08f89299b572 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -31,6 +31,7 @@
 struct ddi_buf_trans {
 	u32 trans1;	/* balance leg enable, de-emph level */
 	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
@@ -38,134 +39,213 @@ struct ddi_buf_trans {
  * automatically adapt to HDMI connections as well
  */
 static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
-	{ 0x00FFFFFF, 0x0006000E },
-	{ 0x00D75FFF, 0x0005000A },
-	{ 0x00C30FFF, 0x00040006 },
-	{ 0x80AAAFFF, 0x000B0000 },
-	{ 0x00FFFFFF, 0x0005000A },
-	{ 0x00D75FFF, 0x000C0004 },
-	{ 0x80C30FFF, 0x000B0000 },
-	{ 0x00FFFFFF, 0x00040006 },
-	{ 0x80D75FFF, 0x000B0000 },
+	{ 0x00FFFFFF, 0x0006000E, 0x0 },
+	{ 0x00D75FFF, 0x0005000A, 0x0 },
+	{ 0x00C30FFF, 0x00040006, 0x0 },
+	{ 0x80AAAFFF, 0x000B0000, 0x0 },
+	{ 0x00FFFFFF, 0x0005000A, 0x0 },
+	{ 0x00D75FFF, 0x000C0004, 0x0 },
+	{ 0x80C30FFF, 0x000B0000, 0x0 },
+	{ 0x00FFFFFF, 0x00040006, 0x0 },
+	{ 0x80D75FFF, 0x000B0000, 0x0 },
 };
 
 static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
-	{ 0x00FFFFFF, 0x0007000E },
-	{ 0x00D75FFF, 0x000F000A },
-	{ 0x00C30FFF, 0x00060006 },
-	{ 0x00AAAFFF, 0x001E0000 },
-	{ 0x00FFFFFF, 0x000F000A },
-	{ 0x00D75FFF, 0x00160004 },
-	{ 0x00C30FFF, 0x001E0000 },
-	{ 0x00FFFFFF, 0x00060006 },
-	{ 0x00D75FFF, 0x001E0000 },
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },
+	{ 0x00D75FFF, 0x000F000A, 0x0 },
+	{ 0x00C30FFF, 0x00060006, 0x0 },
+	{ 0x00AAAFFF, 0x001E0000, 0x0 },
+	{ 0x00FFFFFF, 0x000F000A, 0x0 },
+	{ 0x00D75FFF, 0x00160004, 0x0 },
+	{ 0x00C30FFF, 0x001E0000, 0x0 },
+	{ 0x00FFFFFF, 0x00060006, 0x0 },
+	{ 0x00D75FFF, 0x001E0000, 0x0 },
 };
 
 static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
 					/* Idx	NT mV d	T mV d	db	*/
-	{ 0x00FFFFFF, 0x0006000E },	/* 0:	400	400	0	*/
-	{ 0x00E79FFF, 0x000E000C },	/* 1:	400	500	2	*/
-	{ 0x00D75FFF, 0x0005000A },	/* 2:	400	600	3.5	*/
-	{ 0x00FFFFFF, 0x0005000A },	/* 3:	600	600	0	*/
-	{ 0x00E79FFF, 0x001D0007 },	/* 4:	600	750	2	*/
-	{ 0x00D75FFF, 0x000C0004 },	/* 5:	600	900	3.5	*/
-	{ 0x00FFFFFF, 0x00040006 },	/* 6:	800	800	0	*/
-	{ 0x80E79FFF, 0x00030002 },	/* 7:	800	1000	2	*/
-	{ 0x00FFFFFF, 0x00140005 },	/* 8:	850	850	0	*/
-	{ 0x00FFFFFF, 0x000C0004 },	/* 9:	900	900	0	*/
-	{ 0x00FFFFFF, 0x001C0003 },	/* 10:	950	950	0	*/
-	{ 0x80FFFFFF, 0x00030002 },	/* 11:	1000	1000	0	*/
+	{ 0x00FFFFFF, 0x0006000E, 0x0 },/* 0:	400	400	0	*/
+	{ 0x00E79FFF, 0x000E000C, 0x0 },/* 1:	400	500	2	*/
+	{ 0x00D75FFF, 0x0005000A, 0x0 },/* 2:	400	600	3.5	*/
+	{ 0x00FFFFFF, 0x0005000A, 0x0 },/* 3:	600	600	0	*/
+	{ 0x00E79FFF, 0x001D0007, 0x0 },/* 4:	600	750	2	*/
+	{ 0x00D75FFF, 0x000C0004, 0x0 },/* 5:	600	900	3.5	*/
+	{ 0x00FFFFFF, 0x00040006, 0x0 },/* 6:	800	800	0	*/
+	{ 0x80E79FFF, 0x00030002, 0x0 },/* 7:	800	1000	2	*/
+	{ 0x00FFFFFF, 0x00140005, 0x0 },/* 8:	850	850	0	*/
+	{ 0x00FFFFFF, 0x000C0004, 0x0 },/* 9:	900	900	0	*/
+	{ 0x00FFFFFF, 0x001C0003, 0x0 },/* 10:	950	950	0	*/
+	{ 0x80FFFFFF, 0x00030002, 0x0 },/* 11:	1000	1000	0	*/
 };
 
 static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
-	{ 0x00FFFFFF, 0x00000012 },
-	{ 0x00EBAFFF, 0x00020011 },
-	{ 0x00C71FFF, 0x0006000F },
-	{ 0x00AAAFFF, 0x000E000A },
-	{ 0x00FFFFFF, 0x00020011 },
-	{ 0x00DB6FFF, 0x0005000F },
-	{ 0x00BEEFFF, 0x000A000C },
-	{ 0x00FFFFFF, 0x0005000F },
-	{ 0x00DB6FFF, 0x000A000C },
+	{ 0x00FFFFFF, 0x00000012, 0x0 },
+	{ 0x00EBAFFF, 0x00020011, 0x0 },
+	{ 0x00C71FFF, 0x0006000F, 0x0 },
+	{ 0x00AAAFFF, 0x000E000A, 0x0 },
+	{ 0x00FFFFFF, 0x00020011, 0x0 },
+	{ 0x00DB6FFF, 0x0005000F, 0x0 },
+	{ 0x00BEEFFF, 0x000A000C, 0x0 },
+	{ 0x00FFFFFF, 0x0005000F, 0x0 },
+	{ 0x00DB6FFF, 0x000A000C, 0x0 },
 };
 
 static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
-	{ 0x00FFFFFF, 0x0007000E },
-	{ 0x00D75FFF, 0x000E000A },
-	{ 0x00BEFFFF, 0x00140006 },
-	{ 0x80B2CFFF, 0x001B0002 },
-	{ 0x00FFFFFF, 0x000E000A },
-	{ 0x00DB6FFF, 0x00160005 },
-	{ 0x80C71FFF, 0x001A0002 },
-	{ 0x00F7DFFF, 0x00180004 },
-	{ 0x80D75FFF, 0x001B0002 },
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },
+	{ 0x00D75FFF, 0x000E000A, 0x0 },
+	{ 0x00BEFFFF, 0x00140006, 0x0 },
+	{ 0x80B2CFFF, 0x001B0002, 0x0 },
+	{ 0x00FFFFFF, 0x000E000A, 0x0 },
+	{ 0x00DB6FFF, 0x00160005, 0x0 },
+	{ 0x80C71FFF, 0x001A0002, 0x0 },
+	{ 0x00F7DFFF, 0x00180004, 0x0 },
+	{ 0x80D75FFF, 0x001B0002, 0x0 },
 };
 
 static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
-	{ 0x00FFFFFF, 0x0001000E },
-	{ 0x00D75FFF, 0x0004000A },
-	{ 0x00C30FFF, 0x00070006 },
-	{ 0x00AAAFFF, 0x000C0000 },
-	{ 0x00FFFFFF, 0x0004000A },
-	{ 0x00D75FFF, 0x00090004 },
-	{ 0x00C30FFF, 0x000C0000 },
-	{ 0x00FFFFFF, 0x00070006 },
-	{ 0x00D75FFF, 0x000C0000 },
+	{ 0x00FFFFFF, 0x0001000E, 0x0 },
+	{ 0x00D75FFF, 0x0004000A, 0x0 },
+	{ 0x00C30FFF, 0x00070006, 0x0 },
+	{ 0x00AAAFFF, 0x000C0000, 0x0 },
+	{ 0x00FFFFFF, 0x0004000A, 0x0 },
+	{ 0x00D75FFF, 0x00090004, 0x0 },
+	{ 0x00C30FFF, 0x000C0000, 0x0 },
+	{ 0x00FFFFFF, 0x00070006, 0x0 },
+	{ 0x00D75FFF, 0x000C0000, 0x0 },
 };
 
 static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
 					/* Idx	NT mV d	T mV df	db	*/
-	{ 0x00FFFFFF, 0x0007000E },	/* 0:	400	400	0	*/
-	{ 0x00D75FFF, 0x000E000A },	/* 1:	400	600	3.5	*/
-	{ 0x00BEFFFF, 0x00140006 },	/* 2:	400	800	6	*/
-	{ 0x00FFFFFF, 0x0009000D },	/* 3:	450	450	0	*/
-	{ 0x00FFFFFF, 0x000E000A },	/* 4:	600	600	0	*/
-	{ 0x00D7FFFF, 0x00140006 },	/* 5:	600	800	2.5	*/
-	{ 0x80CB2FFF, 0x001B0002 },	/* 6:	600	1000	4.5	*/
-	{ 0x00FFFFFF, 0x00140006 },	/* 7:	800	800	0	*/
-	{ 0x80E79FFF, 0x001B0002 },	/* 8:	800	1000	2	*/
-	{ 0x80FFFFFF, 0x001B0002 },	/* 9:	1000	1000	0	*/
+	{ 0x00FFFFFF, 0x0007000E, 0x0 },/* 0:	400	400	0	*/
+	{ 0x00D75FFF, 0x000E000A, 0x0 },/* 1:	400	600	3.5	*/
+	{ 0x00BEFFFF, 0x00140006, 0x0 },/* 2:	400	800	6	*/
+	{ 0x00FFFFFF, 0x0009000D, 0x0 },/* 3:	450	450	0	*/
+	{ 0x00FFFFFF, 0x000E000A, 0x0 },/* 4:	600	600	0	*/
+	{ 0x00D7FFFF, 0x00140006, 0x0 },/* 5:	600	800	2.5	*/
+	{ 0x80CB2FFF, 0x001B0002, 0x0 },/* 6:	600	1000	4.5	*/
+	{ 0x00FFFFFF, 0x00140006, 0x0 },/* 7:	800	800	0	*/
+	{ 0x80E79FFF, 0x001B0002, 0x0 },/* 8:	800	1000	2	*/
+	{ 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[] = {
-	{ 0x00000018, 0x000000a2 },
-	{ 0x00004014, 0x0000009B },
-	{ 0x00006012, 0x00000088 },
-	{ 0x00008010, 0x00000087 },
-	{ 0x00000018, 0x0000009B },
-	{ 0x00004014, 0x00000088 },
-	{ 0x00006012, 0x00000087 },
-	{ 0x00000018, 0x00000088 },
-	{ 0x00004014, 0x00000087 },
+	{ 0x00002016, 0x000000A0, 0x0 },
+	{ 0x00005012, 0x0000009B, 0x0 },
+	{ 0x00007011, 0x00000088, 0x0 },
+	{ 0x00009010, 0x000000C7, 0x0 },
+	{ 0x00002016, 0x0000009B, 0x0 },
+	{ 0x00005012, 0x00000088, 0x0 },
+	{ 0x00007011, 0x000000C7, 0x0 },
+	{ 0x00002016, 0x000000DF, 0x0 },
+	{ 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[] = {
-	{ 0x00000018, 0x000000a8 },
-	{ 0x00002016, 0x000000ab },
-	{ 0x00006012, 0x000000a2 },
-	{ 0x00008010, 0x00000088 },
-	{ 0x00000018, 0x000000ab },
-	{ 0x00004014, 0x000000a2 },
-	{ 0x00006012, 0x000000a6 },
-	{ 0x00000018, 0x000000a2 },
-	{ 0x00005013, 0x0000009c },
-	{ 0x00000018, 0x00000088 },
+	{ 0x00000018, 0x000000A8, 0x0 },
+	{ 0x00004013, 0x000000A9, 0x0 },
+	{ 0x00007011, 0x000000A2, 0x0 },
+	{ 0x00009010, 0x0000009C, 0x0 },
+	{ 0x00000018, 0x000000A9, 0x0 },
+	{ 0x00006013, 0x000000A2, 0x0 },
+	{ 0x00007011, 0x000000A6, 0x0 },
+	{ 0x00000018, 0x000000AB, 0x0 },
+	{ 0x00007013, 0x0000009F, 0x0 },
+	{ 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[] = {
-	{ 0x00000018, 0x000000ac },
-	{ 0x00005012, 0x0000009d },
-	{ 0x00007011, 0x00000088 },
-	{ 0x00000018, 0x000000a1 },
-	{ 0x00000018, 0x00000098 },
-	{ 0x00004013, 0x00000088 },
-	{ 0x00006012, 0x00000087 },
-	{ 0x00000018, 0x000000df },
-	{ 0x00003015, 0x00000087 },
-	{ 0x00003015, 0x000000c7 },
-	{ 0x00000018, 0x000000c7 },
+	{ 0x00000018, 0x000000AC, 0x0 },
+	{ 0x00005012, 0x0000009D, 0x0 },
+	{ 0x00007011, 0x00000088, 0x0 },
+	{ 0x00000018, 0x000000A1, 0x0 },
+	{ 0x00000018, 0x00000098, 0x0 },
+	{ 0x00004013, 0x00000088, 0x0 },
+	{ 0x00006012, 0x00000087, 0x0 },
+	{ 0x00000018, 0x000000DF, 0x0 },
+	{ 0x00003015, 0x00000087, 0x0 },	/* Default */
+	{ 0x00003015, 0x000000C7, 0x0 },
+	{ 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 {
@@ -190,7 +270,7 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
 	{ 154, 0x9A, 0, 64,  false },	/* 6:	600		6   */
 	{ 102, 0x9A, 0, 128, false },	/* 7:	800		0   */
 	{ 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.
@@ -210,6 +290,9 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
 	{ 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,
 				 struct intel_digital_port **dig_port,
 				 enum port *port)
@@ -249,6 +332,99 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
 	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
  * values in advance. The buffer values are different for FDI and DP modes,
@@ -279,20 +455,13 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
 					INTEL_OUTPUT_HDMI);
 		return;
 	} else if (IS_SKYLAKE(dev)) {
-		ddi_translations_fdi = NULL;
-		ddi_translations_dp = skl_ddi_translations_dp;
-		n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
-		if (dev_priv->edp_low_vswing) {
-			ddi_translations_edp = skl_ddi_translations_edp;
-			n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp);
-		} else {
-			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;
+		ddi_translations_dp =
+				skl_get_buf_trans_dp(dev, &n_dp_entries);
+		ddi_translations_edp =
+				skl_get_buf_trans_edp(dev, &n_edp_entries);
+		ddi_translations_hdmi =
+				skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
+		hdmi_default_entry = 8;
 	} else if (IS_BROADWELL(dev)) {
 		ddi_translations_fdi = bdw_ddi_translations_fdi;
 		ddi_translations_dp = bdw_ddi_translations_dp;
@@ -1806,8 +1975,49 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
 			   TRANS_CLK_SEL_DISABLED);
 }
 
-void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
-			     enum port port, int type)
+static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
+			       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;
 	const struct bxt_ddi_buf_trans *ddi_translations;
@@ -1867,6 +2077,73 @@ void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 	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)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f52eef138247..041e2d6dcc56 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3417,92 +3417,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. */
 static void
 intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
@@ -3510,22 +3424,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);
 	enum port port = intel_dig_port->port;
 	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];
 
-	if (IS_BROXTON(dev)) {
-		signal_levels = 0;
-		bxt_signal_levels(intel_dp);
-		mask = 0;
-	} else if (HAS_DDI(dev)) {
-		signal_levels = hsw_signal_levels(train_set);
-		mask = DDI_BUF_EMP_MASK;
+	if (HAS_DDI(dev)) {
+		signal_levels = ddi_signal_levels(intel_dp);
+
+		if (IS_BROXTON(dev))
+			signal_levels = 0;
+		else
+			mask = DDI_BUF_EMP_MASK;
 	} else if (IS_CHERRYVIEW(dev)) {
 		signal_levels = chv_signal_levels(intel_dp);
-		mask = 0;
 	} else if (IS_VALLEYVIEW(dev)) {
 		signal_levels = vlv_signal_levels(intel_dp);
-		mask = 0;
 	} else if (IS_GEN7(dev) && port == PORT_A) {
 		signal_levels = gen7_edp_signal_levels(train_set);
 		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index bcafefcf048b..c6cbe8c602f9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -950,8 +950,7 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
 void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
-void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
-				enum port port, int type);
+uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
 
 /* intel_frontbuffer.c */
 void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
-- 
2.1.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] drm/i915/skl: Buffer translation improvements
  2015-06-24  4:47     ` Jindal, Sonika
@ 2015-06-25 10:18       ` David Weinehall
  0 siblings, 0 replies; 16+ messages in thread
From: David Weinehall @ 2015-06-25 10:18 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Wed, Jun 24, 2015 at 10:17:34AM +0530, Jindal, Sonika wrote:
> 
> 
> On 6/23/2015 4:42 PM, David Weinehall wrote:
> >On Thu, Jun 18, 2015 at 05:05:21PM +0200, Daniel Vetter wrote:
> >>On Thu, Jun 18, 2015 at 12:50:33PM +0300, David Weinehall wrote:
> >>>@@ -3520,6 +3545,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
> >>>  	} else if (HAS_DDI(dev)) {
> >>>  		signal_levels = hsw_signal_levels(train_set);
> >>>  		mask = DDI_BUF_EMP_MASK;
> >>>+
> >>>+		if (IS_SKYLAKE(dev))
> >>>+			skl_set_iboost(intel_dp);
> >>
> >>Imo this should be put into hsw_signal_levels and then hsw_signal_levels
> >>be moved into intel_ddi.c - that way everything related to low-level ddi
> >>DP signal level code in intel_ddi.c.
> >
> >I'm guessing the BXT code should be moved there too
> >and preferably folded in under HAS_DDI(dev)?
> No, it is not required. The Vswing programming for SKL and BXT is completely
> different. So, better keep it separate.

It's not a matter of whether it's required, but whether it makes sense
from a consistency perspective.  From a logical point of view it makes
sense, and keeping them in the same place also makes it possible to
reuse quite a lot of code.  Hence my v2 does so.


Kind regards, David
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/i915/skl: Buffer translation improvements
  2015-06-25  8:11 ` [PATCH v2] " David Weinehall
@ 2015-06-29 10:35   ` Antti Koskipää
  2015-06-29 16:12     ` Daniel Vetter
  0 siblings, 1 reply; 16+ messages in thread
From: Antti Koskipää @ 2015-06-29 10:35 UTC (permalink / raw)
  To: intel-gfx

Looks fine to me.

Reviewed-by: Antti Koskipää <antti.koskipaa@linux.intel.com>


On 06/25/2015 11:11 AM, David Weinehall wrote:
> 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>
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |   8 +
>  drivers/gpu/drm/i915/i915_reg.h  |  12 +
>  drivers/gpu/drm/i915/intel_ddi.c | 507 ++++++++++++++++++++++++++++++---------
>  drivers/gpu/drm/i915/intel_dp.c  | 104 +-------
>  drivers/gpu/drm/i915/intel_drv.h |   3 +-
>  5 files changed, 421 insertions(+), 213 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 491ef0cfcb0b..09a57a584f5f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2415,6 +2415,14 @@ struct drm_i915_cmd_table {
>  /* ULX machines are also considered ULT. */
>  #define IS_HSW_ULX(dev)		(INTEL_DEVID(dev) == 0x0A0E || \
>  				 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 SKL_REVID_A0		(0x0)
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 0b979ad16d41..fb63ead2b8eb 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1382,6 +1382,18 @@ enum skl_disp_power_wells {
>  							_PORT_TX_DW14_LN0_C) + \
>  					 _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
>   */
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 31b29e8781ac..08f89299b572 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -31,6 +31,7 @@
>  struct ddi_buf_trans {
>  	u32 trans1;	/* balance leg enable, de-emph level */
>  	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
> @@ -38,134 +39,213 @@ struct ddi_buf_trans {
>   * automatically adapt to HDMI connections as well
>   */
>  static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
> -	{ 0x00FFFFFF, 0x0006000E },
> -	{ 0x00D75FFF, 0x0005000A },
> -	{ 0x00C30FFF, 0x00040006 },
> -	{ 0x80AAAFFF, 0x000B0000 },
> -	{ 0x00FFFFFF, 0x0005000A },
> -	{ 0x00D75FFF, 0x000C0004 },
> -	{ 0x80C30FFF, 0x000B0000 },
> -	{ 0x00FFFFFF, 0x00040006 },
> -	{ 0x80D75FFF, 0x000B0000 },
> +	{ 0x00FFFFFF, 0x0006000E, 0x0 },
> +	{ 0x00D75FFF, 0x0005000A, 0x0 },
> +	{ 0x00C30FFF, 0x00040006, 0x0 },
> +	{ 0x80AAAFFF, 0x000B0000, 0x0 },
> +	{ 0x00FFFFFF, 0x0005000A, 0x0 },
> +	{ 0x00D75FFF, 0x000C0004, 0x0 },
> +	{ 0x80C30FFF, 0x000B0000, 0x0 },
> +	{ 0x00FFFFFF, 0x00040006, 0x0 },
> +	{ 0x80D75FFF, 0x000B0000, 0x0 },
>  };
>  
>  static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
> -	{ 0x00FFFFFF, 0x0007000E },
> -	{ 0x00D75FFF, 0x000F000A },
> -	{ 0x00C30FFF, 0x00060006 },
> -	{ 0x00AAAFFF, 0x001E0000 },
> -	{ 0x00FFFFFF, 0x000F000A },
> -	{ 0x00D75FFF, 0x00160004 },
> -	{ 0x00C30FFF, 0x001E0000 },
> -	{ 0x00FFFFFF, 0x00060006 },
> -	{ 0x00D75FFF, 0x001E0000 },
> +	{ 0x00FFFFFF, 0x0007000E, 0x0 },
> +	{ 0x00D75FFF, 0x000F000A, 0x0 },
> +	{ 0x00C30FFF, 0x00060006, 0x0 },
> +	{ 0x00AAAFFF, 0x001E0000, 0x0 },
> +	{ 0x00FFFFFF, 0x000F000A, 0x0 },
> +	{ 0x00D75FFF, 0x00160004, 0x0 },
> +	{ 0x00C30FFF, 0x001E0000, 0x0 },
> +	{ 0x00FFFFFF, 0x00060006, 0x0 },
> +	{ 0x00D75FFF, 0x001E0000, 0x0 },
>  };
>  
>  static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
>  					/* Idx	NT mV d	T mV d	db	*/
> -	{ 0x00FFFFFF, 0x0006000E },	/* 0:	400	400	0	*/
> -	{ 0x00E79FFF, 0x000E000C },	/* 1:	400	500	2	*/
> -	{ 0x00D75FFF, 0x0005000A },	/* 2:	400	600	3.5	*/
> -	{ 0x00FFFFFF, 0x0005000A },	/* 3:	600	600	0	*/
> -	{ 0x00E79FFF, 0x001D0007 },	/* 4:	600	750	2	*/
> -	{ 0x00D75FFF, 0x000C0004 },	/* 5:	600	900	3.5	*/
> -	{ 0x00FFFFFF, 0x00040006 },	/* 6:	800	800	0	*/
> -	{ 0x80E79FFF, 0x00030002 },	/* 7:	800	1000	2	*/
> -	{ 0x00FFFFFF, 0x00140005 },	/* 8:	850	850	0	*/
> -	{ 0x00FFFFFF, 0x000C0004 },	/* 9:	900	900	0	*/
> -	{ 0x00FFFFFF, 0x001C0003 },	/* 10:	950	950	0	*/
> -	{ 0x80FFFFFF, 0x00030002 },	/* 11:	1000	1000	0	*/
> +	{ 0x00FFFFFF, 0x0006000E, 0x0 },/* 0:	400	400	0	*/
> +	{ 0x00E79FFF, 0x000E000C, 0x0 },/* 1:	400	500	2	*/
> +	{ 0x00D75FFF, 0x0005000A, 0x0 },/* 2:	400	600	3.5	*/
> +	{ 0x00FFFFFF, 0x0005000A, 0x0 },/* 3:	600	600	0	*/
> +	{ 0x00E79FFF, 0x001D0007, 0x0 },/* 4:	600	750	2	*/
> +	{ 0x00D75FFF, 0x000C0004, 0x0 },/* 5:	600	900	3.5	*/
> +	{ 0x00FFFFFF, 0x00040006, 0x0 },/* 6:	800	800	0	*/
> +	{ 0x80E79FFF, 0x00030002, 0x0 },/* 7:	800	1000	2	*/
> +	{ 0x00FFFFFF, 0x00140005, 0x0 },/* 8:	850	850	0	*/
> +	{ 0x00FFFFFF, 0x000C0004, 0x0 },/* 9:	900	900	0	*/
> +	{ 0x00FFFFFF, 0x001C0003, 0x0 },/* 10:	950	950	0	*/
> +	{ 0x80FFFFFF, 0x00030002, 0x0 },/* 11:	1000	1000	0	*/
>  };
>  
>  static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
> -	{ 0x00FFFFFF, 0x00000012 },
> -	{ 0x00EBAFFF, 0x00020011 },
> -	{ 0x00C71FFF, 0x0006000F },
> -	{ 0x00AAAFFF, 0x000E000A },
> -	{ 0x00FFFFFF, 0x00020011 },
> -	{ 0x00DB6FFF, 0x0005000F },
> -	{ 0x00BEEFFF, 0x000A000C },
> -	{ 0x00FFFFFF, 0x0005000F },
> -	{ 0x00DB6FFF, 0x000A000C },
> +	{ 0x00FFFFFF, 0x00000012, 0x0 },
> +	{ 0x00EBAFFF, 0x00020011, 0x0 },
> +	{ 0x00C71FFF, 0x0006000F, 0x0 },
> +	{ 0x00AAAFFF, 0x000E000A, 0x0 },
> +	{ 0x00FFFFFF, 0x00020011, 0x0 },
> +	{ 0x00DB6FFF, 0x0005000F, 0x0 },
> +	{ 0x00BEEFFF, 0x000A000C, 0x0 },
> +	{ 0x00FFFFFF, 0x0005000F, 0x0 },
> +	{ 0x00DB6FFF, 0x000A000C, 0x0 },
>  };
>  
>  static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
> -	{ 0x00FFFFFF, 0x0007000E },
> -	{ 0x00D75FFF, 0x000E000A },
> -	{ 0x00BEFFFF, 0x00140006 },
> -	{ 0x80B2CFFF, 0x001B0002 },
> -	{ 0x00FFFFFF, 0x000E000A },
> -	{ 0x00DB6FFF, 0x00160005 },
> -	{ 0x80C71FFF, 0x001A0002 },
> -	{ 0x00F7DFFF, 0x00180004 },
> -	{ 0x80D75FFF, 0x001B0002 },
> +	{ 0x00FFFFFF, 0x0007000E, 0x0 },
> +	{ 0x00D75FFF, 0x000E000A, 0x0 },
> +	{ 0x00BEFFFF, 0x00140006, 0x0 },
> +	{ 0x80B2CFFF, 0x001B0002, 0x0 },
> +	{ 0x00FFFFFF, 0x000E000A, 0x0 },
> +	{ 0x00DB6FFF, 0x00160005, 0x0 },
> +	{ 0x80C71FFF, 0x001A0002, 0x0 },
> +	{ 0x00F7DFFF, 0x00180004, 0x0 },
> +	{ 0x80D75FFF, 0x001B0002, 0x0 },
>  };
>  
>  static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
> -	{ 0x00FFFFFF, 0x0001000E },
> -	{ 0x00D75FFF, 0x0004000A },
> -	{ 0x00C30FFF, 0x00070006 },
> -	{ 0x00AAAFFF, 0x000C0000 },
> -	{ 0x00FFFFFF, 0x0004000A },
> -	{ 0x00D75FFF, 0x00090004 },
> -	{ 0x00C30FFF, 0x000C0000 },
> -	{ 0x00FFFFFF, 0x00070006 },
> -	{ 0x00D75FFF, 0x000C0000 },
> +	{ 0x00FFFFFF, 0x0001000E, 0x0 },
> +	{ 0x00D75FFF, 0x0004000A, 0x0 },
> +	{ 0x00C30FFF, 0x00070006, 0x0 },
> +	{ 0x00AAAFFF, 0x000C0000, 0x0 },
> +	{ 0x00FFFFFF, 0x0004000A, 0x0 },
> +	{ 0x00D75FFF, 0x00090004, 0x0 },
> +	{ 0x00C30FFF, 0x000C0000, 0x0 },
> +	{ 0x00FFFFFF, 0x00070006, 0x0 },
> +	{ 0x00D75FFF, 0x000C0000, 0x0 },
>  };
>  
>  static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
>  					/* Idx	NT mV d	T mV df	db	*/
> -	{ 0x00FFFFFF, 0x0007000E },	/* 0:	400	400	0	*/
> -	{ 0x00D75FFF, 0x000E000A },	/* 1:	400	600	3.5	*/
> -	{ 0x00BEFFFF, 0x00140006 },	/* 2:	400	800	6	*/
> -	{ 0x00FFFFFF, 0x0009000D },	/* 3:	450	450	0	*/
> -	{ 0x00FFFFFF, 0x000E000A },	/* 4:	600	600	0	*/
> -	{ 0x00D7FFFF, 0x00140006 },	/* 5:	600	800	2.5	*/
> -	{ 0x80CB2FFF, 0x001B0002 },	/* 6:	600	1000	4.5	*/
> -	{ 0x00FFFFFF, 0x00140006 },	/* 7:	800	800	0	*/
> -	{ 0x80E79FFF, 0x001B0002 },	/* 8:	800	1000	2	*/
> -	{ 0x80FFFFFF, 0x001B0002 },	/* 9:	1000	1000	0	*/
> +	{ 0x00FFFFFF, 0x0007000E, 0x0 },/* 0:	400	400	0	*/
> +	{ 0x00D75FFF, 0x000E000A, 0x0 },/* 1:	400	600	3.5	*/
> +	{ 0x00BEFFFF, 0x00140006, 0x0 },/* 2:	400	800	6	*/
> +	{ 0x00FFFFFF, 0x0009000D, 0x0 },/* 3:	450	450	0	*/
> +	{ 0x00FFFFFF, 0x000E000A, 0x0 },/* 4:	600	600	0	*/
> +	{ 0x00D7FFFF, 0x00140006, 0x0 },/* 5:	600	800	2.5	*/
> +	{ 0x80CB2FFF, 0x001B0002, 0x0 },/* 6:	600	1000	4.5	*/
> +	{ 0x00FFFFFF, 0x00140006, 0x0 },/* 7:	800	800	0	*/
> +	{ 0x80E79FFF, 0x001B0002, 0x0 },/* 8:	800	1000	2	*/
> +	{ 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[] = {
> -	{ 0x00000018, 0x000000a2 },
> -	{ 0x00004014, 0x0000009B },
> -	{ 0x00006012, 0x00000088 },
> -	{ 0x00008010, 0x00000087 },
> -	{ 0x00000018, 0x0000009B },
> -	{ 0x00004014, 0x00000088 },
> -	{ 0x00006012, 0x00000087 },
> -	{ 0x00000018, 0x00000088 },
> -	{ 0x00004014, 0x00000087 },
> +	{ 0x00002016, 0x000000A0, 0x0 },
> +	{ 0x00005012, 0x0000009B, 0x0 },
> +	{ 0x00007011, 0x00000088, 0x0 },
> +	{ 0x00009010, 0x000000C7, 0x0 },
> +	{ 0x00002016, 0x0000009B, 0x0 },
> +	{ 0x00005012, 0x00000088, 0x0 },
> +	{ 0x00007011, 0x000000C7, 0x0 },
> +	{ 0x00002016, 0x000000DF, 0x0 },
> +	{ 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[] = {
> -	{ 0x00000018, 0x000000a8 },
> -	{ 0x00002016, 0x000000ab },
> -	{ 0x00006012, 0x000000a2 },
> -	{ 0x00008010, 0x00000088 },
> -	{ 0x00000018, 0x000000ab },
> -	{ 0x00004014, 0x000000a2 },
> -	{ 0x00006012, 0x000000a6 },
> -	{ 0x00000018, 0x000000a2 },
> -	{ 0x00005013, 0x0000009c },
> -	{ 0x00000018, 0x00000088 },
> +	{ 0x00000018, 0x000000A8, 0x0 },
> +	{ 0x00004013, 0x000000A9, 0x0 },
> +	{ 0x00007011, 0x000000A2, 0x0 },
> +	{ 0x00009010, 0x0000009C, 0x0 },
> +	{ 0x00000018, 0x000000A9, 0x0 },
> +	{ 0x00006013, 0x000000A2, 0x0 },
> +	{ 0x00007011, 0x000000A6, 0x0 },
> +	{ 0x00000018, 0x000000AB, 0x0 },
> +	{ 0x00007013, 0x0000009F, 0x0 },
> +	{ 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[] = {
> -	{ 0x00000018, 0x000000ac },
> -	{ 0x00005012, 0x0000009d },
> -	{ 0x00007011, 0x00000088 },
> -	{ 0x00000018, 0x000000a1 },
> -	{ 0x00000018, 0x00000098 },
> -	{ 0x00004013, 0x00000088 },
> -	{ 0x00006012, 0x00000087 },
> -	{ 0x00000018, 0x000000df },
> -	{ 0x00003015, 0x00000087 },
> -	{ 0x00003015, 0x000000c7 },
> -	{ 0x00000018, 0x000000c7 },
> +	{ 0x00000018, 0x000000AC, 0x0 },
> +	{ 0x00005012, 0x0000009D, 0x0 },
> +	{ 0x00007011, 0x00000088, 0x0 },
> +	{ 0x00000018, 0x000000A1, 0x0 },
> +	{ 0x00000018, 0x00000098, 0x0 },
> +	{ 0x00004013, 0x00000088, 0x0 },
> +	{ 0x00006012, 0x00000087, 0x0 },
> +	{ 0x00000018, 0x000000DF, 0x0 },
> +	{ 0x00003015, 0x00000087, 0x0 },	/* Default */
> +	{ 0x00003015, 0x000000C7, 0x0 },
> +	{ 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 {
> @@ -190,7 +270,7 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
>  	{ 154, 0x9A, 0, 64,  false },	/* 6:	600		6   */
>  	{ 102, 0x9A, 0, 128, false },	/* 7:	800		0   */
>  	{ 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.
> @@ -210,6 +290,9 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
>  	{ 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,
>  				 struct intel_digital_port **dig_port,
>  				 enum port *port)
> @@ -249,6 +332,99 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
>  	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
>   * values in advance. The buffer values are different for FDI and DP modes,
> @@ -279,20 +455,13 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
>  					INTEL_OUTPUT_HDMI);
>  		return;
>  	} else if (IS_SKYLAKE(dev)) {
> -		ddi_translations_fdi = NULL;
> -		ddi_translations_dp = skl_ddi_translations_dp;
> -		n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
> -		if (dev_priv->edp_low_vswing) {
> -			ddi_translations_edp = skl_ddi_translations_edp;
> -			n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp);
> -		} else {
> -			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;
> +		ddi_translations_dp =
> +				skl_get_buf_trans_dp(dev, &n_dp_entries);
> +		ddi_translations_edp =
> +				skl_get_buf_trans_edp(dev, &n_edp_entries);
> +		ddi_translations_hdmi =
> +				skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
> +		hdmi_default_entry = 8;
>  	} else if (IS_BROADWELL(dev)) {
>  		ddi_translations_fdi = bdw_ddi_translations_fdi;
>  		ddi_translations_dp = bdw_ddi_translations_dp;
> @@ -1806,8 +1975,49 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
>  			   TRANS_CLK_SEL_DISABLED);
>  }
>  
> -void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
> -			     enum port port, int type)
> +static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
> +			       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;
>  	const struct bxt_ddi_buf_trans *ddi_translations;
> @@ -1867,6 +2077,73 @@ void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
>  	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)
>  {
>  	struct drm_encoder *encoder = &intel_encoder->base;
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index f52eef138247..041e2d6dcc56 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3417,92 +3417,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. */
>  static void
>  intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
> @@ -3510,22 +3424,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);
>  	enum port port = intel_dig_port->port;
>  	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];
>  
> -	if (IS_BROXTON(dev)) {
> -		signal_levels = 0;
> -		bxt_signal_levels(intel_dp);
> -		mask = 0;
> -	} else if (HAS_DDI(dev)) {
> -		signal_levels = hsw_signal_levels(train_set);
> -		mask = DDI_BUF_EMP_MASK;
> +	if (HAS_DDI(dev)) {
> +		signal_levels = ddi_signal_levels(intel_dp);
> +
> +		if (IS_BROXTON(dev))
> +			signal_levels = 0;
> +		else
> +			mask = DDI_BUF_EMP_MASK;
>  	} else if (IS_CHERRYVIEW(dev)) {
>  		signal_levels = chv_signal_levels(intel_dp);
> -		mask = 0;
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		signal_levels = vlv_signal_levels(intel_dp);
> -		mask = 0;
>  	} else if (IS_GEN7(dev) && port == PORT_A) {
>  		signal_levels = gen7_edp_signal_levels(train_set);
>  		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index bcafefcf048b..c6cbe8c602f9 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -950,8 +950,7 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
>  void intel_ddi_clock_get(struct intel_encoder *encoder,
>  			 struct intel_crtc_state *pipe_config);
>  void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
> -void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
> -				enum port port, int type);
> +uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
>  
>  /* intel_frontbuffer.c */
>  void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
> 

-- 
- Antti

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/i915/skl: Buffer translation improvements
  2015-06-29 10:35   ` Antti Koskipää
@ 2015-06-29 16:12     ` Daniel Vetter
  2015-06-30 10:27       ` David Weinehall
  0 siblings, 1 reply; 16+ messages in thread
From: Daniel Vetter @ 2015-06-29 16:12 UTC (permalink / raw)
  To: Antti Koskipää; +Cc: intel-gfx

On Mon, Jun 29, 2015 at 01:35:06PM +0300, Antti Koskipää wrote:
> Looks fine to me.
> 
> Reviewed-by: Antti Koskipää <antti.koskipaa@linux.intel.com>
> 
> 
> On 06/25/2015 11:11 AM, David Weinehall wrote:
> > 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

For next time around please split out refactoring from actual code
changes, makes it a pain to review. And if this blows up in a
regression that's really annoying. Also please head checkpatch's
suggestions a bit more, I fixed that up when applying.
-Daniel

> > 
> > Issue: VIZ-5677
> > Signed-off-by: David Weinehall <david.weinehall@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h  |   8 +
> >  drivers/gpu/drm/i915/i915_reg.h  |  12 +
> >  drivers/gpu/drm/i915/intel_ddi.c | 507 ++++++++++++++++++++++++++++++---------
> >  drivers/gpu/drm/i915/intel_dp.c  | 104 +-------
> >  drivers/gpu/drm/i915/intel_drv.h |   3 +-
> >  5 files changed, 421 insertions(+), 213 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 491ef0cfcb0b..09a57a584f5f 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2415,6 +2415,14 @@ struct drm_i915_cmd_table {
> >  /* ULX machines are also considered ULT. */
> >  #define IS_HSW_ULX(dev)		(INTEL_DEVID(dev) == 0x0A0E || \
> >  				 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 SKL_REVID_A0		(0x0)
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > index 0b979ad16d41..fb63ead2b8eb 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -1382,6 +1382,18 @@ enum skl_disp_power_wells {
> >  							_PORT_TX_DW14_LN0_C) + \
> >  					 _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
> >   */
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 31b29e8781ac..08f89299b572 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -31,6 +31,7 @@
> >  struct ddi_buf_trans {
> >  	u32 trans1;	/* balance leg enable, de-emph level */
> >  	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
> > @@ -38,134 +39,213 @@ struct ddi_buf_trans {
> >   * automatically adapt to HDMI connections as well
> >   */
> >  static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
> > -	{ 0x00FFFFFF, 0x0006000E },
> > -	{ 0x00D75FFF, 0x0005000A },
> > -	{ 0x00C30FFF, 0x00040006 },
> > -	{ 0x80AAAFFF, 0x000B0000 },
> > -	{ 0x00FFFFFF, 0x0005000A },
> > -	{ 0x00D75FFF, 0x000C0004 },
> > -	{ 0x80C30FFF, 0x000B0000 },
> > -	{ 0x00FFFFFF, 0x00040006 },
> > -	{ 0x80D75FFF, 0x000B0000 },
> > +	{ 0x00FFFFFF, 0x0006000E, 0x0 },
> > +	{ 0x00D75FFF, 0x0005000A, 0x0 },
> > +	{ 0x00C30FFF, 0x00040006, 0x0 },
> > +	{ 0x80AAAFFF, 0x000B0000, 0x0 },
> > +	{ 0x00FFFFFF, 0x0005000A, 0x0 },
> > +	{ 0x00D75FFF, 0x000C0004, 0x0 },
> > +	{ 0x80C30FFF, 0x000B0000, 0x0 },
> > +	{ 0x00FFFFFF, 0x00040006, 0x0 },
> > +	{ 0x80D75FFF, 0x000B0000, 0x0 },
> >  };
> >  
> >  static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
> > -	{ 0x00FFFFFF, 0x0007000E },
> > -	{ 0x00D75FFF, 0x000F000A },
> > -	{ 0x00C30FFF, 0x00060006 },
> > -	{ 0x00AAAFFF, 0x001E0000 },
> > -	{ 0x00FFFFFF, 0x000F000A },
> > -	{ 0x00D75FFF, 0x00160004 },
> > -	{ 0x00C30FFF, 0x001E0000 },
> > -	{ 0x00FFFFFF, 0x00060006 },
> > -	{ 0x00D75FFF, 0x001E0000 },
> > +	{ 0x00FFFFFF, 0x0007000E, 0x0 },
> > +	{ 0x00D75FFF, 0x000F000A, 0x0 },
> > +	{ 0x00C30FFF, 0x00060006, 0x0 },
> > +	{ 0x00AAAFFF, 0x001E0000, 0x0 },
> > +	{ 0x00FFFFFF, 0x000F000A, 0x0 },
> > +	{ 0x00D75FFF, 0x00160004, 0x0 },
> > +	{ 0x00C30FFF, 0x001E0000, 0x0 },
> > +	{ 0x00FFFFFF, 0x00060006, 0x0 },
> > +	{ 0x00D75FFF, 0x001E0000, 0x0 },
> >  };
> >  
> >  static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
> >  					/* Idx	NT mV d	T mV d	db	*/
> > -	{ 0x00FFFFFF, 0x0006000E },	/* 0:	400	400	0	*/
> > -	{ 0x00E79FFF, 0x000E000C },	/* 1:	400	500	2	*/
> > -	{ 0x00D75FFF, 0x0005000A },	/* 2:	400	600	3.5	*/
> > -	{ 0x00FFFFFF, 0x0005000A },	/* 3:	600	600	0	*/
> > -	{ 0x00E79FFF, 0x001D0007 },	/* 4:	600	750	2	*/
> > -	{ 0x00D75FFF, 0x000C0004 },	/* 5:	600	900	3.5	*/
> > -	{ 0x00FFFFFF, 0x00040006 },	/* 6:	800	800	0	*/
> > -	{ 0x80E79FFF, 0x00030002 },	/* 7:	800	1000	2	*/
> > -	{ 0x00FFFFFF, 0x00140005 },	/* 8:	850	850	0	*/
> > -	{ 0x00FFFFFF, 0x000C0004 },	/* 9:	900	900	0	*/
> > -	{ 0x00FFFFFF, 0x001C0003 },	/* 10:	950	950	0	*/
> > -	{ 0x80FFFFFF, 0x00030002 },	/* 11:	1000	1000	0	*/
> > +	{ 0x00FFFFFF, 0x0006000E, 0x0 },/* 0:	400	400	0	*/
> > +	{ 0x00E79FFF, 0x000E000C, 0x0 },/* 1:	400	500	2	*/
> > +	{ 0x00D75FFF, 0x0005000A, 0x0 },/* 2:	400	600	3.5	*/
> > +	{ 0x00FFFFFF, 0x0005000A, 0x0 },/* 3:	600	600	0	*/
> > +	{ 0x00E79FFF, 0x001D0007, 0x0 },/* 4:	600	750	2	*/
> > +	{ 0x00D75FFF, 0x000C0004, 0x0 },/* 5:	600	900	3.5	*/
> > +	{ 0x00FFFFFF, 0x00040006, 0x0 },/* 6:	800	800	0	*/
> > +	{ 0x80E79FFF, 0x00030002, 0x0 },/* 7:	800	1000	2	*/
> > +	{ 0x00FFFFFF, 0x00140005, 0x0 },/* 8:	850	850	0	*/
> > +	{ 0x00FFFFFF, 0x000C0004, 0x0 },/* 9:	900	900	0	*/
> > +	{ 0x00FFFFFF, 0x001C0003, 0x0 },/* 10:	950	950	0	*/
> > +	{ 0x80FFFFFF, 0x00030002, 0x0 },/* 11:	1000	1000	0	*/
> >  };
> >  
> >  static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
> > -	{ 0x00FFFFFF, 0x00000012 },
> > -	{ 0x00EBAFFF, 0x00020011 },
> > -	{ 0x00C71FFF, 0x0006000F },
> > -	{ 0x00AAAFFF, 0x000E000A },
> > -	{ 0x00FFFFFF, 0x00020011 },
> > -	{ 0x00DB6FFF, 0x0005000F },
> > -	{ 0x00BEEFFF, 0x000A000C },
> > -	{ 0x00FFFFFF, 0x0005000F },
> > -	{ 0x00DB6FFF, 0x000A000C },
> > +	{ 0x00FFFFFF, 0x00000012, 0x0 },
> > +	{ 0x00EBAFFF, 0x00020011, 0x0 },
> > +	{ 0x00C71FFF, 0x0006000F, 0x0 },
> > +	{ 0x00AAAFFF, 0x000E000A, 0x0 },
> > +	{ 0x00FFFFFF, 0x00020011, 0x0 },
> > +	{ 0x00DB6FFF, 0x0005000F, 0x0 },
> > +	{ 0x00BEEFFF, 0x000A000C, 0x0 },
> > +	{ 0x00FFFFFF, 0x0005000F, 0x0 },
> > +	{ 0x00DB6FFF, 0x000A000C, 0x0 },
> >  };
> >  
> >  static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
> > -	{ 0x00FFFFFF, 0x0007000E },
> > -	{ 0x00D75FFF, 0x000E000A },
> > -	{ 0x00BEFFFF, 0x00140006 },
> > -	{ 0x80B2CFFF, 0x001B0002 },
> > -	{ 0x00FFFFFF, 0x000E000A },
> > -	{ 0x00DB6FFF, 0x00160005 },
> > -	{ 0x80C71FFF, 0x001A0002 },
> > -	{ 0x00F7DFFF, 0x00180004 },
> > -	{ 0x80D75FFF, 0x001B0002 },
> > +	{ 0x00FFFFFF, 0x0007000E, 0x0 },
> > +	{ 0x00D75FFF, 0x000E000A, 0x0 },
> > +	{ 0x00BEFFFF, 0x00140006, 0x0 },
> > +	{ 0x80B2CFFF, 0x001B0002, 0x0 },
> > +	{ 0x00FFFFFF, 0x000E000A, 0x0 },
> > +	{ 0x00DB6FFF, 0x00160005, 0x0 },
> > +	{ 0x80C71FFF, 0x001A0002, 0x0 },
> > +	{ 0x00F7DFFF, 0x00180004, 0x0 },
> > +	{ 0x80D75FFF, 0x001B0002, 0x0 },
> >  };
> >  
> >  static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
> > -	{ 0x00FFFFFF, 0x0001000E },
> > -	{ 0x00D75FFF, 0x0004000A },
> > -	{ 0x00C30FFF, 0x00070006 },
> > -	{ 0x00AAAFFF, 0x000C0000 },
> > -	{ 0x00FFFFFF, 0x0004000A },
> > -	{ 0x00D75FFF, 0x00090004 },
> > -	{ 0x00C30FFF, 0x000C0000 },
> > -	{ 0x00FFFFFF, 0x00070006 },
> > -	{ 0x00D75FFF, 0x000C0000 },
> > +	{ 0x00FFFFFF, 0x0001000E, 0x0 },
> > +	{ 0x00D75FFF, 0x0004000A, 0x0 },
> > +	{ 0x00C30FFF, 0x00070006, 0x0 },
> > +	{ 0x00AAAFFF, 0x000C0000, 0x0 },
> > +	{ 0x00FFFFFF, 0x0004000A, 0x0 },
> > +	{ 0x00D75FFF, 0x00090004, 0x0 },
> > +	{ 0x00C30FFF, 0x000C0000, 0x0 },
> > +	{ 0x00FFFFFF, 0x00070006, 0x0 },
> > +	{ 0x00D75FFF, 0x000C0000, 0x0 },
> >  };
> >  
> >  static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
> >  					/* Idx	NT mV d	T mV df	db	*/
> > -	{ 0x00FFFFFF, 0x0007000E },	/* 0:	400	400	0	*/
> > -	{ 0x00D75FFF, 0x000E000A },	/* 1:	400	600	3.5	*/
> > -	{ 0x00BEFFFF, 0x00140006 },	/* 2:	400	800	6	*/
> > -	{ 0x00FFFFFF, 0x0009000D },	/* 3:	450	450	0	*/
> > -	{ 0x00FFFFFF, 0x000E000A },	/* 4:	600	600	0	*/
> > -	{ 0x00D7FFFF, 0x00140006 },	/* 5:	600	800	2.5	*/
> > -	{ 0x80CB2FFF, 0x001B0002 },	/* 6:	600	1000	4.5	*/
> > -	{ 0x00FFFFFF, 0x00140006 },	/* 7:	800	800	0	*/
> > -	{ 0x80E79FFF, 0x001B0002 },	/* 8:	800	1000	2	*/
> > -	{ 0x80FFFFFF, 0x001B0002 },	/* 9:	1000	1000	0	*/
> > +	{ 0x00FFFFFF, 0x0007000E, 0x0 },/* 0:	400	400	0	*/
> > +	{ 0x00D75FFF, 0x000E000A, 0x0 },/* 1:	400	600	3.5	*/
> > +	{ 0x00BEFFFF, 0x00140006, 0x0 },/* 2:	400	800	6	*/
> > +	{ 0x00FFFFFF, 0x0009000D, 0x0 },/* 3:	450	450	0	*/
> > +	{ 0x00FFFFFF, 0x000E000A, 0x0 },/* 4:	600	600	0	*/
> > +	{ 0x00D7FFFF, 0x00140006, 0x0 },/* 5:	600	800	2.5	*/
> > +	{ 0x80CB2FFF, 0x001B0002, 0x0 },/* 6:	600	1000	4.5	*/
> > +	{ 0x00FFFFFF, 0x00140006, 0x0 },/* 7:	800	800	0	*/
> > +	{ 0x80E79FFF, 0x001B0002, 0x0 },/* 8:	800	1000	2	*/
> > +	{ 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[] = {
> > -	{ 0x00000018, 0x000000a2 },
> > -	{ 0x00004014, 0x0000009B },
> > -	{ 0x00006012, 0x00000088 },
> > -	{ 0x00008010, 0x00000087 },
> > -	{ 0x00000018, 0x0000009B },
> > -	{ 0x00004014, 0x00000088 },
> > -	{ 0x00006012, 0x00000087 },
> > -	{ 0x00000018, 0x00000088 },
> > -	{ 0x00004014, 0x00000087 },
> > +	{ 0x00002016, 0x000000A0, 0x0 },
> > +	{ 0x00005012, 0x0000009B, 0x0 },
> > +	{ 0x00007011, 0x00000088, 0x0 },
> > +	{ 0x00009010, 0x000000C7, 0x0 },
> > +	{ 0x00002016, 0x0000009B, 0x0 },
> > +	{ 0x00005012, 0x00000088, 0x0 },
> > +	{ 0x00007011, 0x000000C7, 0x0 },
> > +	{ 0x00002016, 0x000000DF, 0x0 },
> > +	{ 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[] = {
> > -	{ 0x00000018, 0x000000a8 },
> > -	{ 0x00002016, 0x000000ab },
> > -	{ 0x00006012, 0x000000a2 },
> > -	{ 0x00008010, 0x00000088 },
> > -	{ 0x00000018, 0x000000ab },
> > -	{ 0x00004014, 0x000000a2 },
> > -	{ 0x00006012, 0x000000a6 },
> > -	{ 0x00000018, 0x000000a2 },
> > -	{ 0x00005013, 0x0000009c },
> > -	{ 0x00000018, 0x00000088 },
> > +	{ 0x00000018, 0x000000A8, 0x0 },
> > +	{ 0x00004013, 0x000000A9, 0x0 },
> > +	{ 0x00007011, 0x000000A2, 0x0 },
> > +	{ 0x00009010, 0x0000009C, 0x0 },
> > +	{ 0x00000018, 0x000000A9, 0x0 },
> > +	{ 0x00006013, 0x000000A2, 0x0 },
> > +	{ 0x00007011, 0x000000A6, 0x0 },
> > +	{ 0x00000018, 0x000000AB, 0x0 },
> > +	{ 0x00007013, 0x0000009F, 0x0 },
> > +	{ 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[] = {
> > -	{ 0x00000018, 0x000000ac },
> > -	{ 0x00005012, 0x0000009d },
> > -	{ 0x00007011, 0x00000088 },
> > -	{ 0x00000018, 0x000000a1 },
> > -	{ 0x00000018, 0x00000098 },
> > -	{ 0x00004013, 0x00000088 },
> > -	{ 0x00006012, 0x00000087 },
> > -	{ 0x00000018, 0x000000df },
> > -	{ 0x00003015, 0x00000087 },
> > -	{ 0x00003015, 0x000000c7 },
> > -	{ 0x00000018, 0x000000c7 },
> > +	{ 0x00000018, 0x000000AC, 0x0 },
> > +	{ 0x00005012, 0x0000009D, 0x0 },
> > +	{ 0x00007011, 0x00000088, 0x0 },
> > +	{ 0x00000018, 0x000000A1, 0x0 },
> > +	{ 0x00000018, 0x00000098, 0x0 },
> > +	{ 0x00004013, 0x00000088, 0x0 },
> > +	{ 0x00006012, 0x00000087, 0x0 },
> > +	{ 0x00000018, 0x000000DF, 0x0 },
> > +	{ 0x00003015, 0x00000087, 0x0 },	/* Default */
> > +	{ 0x00003015, 0x000000C7, 0x0 },
> > +	{ 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 {
> > @@ -190,7 +270,7 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
> >  	{ 154, 0x9A, 0, 64,  false },	/* 6:	600		6   */
> >  	{ 102, 0x9A, 0, 128, false },	/* 7:	800		0   */
> >  	{ 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.
> > @@ -210,6 +290,9 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
> >  	{ 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,
> >  				 struct intel_digital_port **dig_port,
> >  				 enum port *port)
> > @@ -249,6 +332,99 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
> >  	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
> >   * values in advance. The buffer values are different for FDI and DP modes,
> > @@ -279,20 +455,13 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
> >  					INTEL_OUTPUT_HDMI);
> >  		return;
> >  	} else if (IS_SKYLAKE(dev)) {
> > -		ddi_translations_fdi = NULL;
> > -		ddi_translations_dp = skl_ddi_translations_dp;
> > -		n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
> > -		if (dev_priv->edp_low_vswing) {
> > -			ddi_translations_edp = skl_ddi_translations_edp;
> > -			n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp);
> > -		} else {
> > -			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;
> > +		ddi_translations_dp =
> > +				skl_get_buf_trans_dp(dev, &n_dp_entries);
> > +		ddi_translations_edp =
> > +				skl_get_buf_trans_edp(dev, &n_edp_entries);
> > +		ddi_translations_hdmi =
> > +				skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
> > +		hdmi_default_entry = 8;
> >  	} else if (IS_BROADWELL(dev)) {
> >  		ddi_translations_fdi = bdw_ddi_translations_fdi;
> >  		ddi_translations_dp = bdw_ddi_translations_dp;
> > @@ -1806,8 +1975,49 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
> >  			   TRANS_CLK_SEL_DISABLED);
> >  }
> >  
> > -void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
> > -			     enum port port, int type)
> > +static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
> > +			       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;
> >  	const struct bxt_ddi_buf_trans *ddi_translations;
> > @@ -1867,6 +2077,73 @@ void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
> >  	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)
> >  {
> >  	struct drm_encoder *encoder = &intel_encoder->base;
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index f52eef138247..041e2d6dcc56 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -3417,92 +3417,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. */
> >  static void
> >  intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
> > @@ -3510,22 +3424,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);
> >  	enum port port = intel_dig_port->port;
> >  	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];
> >  
> > -	if (IS_BROXTON(dev)) {
> > -		signal_levels = 0;
> > -		bxt_signal_levels(intel_dp);
> > -		mask = 0;
> > -	} else if (HAS_DDI(dev)) {
> > -		signal_levels = hsw_signal_levels(train_set);
> > -		mask = DDI_BUF_EMP_MASK;
> > +	if (HAS_DDI(dev)) {
> > +		signal_levels = ddi_signal_levels(intel_dp);
> > +
> > +		if (IS_BROXTON(dev))
> > +			signal_levels = 0;
> > +		else
> > +			mask = DDI_BUF_EMP_MASK;
> >  	} else if (IS_CHERRYVIEW(dev)) {
> >  		signal_levels = chv_signal_levels(intel_dp);
> > -		mask = 0;
> >  	} else if (IS_VALLEYVIEW(dev)) {
> >  		signal_levels = vlv_signal_levels(intel_dp);
> > -		mask = 0;
> >  	} else if (IS_GEN7(dev) && port == PORT_A) {
> >  		signal_levels = gen7_edp_signal_levels(train_set);
> >  		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index bcafefcf048b..c6cbe8c602f9 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -950,8 +950,7 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
> >  void intel_ddi_clock_get(struct intel_encoder *encoder,
> >  			 struct intel_crtc_state *pipe_config);
> >  void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
> > -void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
> > -				enum port port, int type);
> > +uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
> >  
> >  /* intel_frontbuffer.c */
> >  void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
> > 
> 
> -- 
> - Antti
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2] drm/i915/skl: Buffer translation improvements
  2015-06-29 16:12     ` Daniel Vetter
@ 2015-06-30 10:27       ` David Weinehall
  0 siblings, 0 replies; 16+ messages in thread
From: David Weinehall @ 2015-06-30 10:27 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Mon, Jun 29, 2015 at 06:12:54PM +0200, Daniel Vetter wrote:
> On Mon, Jun 29, 2015 at 01:35:06PM +0300, Antti Koskipää wrote:
> > Looks fine to me.
> > 
> > Reviewed-by: Antti Koskipää <antti.koskipaa@linux.intel.com>
> > 
> > 
> > On 06/25/2015 11:11 AM, David Weinehall wrote:
> > > 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
> 
> For next time around please split out refactoring from actual code
> changes, makes it a pain to review. And if this blows up in a
> regression that's really annoying. Also please head checkpatch's
> suggestions a bit more, I fixed that up when applying.

OK, noted.


Kind regards, David
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2015-06-30 10:27 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-18  9:50 [PATCH] drm/i915/skl: Buffer translation improvements David Weinehall
2015-06-18 10:10 ` Chris Wilson
2015-06-18 10:47   ` David Weinehall
2015-06-18 10:59     ` Chris Wilson
2015-06-23 10:28       ` David Weinehall
2015-06-25  8:09   ` David Weinehall
2015-06-18 15:05 ` Daniel Vetter
2015-06-23 10:47   ` David Weinehall
2015-06-23 11:12   ` David Weinehall
2015-06-23 12:07     ` Daniel Vetter
2015-06-24  4:47     ` Jindal, Sonika
2015-06-25 10:18       ` David Weinehall
2015-06-25  8:11 ` [PATCH v2] " David Weinehall
2015-06-29 10:35   ` Antti Koskipää
2015-06-29 16:12     ` Daniel Vetter
2015-06-30 10:27       ` David Weinehall

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.