mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm/intel fixes from Dave Airlie: "Just some intel fixes. I have some radeon ones but I need to get some patches dropped from the pull req" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/i915: Increase WM memory latency values on SNB drm/i915: restore backlight precision when converting from ACPI drm/i915: Use the first mode if there is no preferred mode in the EDID drm/i915/dp: force eDP lane count to max available lanes on BDW drm/i915/vlv: reset VLV media force wake request register drm/i915/SDVO: For sysfs link put directory and target in correct order drm/i915: use lane count and link rate from VBT as minimums for eDP drm/i915: clean up VBT eDP link param decoding drm/i915: consider the source max DP lane count too
This commit is contained in:
commit
a7b0806392
@ -560,47 +560,71 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
|
|||||||
|
|
||||||
dev_priv->vbt.edp_pps = *edp_pps;
|
dev_priv->vbt.edp_pps = *edp_pps;
|
||||||
|
|
||||||
dev_priv->vbt.edp_rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
|
switch (edp_link_params->rate) {
|
||||||
DP_LINK_BW_1_62;
|
case EDP_RATE_1_62:
|
||||||
|
dev_priv->vbt.edp_rate = DP_LINK_BW_1_62;
|
||||||
|
break;
|
||||||
|
case EDP_RATE_2_7:
|
||||||
|
dev_priv->vbt.edp_rate = DP_LINK_BW_2_7;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DRM_DEBUG_KMS("VBT has unknown eDP link rate value %u\n",
|
||||||
|
edp_link_params->rate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (edp_link_params->lanes) {
|
switch (edp_link_params->lanes) {
|
||||||
case 0:
|
case EDP_LANE_1:
|
||||||
dev_priv->vbt.edp_lanes = 1;
|
dev_priv->vbt.edp_lanes = 1;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case EDP_LANE_2:
|
||||||
dev_priv->vbt.edp_lanes = 2;
|
dev_priv->vbt.edp_lanes = 2;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case EDP_LANE_4:
|
||||||
default:
|
|
||||||
dev_priv->vbt.edp_lanes = 4;
|
dev_priv->vbt.edp_lanes = 4;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
DRM_DEBUG_KMS("VBT has unknown eDP lane count value %u\n",
|
||||||
|
edp_link_params->lanes);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (edp_link_params->preemphasis) {
|
switch (edp_link_params->preemphasis) {
|
||||||
case 0:
|
case EDP_PREEMPHASIS_NONE:
|
||||||
dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
|
dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case EDP_PREEMPHASIS_3_5dB:
|
||||||
dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
|
dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case EDP_PREEMPHASIS_6dB:
|
||||||
dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
|
dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case EDP_PREEMPHASIS_9_5dB:
|
||||||
dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
|
dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
DRM_DEBUG_KMS("VBT has unknown eDP pre-emphasis value %u\n",
|
||||||
|
edp_link_params->preemphasis);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (edp_link_params->vswing) {
|
switch (edp_link_params->vswing) {
|
||||||
case 0:
|
case EDP_VSWING_0_4V:
|
||||||
dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_400;
|
dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_400;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case EDP_VSWING_0_6V:
|
||||||
dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_600;
|
dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_600;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case EDP_VSWING_0_8V:
|
||||||
dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_800;
|
dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_800;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case EDP_VSWING_1_2V:
|
||||||
dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_1200;
|
dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_1200;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
DRM_DEBUG_KMS("VBT has unknown eDP voltage swing value %u\n",
|
||||||
|
edp_link_params->vswing);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +121,22 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp)
|
|||||||
return max_link_bw;
|
return max_link_bw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
|
||||||
|
struct drm_device *dev = intel_dig_port->base.base.dev;
|
||||||
|
u8 source_max, sink_max;
|
||||||
|
|
||||||
|
source_max = 4;
|
||||||
|
if (HAS_DDI(dev) && intel_dig_port->port == PORT_A &&
|
||||||
|
(intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0)
|
||||||
|
source_max = 2;
|
||||||
|
|
||||||
|
sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
|
||||||
|
|
||||||
|
return min(source_max, sink_max);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The units on the numbers in the next two are... bizarre. Examples will
|
* The units on the numbers in the next two are... bizarre. Examples will
|
||||||
* make it clearer; this one parallels an example in the eDP spec.
|
* make it clearer; this one parallels an example in the eDP spec.
|
||||||
@ -171,7 +187,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp));
|
max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp));
|
||||||
max_lanes = drm_dp_max_lane_count(intel_dp->dpcd);
|
max_lanes = intel_dp_max_lane_count(intel_dp);
|
||||||
|
|
||||||
max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
|
max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
|
||||||
mode_rate = intel_dp_link_required(target_clock, 18);
|
mode_rate = intel_dp_link_required(target_clock, 18);
|
||||||
@ -751,8 +767,10 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
|||||||
struct intel_crtc *intel_crtc = encoder->new_crtc;
|
struct intel_crtc *intel_crtc = encoder->new_crtc;
|
||||||
struct intel_connector *intel_connector = intel_dp->attached_connector;
|
struct intel_connector *intel_connector = intel_dp->attached_connector;
|
||||||
int lane_count, clock;
|
int lane_count, clock;
|
||||||
int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
|
int min_lane_count = 1;
|
||||||
|
int max_lane_count = intel_dp_max_lane_count(intel_dp);
|
||||||
/* Conveniently, the link BW constants become indices with a shift...*/
|
/* Conveniently, the link BW constants become indices with a shift...*/
|
||||||
|
int min_clock = 0;
|
||||||
int max_clock = intel_dp_max_link_bw(intel_dp) >> 3;
|
int max_clock = intel_dp_max_link_bw(intel_dp) >> 3;
|
||||||
int bpp, mode_rate;
|
int bpp, mode_rate;
|
||||||
static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 };
|
static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 };
|
||||||
@ -785,19 +803,38 @@ intel_dp_compute_config(struct intel_encoder *encoder,
|
|||||||
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
|
/* Walk through all bpp values. Luckily they're all nicely spaced with 2
|
||||||
* bpc in between. */
|
* bpc in between. */
|
||||||
bpp = pipe_config->pipe_bpp;
|
bpp = pipe_config->pipe_bpp;
|
||||||
if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp &&
|
if (is_edp(intel_dp)) {
|
||||||
dev_priv->vbt.edp_bpp < bpp) {
|
if (dev_priv->vbt.edp_bpp && dev_priv->vbt.edp_bpp < bpp) {
|
||||||
DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n",
|
DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n",
|
||||||
dev_priv->vbt.edp_bpp);
|
dev_priv->vbt.edp_bpp);
|
||||||
bpp = dev_priv->vbt.edp_bpp;
|
bpp = dev_priv->vbt.edp_bpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_BROADWELL(dev)) {
|
||||||
|
/* Yes, it's an ugly hack. */
|
||||||
|
min_lane_count = max_lane_count;
|
||||||
|
DRM_DEBUG_KMS("forcing lane count to max (%u) on BDW\n",
|
||||||
|
min_lane_count);
|
||||||
|
} else if (dev_priv->vbt.edp_lanes) {
|
||||||
|
min_lane_count = min(dev_priv->vbt.edp_lanes,
|
||||||
|
max_lane_count);
|
||||||
|
DRM_DEBUG_KMS("using min %u lanes per VBT\n",
|
||||||
|
min_lane_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_priv->vbt.edp_rate) {
|
||||||
|
min_clock = min(dev_priv->vbt.edp_rate >> 3, max_clock);
|
||||||
|
DRM_DEBUG_KMS("using min %02x link bw per VBT\n",
|
||||||
|
bws[min_clock]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; bpp >= 6*3; bpp -= 2*3) {
|
for (; bpp >= 6*3; bpp -= 2*3) {
|
||||||
mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
|
mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
|
||||||
bpp);
|
bpp);
|
||||||
|
|
||||||
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
|
for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) {
|
||||||
for (clock = 0; clock <= max_clock; clock++) {
|
for (clock = min_clock; clock <= max_clock; clock++) {
|
||||||
link_clock = drm_dp_bw_code_to_link_rate(bws[clock]);
|
link_clock = drm_dp_bw_code_to_link_rate(bws[clock]);
|
||||||
link_avail = intel_dp_max_data_rate(link_clock,
|
link_avail = intel_dp_max_data_rate(link_clock,
|
||||||
lane_count);
|
lane_count);
|
||||||
|
@ -387,6 +387,15 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
|
|||||||
height);
|
height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No preferred mode marked by the EDID? Are there any modes? */
|
||||||
|
if (!modes[i] && !list_empty(&connector->modes)) {
|
||||||
|
DRM_DEBUG_KMS("using first mode listed on connector %s\n",
|
||||||
|
drm_get_connector_name(connector));
|
||||||
|
modes[i] = list_first_entry(&connector->modes,
|
||||||
|
struct drm_display_mode,
|
||||||
|
head);
|
||||||
|
}
|
||||||
|
|
||||||
/* last resort: use current mode */
|
/* last resort: use current mode */
|
||||||
if (!modes[i]) {
|
if (!modes[i]) {
|
||||||
/*
|
/*
|
||||||
|
@ -492,6 +492,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
|
|||||||
enum pipe pipe = intel_get_pipe_from_connector(connector);
|
enum pipe pipe = intel_get_pipe_from_connector(connector);
|
||||||
u32 freq;
|
u32 freq;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
u64 n;
|
||||||
|
|
||||||
if (!panel->backlight.present || pipe == INVALID_PIPE)
|
if (!panel->backlight.present || pipe == INVALID_PIPE)
|
||||||
return;
|
return;
|
||||||
@ -502,10 +503,9 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
|
|||||||
|
|
||||||
/* scale to hardware max, but be careful to not overflow */
|
/* scale to hardware max, but be careful to not overflow */
|
||||||
freq = panel->backlight.max;
|
freq = panel->backlight.max;
|
||||||
if (freq < max)
|
n = (u64)level * freq;
|
||||||
level = level * freq / max;
|
do_div(n, max);
|
||||||
else
|
level = n;
|
||||||
level = freq / max * level;
|
|
||||||
|
|
||||||
panel->backlight.level = level;
|
panel->backlight.level = level;
|
||||||
if (panel->backlight.device)
|
if (panel->backlight.device)
|
||||||
|
@ -2095,6 +2095,43 @@ static void intel_print_wm_latency(struct drm_device *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv,
|
||||||
|
uint16_t wm[5], uint16_t min)
|
||||||
|
{
|
||||||
|
int level, max_level = ilk_wm_max_level(dev_priv->dev);
|
||||||
|
|
||||||
|
if (wm[0] >= min)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wm[0] = max(wm[0], min);
|
||||||
|
for (level = 1; level <= max_level; level++)
|
||||||
|
wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snb_wm_latency_quirk(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
bool changed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The BIOS provided WM memory latency values are often
|
||||||
|
* inadequate for high resolution displays. Adjust them.
|
||||||
|
*/
|
||||||
|
changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) |
|
||||||
|
ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) |
|
||||||
|
ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12);
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("WM latency values increased to avoid potential underruns\n");
|
||||||
|
intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency);
|
||||||
|
intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency);
|
||||||
|
intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
|
||||||
|
}
|
||||||
|
|
||||||
static void ilk_setup_wm_latency(struct drm_device *dev)
|
static void ilk_setup_wm_latency(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
@ -2112,6 +2149,9 @@ static void ilk_setup_wm_latency(struct drm_device *dev)
|
|||||||
intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency);
|
intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency);
|
||||||
intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency);
|
intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency);
|
||||||
intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
|
intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
|
||||||
|
|
||||||
|
if (IS_GEN6(dev))
|
||||||
|
snb_wm_latency_quirk(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
|
static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
|
||||||
|
@ -2424,8 +2424,8 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|
||||||
ret = sysfs_create_link(&encoder->ddc.dev.kobj,
|
ret = sysfs_create_link(&drm_connector->kdev->kobj,
|
||||||
&drm_connector->kdev->kobj,
|
&encoder->ddc.dev.kobj,
|
||||||
encoder->ddc.dev.kobj.name);
|
encoder->ddc.dev.kobj.name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err2;
|
goto err2;
|
||||||
|
@ -185,6 +185,8 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
|
|||||||
{
|
{
|
||||||
__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
|
__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
|
||||||
_MASKED_BIT_DISABLE(0xffff));
|
_MASKED_BIT_DISABLE(0xffff));
|
||||||
|
__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
|
||||||
|
_MASKED_BIT_DISABLE(0xffff));
|
||||||
/* something from same cacheline, but !FORCEWAKE_VLV */
|
/* something from same cacheline, but !FORCEWAKE_VLV */
|
||||||
__raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
|
__raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user