Commit 155e36d4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "A bunch of scattered fixes ati/intel/nouveau, couple of core ones,
  nothing too shocking or different."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm: Add EDID_QUIRK_FORCE_REDUCED_BLANKING for ASUS VW222S
  gma500: Consider CRTC initially active.
  drm/radeon: fix dig encoder selection on DCE61
  drm/radeon: fix double free in radeon_gpu_reset
  drm/radeon: force dma32 to fix regression rs4xx,rs6xx,rs740
  drm/radeon: rework panel mode setup
  drm/radeon/atom: powergating fixes for DCE6
  drm/radeon/atom: rework DIG modesetting on DCE3+
  drm/radeon: don't disable plls that are in use by other crtcs
  drm/radeon: add proper checking of RESOLVE_BOX command for r600-r700
  drm/radeon: initialize tracked CS state
  drm/radeon: fix reading CB_COLORn_MASK from the CS
  drm/nvc0/copy: check PUNITS to determine which copy engines are disabled
  i915: Quirk no_lvds on Gigabyte GA-D525TUD ITX motherboard
  drm/i915: Use the correct size of the GTT for placing the per-process entries
  drm: Check for invalid cursor flags
  drm: Initialize object type when using DRM_MODE() macro
  drm/i915: fix color order for BGR formats on IVB
  drm/i915: fix wrong order of parameters in port checking functions
