Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40d201af authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-2014-09-05' of git://anongit.freedesktop.org/drm-intel into drm-next

- final bits (again) for the rotation support (Sonika Jindal)
- support bl_power in the intel backlight (Jani)
- vdd handling improvements from Ville
- i830M fixes from Ville
- piles of prep work all over to make skl enabling just plug in (Damien, Sonika)
- rename DP training defines to reflect latest edp standards, this touches all
  drm drivers supporting DP (Sonika Jindal)
- cache edids during single detect cycle to avoid re-reading it for e.g. audio,
  from Chris
- move w/a for registers which are stored in the hw context to the context init
  code (Arun&Damien)
- edp panel power sequencer fixes, helps chv a lot (Ville)
- piles of other chv fixes all over
- much more paranoid pageflip handling with stall detection and better recovery
  from Chris
- small things all over, as usual

* tag 'drm-intel-next-2014-09-05' of git://anongit.freedesktop.org/drm-intel: (114 commits)
  drm/i915: Update DRIVER_DATE to 20140905
  drm/i915: Decouple the stuck pageflip on modeset
  drm/i915: Check for a stalled page flip after each vblank
  drm/i915: Introduce a for_each_plane() macro
  drm/i915: Rewrite ABS_DIFF() in a safer manner
  drm/i915: Add comments explaining the vdd on/off functions
  drm/i915: Move DP port disable to post_disable for pch platforms
  drm/i915: Enable DP port earlier
  drm/i915: Turn on panel power before doing aux transfers
  drm/i915: Be more careful when picking the initial power sequencer pipe
  drm/i915: Reset power sequencer pipe tracking when disp2d is off
  drm/i915: Track which port is using which pipe's power sequencer
  drm/i915: Fix edp vdd locking
  drm/i915: Reset the HEAD pointer for the ring after writing START
  drm/i915: Fix unsafe vma iteration in i915_drop_caches
  drm/i915: init sprites with univeral plane init function
  drm/i915: Check of !HAS_PCH_SPLIT() in PCH transcoder funcs
  drm/i915: Use HAS_GMCH_DISPLAY un underrun reporting code
  drm/i915: Use IS_BROADWELL() instead of IS_GEN8() in forcewake code
  drm/i915: Don't call gen8_fbc_sw_flush() on chv
  ...
parents 29a7d179 a1262495
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3091,7 +3091,7 @@ F: include/drm/drm_panel.h
F:	Documentation/devicetree/bindings/panel/

INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
M:	Daniel Vetter <daniel.vetter@ffwll.ch>
M:	Daniel Vetter <daniel.vetter@intel.com>
M:	Jani Nikula <jani.nikula@linux.intel.com>
L:	intel-gfx@lists.freedesktop.org
L:	dri-devel@lists.freedesktop.org
+2 −2
Original line number Diff line number Diff line
@@ -329,8 +329,8 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
		return retval;

	for (lane = 0; lane < lane_count; lane++)
		buf[lane] = DP_TRAIN_PRE_EMPHASIS_0 |
			    DP_TRAIN_VOLTAGE_SWING_400;
		buf[lane] = DP_TRAIN_PRE_EMPH_LEVEL_0 |
			    DP_TRAIN_VOLTAGE_SWING_LEVEL_0;

	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
			lane_count, buf);
+2 −2
Original line number Diff line number Diff line
@@ -1089,7 +1089,7 @@ static char *link_train_names[] = {
};
#endif