parents 318e1510 6f33814b
...@@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, ...@@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET)) if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL; return -EINVAL;
if (!req->flags) if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
return -EINVAL; return -EINVAL;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
......
...@@ -87,6 +87,9 @@ static struct edid_quirk { ...@@ -87,6 +87,9 @@ static struct edid_quirk {
int product_id; int product_id;
u32 quirks; u32 quirks;
} edid_quirk_list[] = { } edid_quirk_list[] = {
/* ASUS VW222S */
{ "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING },
/* Acer AL1706 */ /* Acer AL1706 */
{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
/* Acer F51 */ /* Acer F51 */
......
...@@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, ...@@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
(struct drm_connector **) (psb_intel_crtc + 1); (struct drm_connector **) (psb_intel_crtc + 1);
psb_intel_crtc->mode_set.num_connectors = 0; psb_intel_crtc->mode_set.num_connectors = 0;
psb_intel_cursor_init(dev, psb_intel_crtc); psb_intel_cursor_init(dev, psb_intel_crtc);
/* Set to true so that the pipe is forced off on initial config. */
psb_intel_crtc->active = true;
} }
int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
......
...@@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) ...@@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)
/* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024
* entries. For aliasing ppgtt support we just steal them at the end for * entries. For aliasing ppgtt support we just steal them at the end for
* now. */ * now. */
first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES;
ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
if (!ppgtt) if (!ppgtt)
......
...@@ -1384,7 +1384,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, ...@@ -1384,7 +1384,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
enum pipe pipe, int reg) enum pipe pipe, int reg)
{ {
u32 val = I915_READ(reg); u32 val = I915_READ(reg);
WARN(hdmi_pipe_enabled(dev_priv, val, pipe), WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
"PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
reg, pipe_name(pipe)); reg, pipe_name(pipe));
...@@ -1404,13 +1404,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, ...@@ -1404,13 +1404,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
reg = PCH_ADPA; reg = PCH_ADPA;
val = I915_READ(reg); val = I915_READ(reg);
WARN(adpa_pipe_enabled(dev_priv, val, pipe), WARN(adpa_pipe_enabled(dev_priv, pipe, val),
"PCH VGA enabled on transcoder %c, should be disabled\n", "PCH VGA enabled on transcoder %c, should be disabled\n",
pipe_name(pipe)); pipe_name(pipe));
reg = PCH_LVDS; reg = PCH_LVDS;
val = I915_READ(reg); val = I915_READ(reg);
WARN(lvds_pipe_enabled(dev_priv, val, pipe), WARN(lvds_pipe_enabled(dev_priv, pipe, val),
"PCH LVDS enabled on transcoder %c, should be disabled\n", "PCH LVDS enabled on transcoder %c, should be disabled\n",
pipe_name(pipe)); pipe_name(pipe));
...@@ -1872,7 +1872,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv, ...@@ -1872,7 +1872,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv,
enum pipe pipe, int reg) enum pipe pipe, int reg)
{ {
u32 val = I915_READ(reg); u32 val = I915_READ(reg);
if (hdmi_pipe_enabled(dev_priv, val, pipe)) { if (hdmi_pipe_enabled(dev_priv, pipe, val)) {
DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",
reg, pipe); reg, pipe);
I915_WRITE(reg, val & ~PORT_ENABLE); I915_WRITE(reg, val & ~PORT_ENABLE);
...@@ -1894,12 +1894,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, ...@@ -1894,12 +1894,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,
reg = PCH_ADPA; reg = PCH_ADPA;
val = I915_READ(reg); val = I915_READ(reg);
if (adpa_pipe_enabled(dev_priv, val, pipe)) if (adpa_pipe_enabled(dev_priv, pipe, val))
I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);
reg = PCH_LVDS; reg = PCH_LVDS;
val = I915_READ(reg); val = I915_READ(reg);
if (lvds_pipe_enabled(dev_priv, val, pipe)) { if (lvds_pipe_enabled(dev_priv, pipe, val)) {
DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val);
I915_WRITE(reg, val & ~LVDS_PORT_EN); I915_WRITE(reg, val & ~LVDS_PORT_EN);
POSTING_READ(reg); POSTING_READ(reg);
......
...@@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = { ...@@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"),
}, },
}, },
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Gigabyte GA-D525TUD",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
},
},
{ } /* terminating entry */ { } /* terminating entry */
}; };
......
...@@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, ...@@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
switch (fb->pixel_format) { switch (fb->pixel_format) {
case DRM_FORMAT_XBGR8888: case DRM_FORMAT_XBGR8888:
sprctl |= SPRITE_FORMAT_RGBX888; sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
pixel_size = 4; pixel_size = 4;
break; break;
case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XRGB8888:
sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; sprctl |= SPRITE_FORMAT_RGBX888;
pixel_size = 4; pixel_size = 4;
break; break;
case DRM_FORMAT_YUYV: case DRM_FORMAT_YUYV:
......
...@@ -736,9 +736,11 @@ nouveau_card_init(struct drm_device *dev) ...@@ -736,9 +736,11 @@ nouveau_card_init(struct drm_device *dev)
} }
break; break;
case NV_C0: case NV_C0:
nvc0_copy_create(dev, 1); if (!(nv_rd32(dev, 0x022500) & 0x00000200))
nvc0_copy_create(dev, 1);
case NV_D0: case NV_D0:
nvc0_copy_create(dev, 0); if (!(nv_rd32(dev, 0x022500) & 0x00000100))
nvc0_copy_create(dev, 0);
break; break;
default: default:
break; break;
......
...@@ -258,7 +258,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -258,7 +258,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
radeon_crtc->enabled = true; radeon_crtc->enabled = true;
/* adjust pm to dpms changes BEFORE enabling crtcs */ /* adjust pm to dpms changes BEFORE enabling crtcs */
radeon_pm_compute_clocks(rdev); radeon_pm_compute_clocks(rdev);
/* disable crtc pair power gating before programming */
if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
atombios_powergate_crtc(crtc, ATOM_DISABLE); atombios_powergate_crtc(crtc, ATOM_DISABLE);
atombios_enable_crtc(crtc, ATOM_ENABLE); atombios_enable_crtc(crtc, ATOM_ENABLE);
...@@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
atombios_enable_crtc(crtc, ATOM_DISABLE); atombios_enable_crtc(crtc, ATOM_DISABLE);
radeon_crtc->enabled = false; radeon_crtc->enabled = false;
/* power gating is per-pair */ if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { atombios_powergate_crtc(crtc, ATOM_ENABLE);
struct drm_crtc *other_crtc;
struct radeon_crtc *other_radeon_crtc;
list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) {
other_radeon_crtc = to_radeon_crtc(other_crtc);
if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) ||
((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) ||
((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) ||
((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) ||
((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) ||
((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) {
/* if both crtcs in the pair are off, enable power gating */
if (other_radeon_crtc->enabled == false)
atombios_powergate_crtc(crtc, ATOM_ENABLE);
break;
}
}
}
/* adjust pm to dpms changes AFTER disabling crtcs */ /* adjust pm to dpms changes AFTER disabling crtcs */
radeon_pm_compute_clocks(rdev); radeon_pm_compute_clocks(rdev);
break; break;
...@@ -1682,9 +1664,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) ...@@ -1682,9 +1664,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_atom_ss ss; struct radeon_atom_ss ss;
int i;
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
for (i = 0; i < rdev->num_crtc; i++) {
if (rdev->mode_info.crtcs[i] &&
rdev->mode_info.crtcs[i]->enabled &&
i != radeon_crtc->crtc_id &&
radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) {
/* one other crtc is using this pll don't turn
* off the pll
*/
goto done;
}
}
switch (radeon_crtc->pll_id) { switch (radeon_crtc->pll_id) {
case ATOM_PPLL1: case ATOM_PPLL1:
case ATOM_PPLL2: case ATOM_PPLL2:
...@@ -1701,6 +1696,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) ...@@ -1701,6 +1696,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
default: default:
break; break;
} }
done:
radeon_crtc->pll_id = -1; radeon_crtc->pll_id = -1;
} }
......
...@@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, ...@@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector);
u8 tmp;
if (!ASIC_IS_DCE4(rdev)) if (!ASIC_IS_DCE4(rdev))
return panel_mode; return panel_mode;
if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
ENCODER_OBJECT_ID_NUTMEG) /* DP bridge chips */
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == if (tmp & 1)
ENCODER_OBJECT_ID_TRAVIS) { panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
u8 id[6]; else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
int i; (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
for (i = 0; i < 6; i++)
id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i);
if (id[0] == 0x73 &&
id[1] == 0x69 &&
id[2] == 0x76 &&
id[3] == 0x61 &&
id[4] == 0x72 &&
id[5] == 0x54)
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else else
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); /* eDP */
tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
if (tmp & 1) if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
} }
......
...@@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) ...@@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
struct radeon_connector *radeon_connector = NULL; struct radeon_connector *radeon_connector = NULL;
struct radeon_connector_atom_dig *radeon_dig_connector = NULL; struct radeon_connector_atom_dig *radeon_dig_connector = NULL;
...@@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) ...@@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
switch (mode) { switch (mode) {
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
/* some early dce3.2 boards have a bug in their transmitter control table */ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || if (!connector)
ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
if (ASIC_IS_DCE6(rdev)) { else
/* It seems we need to call ATOM_ENCODER_CMD_SETUP again dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);
* before reenabling encoder on DPMS ON, otherwise we never
* get picture /* setup and enable the encoder */
*/ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); atombios_dig_encoder_setup(encoder,
ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
dig->panel_mode);
if (ext_encoder) {
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
} }
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
} else { } else if (ASIC_IS_DCE4(rdev)) {
/* setup and enable the encoder */
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
/* enable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
} else {
/* setup and enable the encoder and transmitter */
atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
/* some early dce3.2 boards have a bug in their transmitter control table */
if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730))
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
} }
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
...@@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) ...@@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
/* disable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
else } else if (ASIC_IS_DCE4(rdev)) {
/* disable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
} else {
/* disable the encoder and transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
}
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
if (ASIC_IS_DCE4(rdev)) if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
...@@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) ...@@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *test_encoder; struct drm_encoder *test_encoder;
struct radeon_encoder_atom_dig *dig; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t dig_enc_in_use = 0; uint32_t dig_enc_in_use = 0;
/* DCE4/5 */ if (ASIC_IS_DCE6(rdev)) {
if (ASIC_IS_DCE4(rdev)) { /* DCE6 */
dig = radeon_encoder->enc_priv; switch (radeon_encoder->encoder_id) {
if (ASIC_IS_DCE41(rdev)) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
if (dig->linkb)
return 1;
else
return 0;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
if (dig->linkb)
return 3;
else
return 2;
break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
if (dig->linkb)
return 5;
else
return 4;
break;
}
} else if (ASIC_IS_DCE4(rdev)) {
/* DCE4/5 */
if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) {
/* ontario follows DCE4 */ /* ontario follows DCE4 */
if (rdev->family == CHIP_PALM) { if (rdev->family == CHIP_PALM) {
if (dig->linkb) if (dig->linkb)
...@@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
radeon_encoder->pixel_clock = adjusted_mode->clock; radeon_encoder->pixel_clock = adjusted_mode->clock;
/* need to call this here rather than in prepare() since we need some crtc info */
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
atombios_yuv_setup(encoder, true); atombios_yuv_setup(encoder, true);
...@@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { /* handled in dpms */
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
if (!connector)
dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
else
dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);
/* setup and enable the encoder */
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
atombios_dig_encoder_setup(encoder,
ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
dig->panel_mode);
} else if (ASIC_IS_DCE4(rdev)) {
/* disable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
/* setup and enable the encoder */
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
/* enable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
} else {
/* disable the encoder and transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
/* setup and enable the encoder and transmitter */
atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
}
break; break;
case ENCODER_OBJECT_ID_INTERNAL_DDI: case ENCODER_OBJECT_ID_INTERNAL_DDI:
case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DVO1:
...@@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
break; break;
} }
if (ext_encoder) {
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
else
atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
}
atombios_apply_encoder_quirks(encoder, adjusted_mode); atombios_apply_encoder_quirks(encoder, adjusted_mode);
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
...@@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) ...@@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
} }
radeon_atom_output_lock(encoder, true); radeon_atom_output_lock(encoder, true);
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
if (connector) { if (connector) {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
...@@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) ...@@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
static void radeon_atom_encoder_commit(struct drm_encoder *encoder) static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
{ {
/* need to call this here as we need the crtc set up */
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
radeon_atom_output_lock(encoder, false); radeon_atom_output_lock(encoder, false);