#define CDV_DP_VOLTAGE_MAX	    DP_TRAIN_VOLTAGE_SWING_1200
#define CDV_DP_VOLTAGE_MAX	    DP_TRAIN_VOLTAGE_SWING_LEVEL_3
/*
static uint8_t
cdv_intel_dp_pre_emphasis_max(uint8_t voltage_swing)
@@ -1276,7 +1276,7 @@ cdv_intel_dp_set_vswing_premph(struct gma_encoder *encoder, uint8_t signal_level
		cdv_sb_write(dev, ddi_reg->VSwing2, dp_vswing_premph_table[index]);

	/* ;gfx_dpio_set_reg(0x814c, 0x40802040) */
	if ((vswing + premph) == DP_TRAIN_VOLTAGE_SWING_1200)
	if ((vswing + premph) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
		cdv_sb_write(dev, ddi_reg->VSwing3, 0x70802040);
	else
		cdv_sb_write(dev, ddi_reg->VSwing3, 0x40802040);
+8 −8
Original line number Diff line number Diff line
@@ -116,30 +116,30 @@ parse_edp(struct drm_psb_private *dev_priv, struct bdb_header *bdb)

	switch (edp_link_params->preemphasis) {
	case 0:
		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0;
		break;
	case 1:
		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1;
		break;
	case 2:
		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2;
		break;
	case 3:
		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3;
		break;
	}
	switch (edp_link_params->vswing) {
	case 0:
		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400;
		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
		break;
	case 1:
		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600;
		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1;
		break;
	case 2:
		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800;
		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
		break;
	case 3:
		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200;
		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
		break;
	}
	DRM_DEBUG_KMS("VBT reports EDP: VSwing  %d, Preemph %d\n",
+337 −223
Original line number Diff line number Diff line
@@ -60,16 +60,297 @@

#define NS2501_REGC 0x0c

enum {
	MODE_640x480,
	MODE_800x600,
	MODE_1024x768,
};

struct ns2501_reg {
	 uint8_t offset;
	 uint8_t value;
};

/*
 * Magic values based on what the BIOS on
 * Fujitsu-Siemens Lifebook S6010 programs (1024x768 panel).
 */
static const struct ns2501_reg regs_1024x768[][86] = {
	[MODE_640x480] = {
		[0] = { .offset = 0x0a, .value = 0x81, },
		[1] = { .offset = 0x18, .value = 0x07, },
		[2] = { .offset = 0x19, .value = 0x00, },
		[3] = { .offset = 0x1a, .value = 0x00, },
		[4] = { .offset = 0x1b, .value = 0x11, },
		[5] = { .offset = 0x1c, .value = 0x54, },
		[6] = { .offset = 0x1d, .value = 0x03, },
		[7] = { .offset = 0x1e, .value = 0x02, },
		[8] = { .offset = 0xf3, .value = 0x90, },
		[9] = { .offset = 0xf9, .value = 0x00, },
		[10] = { .offset = 0xc1, .value = 0x90, },
		[11] = { .offset = 0xc2, .value = 0x00, },
		[12] = { .offset = 0xc3, .value = 0x0f, },
		[13] = { .offset = 0xc4, .value = 0x03, },
		[14] = { .offset = 0xc5, .value = 0x16, },
		[15] = { .offset = 0xc6, .value = 0x00, },
		[16] = { .offset = 0xc7, .value = 0x02, },
		[17] = { .offset = 0xc8, .value = 0x02, },
		[18] = { .offset = 0xf4, .value = 0x00, },
		[19] = { .offset = 0x80, .value = 0xff, },
		[20] = { .offset = 0x81, .value = 0x07, },
		[21] = { .offset = 0x82, .value = 0x3d, },
		[22] = { .offset = 0x83, .value = 0x05, },
		[23] = { .offset = 0x94, .value = 0x00, },
		[24] = { .offset = 0x95, .value = 0x00, },
		[25] = { .offset = 0x96, .value = 0x05, },
		[26] = { .offset = 0x97, .value = 0x00, },
		[27] = { .offset = 0x9a, .value = 0x88, },
		[28] = { .offset = 0x9b, .value = 0x00, },
		[29] = { .offset = 0x98, .value = 0x00, },
		[30] = { .offset = 0x99, .value = 0x00, },
		[31] = { .offset = 0xf7, .value = 0x88, },
		[32] = { .offset = 0xf8, .value = 0x0a, },
		[33] = { .offset = 0x9c, .value = 0x24, },
		[34] = { .offset = 0x9d, .value = 0x00, },
		[35] = { .offset = 0x9e, .value = 0x25, },
		[36] = { .offset = 0x9f, .value = 0x03, },
		[37] = { .offset = 0xa0, .value = 0x28, },
		[38] = { .offset = 0xa1, .value = 0x01, },
		[39] = { .offset = 0xa2, .value = 0x28, },
		[40] = { .offset = 0xa3, .value = 0x05, },
		[41] = { .offset = 0xb6, .value = 0x09, },
		[42] = { .offset = 0xb8, .value = 0x00, },
		[43] = { .offset = 0xb9, .value = 0xa0, },
		[44] = { .offset = 0xba, .value = 0x00, },
		[45] = { .offset = 0xbb, .value = 0x20, },
		[46] = { .offset = 0x10, .value = 0x00, },
		[47] = { .offset = 0x11, .value = 0xa0, },
		[48] = { .offset = 0x12, .value = 0x02, },
		[49] = { .offset = 0x20, .value = 0x00, },
		[50] = { .offset = 0x22, .value = 0x00, },
		[51] = { .offset = 0x23, .value = 0x00, },
		[52] = { .offset = 0x24, .value = 0x00, },
		[53] = { .offset = 0x25, .value = 0x00, },
		[54] = { .offset = 0x8c, .value = 0x10, },
		[55] = { .offset = 0x8d, .value = 0x02, },
		[56] = { .offset = 0x8e, .value = 0x10, },
		[57] = { .offset = 0x8f, .value = 0x00, },
		[58] = { .offset = 0x90, .value = 0xff, },
		[59] = { .offset = 0x91, .value = 0x07, },
		[60] = { .offset = 0x92, .value = 0xa0, },
		[61] = { .offset = 0x93, .value = 0x02, },
		[62] = { .offset = 0xa5, .value = 0x00, },
		[63] = { .offset = 0xa6, .value = 0x00, },
		[64] = { .offset = 0xa7, .value = 0x00, },
		[65] = { .offset = 0xa8, .value = 0x00, },
		[66] = { .offset = 0xa9, .value = 0x04, },
		[67] = { .offset = 0xaa, .value = 0x70, },
		[68] = { .offset = 0xab, .value = 0x4f, },
		[69] = { .offset = 0xac, .value = 0x00, },
		[70] = { .offset = 0xa4, .value = 0x84, },
		[71] = { .offset = 0x7e, .value = 0x18, },
		[72] = { .offset = 0x84, .value = 0x00, },
		[73] = { .offset = 0x85, .value = 0x00, },
		[74] = { .offset = 0x86, .value = 0x00, },
		[75] = { .offset = 0x87, .value = 0x00, },
		[76] = { .offset = 0x88, .value = 0x00, },
		[77] = { .offset = 0x89, .value = 0x00, },
		[78] = { .offset = 0x8a, .value = 0x00, },
		[79] = { .offset = 0x8b, .value = 0x00, },
		[80] = { .offset = 0x26, .value = 0x00, },
		[81] = { .offset = 0x27, .value = 0x00, },
		[82] = { .offset = 0xad, .value = 0x00, },
		[83] = { .offset = 0x08, .value = 0x30, }, /* 0x31 */
		[84] = { .offset = 0x41, .value = 0x00, },
		[85] = { .offset = 0xc0, .value = 0x05, },
	},
	[MODE_800x600] = {
		[0] = { .offset = 0x0a, .value = 0x81, },
		[1] = { .offset = 0x18, .value = 0x07, },
		[2] = { .offset = 0x19, .value = 0x00, },
		[3] = { .offset = 0x1a, .value = 0x00, },
		[4] = { .offset = 0x1b, .value = 0x19, },
		[5] = { .offset = 0x1c, .value = 0x64, },
		[6] = { .offset = 0x1d, .value = 0x02, },
		[7] = { .offset = 0x1e, .value = 0x02, },
		[8] = { .offset = 0xf3, .value = 0x90, },
		[9] = { .offset = 0xf9, .value = 0x00, },
		[10] = { .offset = 0xc1, .value = 0xd7, },
		[11] = { .offset = 0xc2, .value = 0x00, },
		[12] = { .offset = 0xc3, .value = 0xf8, },
		[13] = { .offset = 0xc4, .value = 0x03, },
		[14] = { .offset = 0xc5, .value = 0x1a, },
		[15] = { .offset = 0xc6, .value = 0x00, },
		[16] = { .offset = 0xc7, .value = 0x73, },
		[17] = { .offset = 0xc8, .value = 0x02, },
		[18] = { .offset = 0xf4, .value = 0x00, },
		[19] = { .offset = 0x80, .value = 0x27, },
		[20] = { .offset = 0x81, .value = 0x03, },
		[21] = { .offset = 0x82, .value = 0x41, },
		[22] = { .offset = 0x83, .value = 0x05, },
		[23] = { .offset = 0x94, .value = 0x00, },
		[24] = { .offset = 0x95, .value = 0x00, },
		[25] = { .offset = 0x96, .value = 0x05, },
		[26] = { .offset = 0x97, .value = 0x00, },
		[27] = { .offset = 0x9a, .value = 0x88, },
		[28] = { .offset = 0x9b, .value = 0x00, },
		[29] = { .offset = 0x98, .value = 0x00, },
		[30] = { .offset = 0x99, .value = 0x00, },
		[31] = { .offset = 0xf7, .value = 0x88, },
		[32] = { .offset = 0xf8, .value = 0x06, },
		[33] = { .offset = 0x9c, .value = 0x23, },
		[34] = { .offset = 0x9d, .value = 0x00, },
		[35] = { .offset = 0x9e, .value = 0x25, },
		[36] = { .offset = 0x9f, .value = 0x03, },
		[37] = { .offset = 0xa0, .value = 0x28, },
		[38] = { .offset = 0xa1, .value = 0x01, },
		[39] = { .offset = 0xa2, .value = 0x28, },
		[40] = { .offset = 0xa3, .value = 0x05, },
		[41] = { .offset = 0xb6, .value = 0x09, },
		[42] = { .offset = 0xb8, .value = 0x30, },
		[43] = { .offset = 0xb9, .value = 0xc8, },
		[44] = { .offset = 0xba, .value = 0x00, },
		[45] = { .offset = 0xbb, .value = 0x20, },
		[46] = { .offset = 0x10, .value = 0x20, },
		[47] = { .offset = 0x11, .value = 0xc8, },
		[48] = { .offset = 0x12, .value = 0x02, },
		[49] = { .offset = 0x20, .value = 0x00, },
		[50] = { .offset = 0x22, .value = 0x00, },
		[51] = { .offset = 0x23, .value = 0x00, },
		[52] = { .offset = 0x24, .value = 0x00, },
		[53] = { .offset = 0x25, .value = 0x00, },
		[54] = { .offset = 0x8c, .value = 0x10, },
		[55] = { .offset = 0x8d, .value = 0x02, },
		[56] = { .offset = 0x8e, .value = 0x04, },
		[57] = { .offset = 0x8f, .value = 0x00, },
		[58] = { .offset = 0x90, .value = 0xff, },
		[59] = { .offset = 0x91, .value = 0x07, },
		[60] = { .offset = 0x92, .value = 0xa0, },
		[61] = { .offset = 0x93, .value = 0x02, },
		[62] = { .offset = 0xa5, .value = 0x00, },
		[63] = { .offset = 0xa6, .value = 0x00, },
		[64] = { .offset = 0xa7, .value = 0x00, },
		[65] = { .offset = 0xa8, .value = 0x00, },
		[66] = { .offset = 0xa9, .value = 0x83, },
		[67] = { .offset = 0xaa, .value = 0x40, },
		[68] = { .offset = 0xab, .value = 0x32, },
		[69] = { .offset = 0xac, .value = 0x00, },
		[70] = { .offset = 0xa4, .value = 0x80, },
		[71] = { .offset = 0x7e, .value = 0x18, },
		[72] = { .offset = 0x84, .value = 0x00, },
		[73] = { .offset = 0x85, .value = 0x00, },
		[74] = { .offset = 0x86, .value = 0x00, },
		[75] = { .offset = 0x87, .value = 0x00, },
		[76] = { .offset = 0x88, .value = 0x00, },
		[77] = { .offset = 0x89, .value = 0x00, },
		[78] = { .offset = 0x8a, .value = 0x00, },
		[79] = { .offset = 0x8b, .value = 0x00, },
		[80] = { .offset = 0x26, .value = 0x00, },
		[81] = { .offset = 0x27, .value = 0x00, },
		[82] = { .offset = 0xad, .value = 0x00, },
		[83] = { .offset = 0x08, .value = 0x30, }, /* 0x31 */
		[84] = { .offset = 0x41, .value = 0x00, },
		[85] = { .offset = 0xc0, .value = 0x07, },
	},
	[MODE_1024x768] = {
		[0] = { .offset = 0x0a, .value = 0x81, },
		[1] = { .offset = 0x18, .value = 0x07, },
		[2] = { .offset = 0x19, .value = 0x00, },
		[3] = { .offset = 0x1a, .value = 0x00, },
		[4] = { .offset = 0x1b, .value = 0x11, },
		[5] = { .offset = 0x1c, .value = 0x54, },
		[6] = { .offset = 0x1d, .value = 0x03, },
		[7] = { .offset = 0x1e, .value = 0x02, },
		[8] = { .offset = 0xf3, .value = 0x90, },
		[9] = { .offset = 0xf9, .value = 0x00, },
		[10] = { .offset = 0xc1, .value = 0x90, },
		[11] = { .offset = 0xc2, .value = 0x00, },
		[12] = { .offset = 0xc3, .value = 0x0f, },
		[13] = { .offset = 0xc4, .value = 0x03, },
		[14] = { .offset = 0xc5, .value = 0x16, },
		[15] = { .offset = 0xc6, .value = 0x00, },
		[16] = { .offset = 0xc7, .value = 0x02, },
		[17] = { .offset = 0xc8, .value = 0x02, },
		[18] = { .offset = 0xf4, .value = 0x00, },
		[19] = { .offset = 0x80, .value = 0xff, },
		[20] = { .offset = 0x81, .value = 0x07, },
		[21] = { .offset = 0x82, .value = 0x3d, },
		[22] = { .offset = 0x83, .value = 0x05, },
		[23] = { .offset = 0x94, .value = 0x00, },
		[24] = { .offset = 0x95, .value = 0x00, },
		[25] = { .offset = 0x96, .value = 0x05, },
		[26] = { .offset = 0x97, .value = 0x00, },
		[27] = { .offset = 0x9a, .value = 0x88, },
		[28] = { .offset = 0x9b, .value = 0x00, },
		[29] = { .offset = 0x98, .value = 0x00, },
		[30] = { .offset = 0x99, .value = 0x00, },
		[31] = { .offset = 0xf7, .value = 0x88, },
		[32] = { .offset = 0xf8, .value = 0x0a, },
		[33] = { .offset = 0x9c, .value = 0x24, },
		[34] = { .offset = 0x9d, .value = 0x00, },
		[35] = { .offset = 0x9e, .value = 0x25, },
		[36] = { .offset = 0x9f, .value = 0x03, },
		[37] = { .offset = 0xa0, .value = 0x28, },
		[38] = { .offset = 0xa1, .value = 0x01, },
		[39] = { .offset = 0xa2, .value = 0x28, },
		[40] = { .offset = 0xa3, .value = 0x05, },
		[41] = { .offset = 0xb6, .value = 0x09, },
		[42] = { .offset = 0xb8, .value = 0x00, },
		[43] = { .offset = 0xb9, .value = 0xa0, },
		[44] = { .offset = 0xba, .value = 0x00, },
		[45] = { .offset = 0xbb, .value = 0x20, },
		[46] = { .offset = 0x10, .value = 0x00, },
		[47] = { .offset = 0x11, .value = 0xa0, },
		[48] = { .offset = 0x12, .value = 0x02, },
		[49] = { .offset = 0x20, .value = 0x00, },
		[50] = { .offset = 0x22, .value = 0x00, },
		[51] = { .offset = 0x23, .value = 0x00, },
		[52] = { .offset = 0x24, .value = 0x00, },
		[53] = { .offset = 0x25, .value = 0x00, },
		[54] = { .offset = 0x8c, .value = 0x10, },
		[55] = { .offset = 0x8d, .value = 0x02, },
		[56] = { .offset = 0x8e, .value = 0x10, },
		[57] = { .offset = 0x8f, .value = 0x00, },
		[58] = { .offset = 0x90, .value = 0xff, },
		[59] = { .offset = 0x91, .value = 0x07, },
		[60] = { .offset = 0x92, .value = 0xa0, },
		[61] = { .offset = 0x93, .value = 0x02, },
		[62] = { .offset = 0xa5, .value = 0x00, },
		[63] = { .offset = 0xa6, .value = 0x00, },
		[64] = { .offset = 0xa7, .value = 0x00, },
		[65] = { .offset = 0xa8, .value = 0x00, },
		[66] = { .offset = 0xa9, .value = 0x04, },
		[67] = { .offset = 0xaa, .value = 0x70, },
		[68] = { .offset = 0xab, .value = 0x4f, },
		[69] = { .offset = 0xac, .value = 0x00, },
		[70] = { .offset = 0xa4, .value = 0x84, },
		[71] = { .offset = 0x7e, .value = 0x18, },
		[72] = { .offset = 0x84, .value = 0x00, },
		[73] = { .offset = 0x85, .value = 0x00, },
		[74] = { .offset = 0x86, .value = 0x00, },
		[75] = { .offset = 0x87, .value = 0x00, },
		[76] = { .offset = 0x88, .value = 0x00, },
		[77] = { .offset = 0x89, .value = 0x00, },
		[78] = { .offset = 0x8a, .value = 0x00, },
		[79] = { .offset = 0x8b, .value = 0x00, },
		[80] = { .offset = 0x26, .value = 0x00, },
		[81] = { .offset = 0x27, .value = 0x00, },
		[82] = { .offset = 0xad, .value = 0x00, },
		[83] = { .offset = 0x08, .value = 0x34, }, /* 0x35 */
		[84] = { .offset = 0x41, .value = 0x00, },
		[85] = { .offset = 0xc0, .value = 0x01, },
	},
};

static const struct ns2501_reg regs_init[] = {
	[0] = { .offset = 0x35, .value = 0xff, },
	[1] = { .offset = 0x34, .value = 0x00, },
	[2] = { .offset = 0x08, .value = 0x30, },
};

struct ns2501_priv {
	//I2CDevRec d;
	bool quiet;
	int reg_8_shadow;
	int reg_8_set;
	// Shadow registers for i915
	int dvoc;
	int pll_a;
	int srcdim;
	int fw_blc;
	const struct ns2501_reg *regs;
};

#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
@@ -205,11 +486,9 @@ static bool ns2501_init(struct intel_dvo_device *dvo,
		goto out;
	}
	ns->quiet = false;
	ns->reg_8_set = 0;
	ns->reg_8_shadow =
	    NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN | NS2501_8_HEN;

	DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n");

	return true;

out:
@@ -242,9 +521,9 @@ static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
	 * of the panel in here so we could always accept it
	 * by disabling the scaler.
	 */
	if ((mode->hdisplay == 800 && mode->vdisplay == 600) ||
	    (mode->hdisplay == 640 && mode->vdisplay == 480) ||
	    (mode->hdisplay == 1024 && mode->vdisplay == 768)) {
	if ((mode->hdisplay == 640 && mode->vdisplay == 480 && mode->clock == 25175) ||
	    (mode->hdisplay == 800 && mode->vdisplay == 600 && mode->clock == 40000) ||
	    (mode->hdisplay == 1024 && mode->vdisplay == 768 && mode->clock == 65000)) {
		return MODE_OK;
	} else {
		return MODE_ONE_SIZE;	/* Is this a reasonable error? */
@@ -255,180 +534,30 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
			    struct drm_display_mode *mode,
			    struct drm_display_mode *adjusted_mode)
{
	bool ok;
	int retries = 10;
	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
	int mode_idx, i;

	DRM_DEBUG_KMS
	    ("set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
	     mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);

	/*
	 * Where do I find the native resolution for which scaling is not required???
	 *
	 * First trigger the DVO on as otherwise the chip does not appear on the i2c
	 * bus.
	 */
	do {
		ok = true;

		if (mode->hdisplay == 800 && mode->vdisplay == 600) {
			/* mode 277 */
			ns->reg_8_shadow &= ~NS2501_8_BPAS;
			DRM_DEBUG_KMS("switching to 800x600\n");

			/*
			 * No, I do not know where this data comes from.
			 * It is just what the video bios left in the DVO, so
			 * I'm just copying it here over.
			 * This also means that I cannot support any other modes
			 * except the ones supported by the bios.
			 */
			ok &= ns2501_writeb(dvo, 0x11, 0xc8);	// 0xc7 also works.
			ok &= ns2501_writeb(dvo, 0x1b, 0x19);
			ok &= ns2501_writeb(dvo, 0x1c, 0x62);	// VBIOS left 0x64 here, but 0x62 works nicer
			ok &= ns2501_writeb(dvo, 0x1d, 0x02);

			ok &= ns2501_writeb(dvo, 0x34, 0x03);
			ok &= ns2501_writeb(dvo, 0x35, 0xff);

			ok &= ns2501_writeb(dvo, 0x80, 0x27);
			ok &= ns2501_writeb(dvo, 0x81, 0x03);
			ok &= ns2501_writeb(dvo, 0x82, 0x41);
			ok &= ns2501_writeb(dvo, 0x83, 0x05);

			ok &= ns2501_writeb(dvo, 0x8d, 0x02);
			ok &= ns2501_writeb(dvo, 0x8e, 0x04);
			ok &= ns2501_writeb(dvo, 0x8f, 0x00);

			ok &= ns2501_writeb(dvo, 0x90, 0xfe);	/* vertical. VBIOS left 0xff here, but 0xfe works better */
			ok &= ns2501_writeb(dvo, 0x91, 0x07);
			ok &= ns2501_writeb(dvo, 0x94, 0x00);
			ok &= ns2501_writeb(dvo, 0x95, 0x00);

			ok &= ns2501_writeb(dvo, 0x96, 0x00);

			ok &= ns2501_writeb(dvo, 0x99, 0x00);
			ok &= ns2501_writeb(dvo, 0x9a, 0x88);

			ok &= ns2501_writeb(dvo, 0x9c, 0x23);	/* Looks like first and last line of the image. */
			ok &= ns2501_writeb(dvo, 0x9d, 0x00);
			ok &= ns2501_writeb(dvo, 0x9e, 0x25);
			ok &= ns2501_writeb(dvo, 0x9f, 0x03);

			ok &= ns2501_writeb(dvo, 0xa4, 0x80);

			ok &= ns2501_writeb(dvo, 0xb6, 0x00);

			ok &= ns2501_writeb(dvo, 0xb9, 0xc8);	/* horizontal? */
			ok &= ns2501_writeb(dvo, 0xba, 0x00);	/* horizontal? */

			ok &= ns2501_writeb(dvo, 0xc0, 0x05);	/* horizontal? */
			ok &= ns2501_writeb(dvo, 0xc1, 0xd7);

			ok &= ns2501_writeb(dvo, 0xc2, 0x00);
			ok &= ns2501_writeb(dvo, 0xc3, 0xf8);

			ok &= ns2501_writeb(dvo, 0xc4, 0x03);
			ok &= ns2501_writeb(dvo, 0xc5, 0x1a);

			ok &= ns2501_writeb(dvo, 0xc6, 0x00);
			ok &= ns2501_writeb(dvo, 0xc7, 0x73);
			ok &= ns2501_writeb(dvo, 0xc8, 0x02);

		} else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
			/* mode 274 */
			DRM_DEBUG_KMS("switching to 640x480\n");
			/*
			 * No, I do not know where this data comes from.
			 * It is just what the video bios left in the DVO, so
			 * I'm just copying it here over.
			 * This also means that I cannot support any other modes
			 * except the ones supported by the bios.
			 */
			ns->reg_8_shadow &= ~NS2501_8_BPAS;

			ok &= ns2501_writeb(dvo, 0x11, 0xa0);
			ok &= ns2501_writeb(dvo, 0x1b, 0x11);
			ok &= ns2501_writeb(dvo, 0x1c, 0x54);
			ok &= ns2501_writeb(dvo, 0x1d, 0x03);

			ok &= ns2501_writeb(dvo, 0x34, 0x03);
			ok &= ns2501_writeb(dvo, 0x35, 0xff);

			ok &= ns2501_writeb(dvo, 0x80, 0xff);
			ok &= ns2501_writeb(dvo, 0x81, 0x07);
			ok &= ns2501_writeb(dvo, 0x82, 0x3d);
			ok &= ns2501_writeb(dvo, 0x83, 0x05);

			ok &= ns2501_writeb(dvo, 0x8d, 0x02);
			ok &= ns2501_writeb(dvo, 0x8e, 0x10);
			ok &= ns2501_writeb(dvo, 0x8f, 0x00);

			ok &= ns2501_writeb(dvo, 0x90, 0xff);	/* vertical */
			ok &= ns2501_writeb(dvo, 0x91, 0x07);
			ok &= ns2501_writeb(dvo, 0x94, 0x00);
			ok &= ns2501_writeb(dvo, 0x95, 0x00);

			ok &= ns2501_writeb(dvo, 0x96, 0x05);

			ok &= ns2501_writeb(dvo, 0x99, 0x00);
			ok &= ns2501_writeb(dvo, 0x9a, 0x88);

			ok &= ns2501_writeb(dvo, 0x9c, 0x24);
			ok &= ns2501_writeb(dvo, 0x9d, 0x00);
			ok &= ns2501_writeb(dvo, 0x9e, 0x25);
			ok &= ns2501_writeb(dvo, 0x9f, 0x03);

			ok &= ns2501_writeb(dvo, 0xa4, 0x84);

			ok &= ns2501_writeb(dvo, 0xb6, 0x09);

			ok &= ns2501_writeb(dvo, 0xb9, 0xa0);	/* horizontal? */
			ok &= ns2501_writeb(dvo, 0xba, 0x00);	/* horizontal? */

			ok &= ns2501_writeb(dvo, 0xc0, 0x05);	/* horizontal? */
			ok &= ns2501_writeb(dvo, 0xc1, 0x90);

			ok &= ns2501_writeb(dvo, 0xc2, 0x00);
			ok &= ns2501_writeb(dvo, 0xc3, 0x0f);
	if (mode->hdisplay == 640 && mode->vdisplay == 480)
		mode_idx = MODE_640x480;
	else if (mode->hdisplay == 800 && mode->vdisplay == 600)
		mode_idx = MODE_800x600;
	else if (mode->hdisplay == 1024 && mode->vdisplay == 768)
		mode_idx = MODE_1024x768;
	else
		return;

			ok &= ns2501_writeb(dvo, 0xc4, 0x03);
			ok &= ns2501_writeb(dvo, 0xc5, 0x16);
	/* Hopefully doing it every time won't hurt... */
	for (i = 0; i < ARRAY_SIZE(regs_init); i++)
		ns2501_writeb(dvo, regs_init[i].offset, regs_init[i].value);

			ok &= ns2501_writeb(dvo, 0xc6, 0x00);
			ok &= ns2501_writeb(dvo, 0xc7, 0x02);
			ok &= ns2501_writeb(dvo, 0xc8, 0x02);
	ns->regs = regs_1024x768[mode_idx];

		} else if (mode->hdisplay == 1024 && mode->vdisplay == 768) {
			/* mode 280 */
			DRM_DEBUG_KMS("switching to 1024x768\n");
			/*
			 * This might or might not work, actually. I'm silently
			 * assuming here that the native panel resolution is
			 * 1024x768. If not, then this leaves the scaler disabled
			 * generating a picture that is likely not the expected.
			 *
			 * Problem is that I do not know where to take the panel
			 * dimensions from.
			 *
			 * Enable the bypass, scaling not required.
			 *
			 * The scaler registers are irrelevant here....
			 *
			 */
			ns->reg_8_shadow |= NS2501_8_BPAS;
			ok &= ns2501_writeb(dvo, 0x37, 0x44);
		} else {
			/*
			 * Data not known. Bummer!
			 * Hopefully, the code should not go here
			 * as mode_OK delivered no other modes.
			 */
			ns->reg_8_shadow |= NS2501_8_BPAS;
		}
		ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow);
	} while (!ok && retries--);
	for (i = 0; i < 84; i++)
		ns2501_writeb(dvo, ns->regs[i].offset, ns->regs[i].value);
}

/* set the NS2501 power state */
@@ -439,60 +568,46 @@ static bool ns2501_get_hw_state(struct intel_dvo_device *dvo)
	if (!ns2501_readb(dvo, NS2501_REG8, &ch))
		return false;

	if (ch & NS2501_8_PD)
		return true;
	else
		return false;
	return ch & NS2501_8_PD;
}

/* set the NS2501 power state */
static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
{
	bool ok;
	int retries = 10;
	struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
	unsigned char ch;

	DRM_DEBUG_KMS("Trying set the dpms of the DVO to %i\n", enable);

	ch = ns->reg_8_shadow;
	if (enable) {
		if (WARN_ON(ns->regs[83].offset != 0x08 ||
			    ns->regs[84].offset != 0x41 ||
			    ns->regs[85].offset != 0xc0))
			return;

	if (enable)
		ch |= NS2501_8_PD;
	else
		ch &= ~NS2501_8_PD;

	if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) {
		ns->reg_8_set = 1;
		ns->reg_8_shadow = ch;

		do {
			ok = true;
			ok &= ns2501_writeb(dvo, NS2501_REG8, ch);
			ok &=
			    ns2501_writeb(dvo, 0x34,
					  enable ? 0x03 : 0x00);
			ok &=
			    ns2501_writeb(dvo, 0x35,
					  enable ? 0xff : 0x00);
		} while (!ok && retries--);
	}
}
		ns2501_writeb(dvo, 0xc0, ns->regs[85].value | 0x08);

static void ns2501_dump_regs(struct intel_dvo_device *dvo)
{
	uint8_t val;

	ns2501_readb(dvo, NS2501_FREQ_LO, &val);
	DRM_DEBUG_KMS("NS2501_FREQ_LO: 0x%02x\n", val);
	ns2501_readb(dvo, NS2501_FREQ_HI, &val);
	DRM_DEBUG_KMS("NS2501_FREQ_HI: 0x%02x\n", val);
	ns2501_readb(dvo, NS2501_REG8, &val);
	DRM_DEBUG_KMS("NS2501_REG8: 0x%02x\n", val);
	ns2501_readb(dvo, NS2501_REG9, &val);
	DRM_DEBUG_KMS("NS2501_REG9: 0x%02x\n", val);
	ns2501_readb(dvo, NS2501_REGC, &val);
	DRM_DEBUG_KMS("NS2501_REGC: 0x%02x\n", val);
		ns2501_writeb(dvo, 0x41, ns->regs[84].value);

		ns2501_writeb(dvo, 0x34, 0x01);
		msleep(15);

		ns2501_writeb(dvo, 0x08, 0x35);
		if (!(ns->regs[83].value & NS2501_8_BPAS))
			ns2501_writeb(dvo, 0x08, 0x31);
		msleep(200);

		ns2501_writeb(dvo, 0x34, 0x03);

		ns2501_writeb(dvo, 0xc0, ns->regs[85].value);
	} else {
		ns2501_writeb(dvo, 0x34, 0x01);
		msleep(200);

		ns2501_writeb(dvo, 0x08, 0x34);
		msleep(15);

		ns2501_writeb(dvo, 0x34, 0x00);
	}
}

static void ns2501_destroy(struct intel_dvo_device *dvo)
@@ -512,6 +627,5 @@ struct intel_dvo_dev_ops ns2501_ops = {
	.mode_set = ns2501_mode_set,
	.dpms = ns2501_dpms,
	.get_hw_state = ns2501_get_hw_state,
	.dump_regs = ns2501_dump_regs,
	.destroy = ns2501_destroy,
};
Loading