Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
Pull drm fixes from Dave Airlie:
 "radeon, i915 and nouveau fixes, all fixes for regressions or black
  screens, or possible oopses"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/radeon: lower the ref * post PLL maximum
  drm/radeon: check that we have a clock before PLL setup
  drm/radeon: drm/radeon: add missing radeon_semaphore_free to error path
  drm/radeon: Fix num_banks calculation for SI
  agp: info leak in agpioc_info_wrap()
  drm/gm107/gr: bump attrib cb size quite a bit
  drm/nouveau: fix another lock unbalance in nouveau_crtc_page_flip
  drm/nouveau/bios: fix shadowing from PROM on big-endian systems
  drm/nouveau/acpi: allow non-optimus setups to load vbios from acpi
  drm/radeon/dp: check for errors in dpcd reads
  drm/radeon: avoid high jitter with small frac divs
  drm/radeon: check buffer relocation offset
  drm/radeon: use pflip irq on R600+ v2
  drm/radeon/uvd: use lower clocks on old UVD to boot v2
  drm/i915: don't try DP_LINK_BW_5_4 on HSW ULX
  drm/i915: Sanitize the enable_ppgtt module option once
  drm/i915: Break encoder->crtc link separately in intel_sanitize_crtc()
  • Loading branch information
Linus Torvalds committed May 7, 2014
2 parents 38583f0 + 2a1235e commit 8a207d3
Show file tree
Hide file tree
Showing 25 changed files with 294 additions and 87 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,9 @@ struct drm_i915_cmd_table {
#define IS_ULT(dev) (IS_HSW_ULT(dev) || IS_BDW_ULT(dev))
#define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \
((dev)->pdev->device & 0x00F0) == 0x0020)
/* ULX machines are also considered ULT. */
#define IS_HSW_ULX(dev) ((dev)->pdev->device == 0x0A0E || \
(dev)->pdev->device == 0x0A1E)
#define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)

/*
Expand Down
32 changes: 25 additions & 7 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,35 @@ static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv);

bool intel_enable_ppgtt(struct drm_device *dev, bool full)
{
if (i915.enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev))
if (i915.enable_ppgtt == 0)
return false;

if (i915.enable_ppgtt == 1 && full)
return false;

return true;
}

static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt)
{
if (enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev))
return 0;

if (enable_ppgtt == 1)
return 1;

if (enable_ppgtt == 2 && HAS_PPGTT(dev))
return 2;

#ifdef CONFIG_INTEL_IOMMU
/* Disable ppgtt on SNB if VT-d is on. */
if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) {
DRM_INFO("Disabling PPGTT because VT-d is on\n");
return false;
return 0;
}
#endif

/* Full ppgtt disabled by default for now due to issues. */
if (full)
return HAS_PPGTT(dev) && (i915.enable_ppgtt == 2);
else
return HAS_ALIASING_PPGTT(dev);
return HAS_ALIASING_PPGTT(dev) ? 1 : 0;
}

#define GEN6_PPGTT_PD_ENTRIES 512
Expand Down Expand Up @@ -2031,6 +2041,14 @@ int i915_gem_gtt_init(struct drm_device *dev)
gtt->base.total >> 20);
DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20);
DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20);
/*
* i915.enable_ppgtt is read-only, so do an early pass to validate the
* user's requested state against the hardware/driver capabilities. We
* do this now so that we can print out any log messages once rather
* than every time we check intel_enable_ppgtt().
*/
i915.enable_ppgtt = sanitize_enable_ppgtt(dev, i915.enable_ppgtt);
DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt);

return 0;
}
Expand Down
26 changes: 14 additions & 12 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -11395,15 +11395,6 @@ void intel_modeset_init(struct drm_device *dev)
}
}

static void
intel_connector_break_all_links(struct intel_connector *connector)
{
connector->base.dpms = DRM_MODE_DPMS_OFF;
connector->base.encoder = NULL;
connector->encoder->connectors_active = false;
connector->encoder->base.crtc = NULL;
}

static void intel_enable_pipe_a(struct drm_device *dev)
{
struct intel_connector *connector;
Expand Down Expand Up @@ -11485,8 +11476,17 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
if (connector->encoder->base.crtc != &crtc->base)
continue;

intel_connector_break_all_links(connector);
connector->base.dpms = DRM_MODE_DPMS_OFF;
connector->base.encoder = NULL;
}
/* multiple connectors may have the same encoder:
* handle them and break crtc link separately */
list_for_each_entry(connector, &dev->mode_config.connector_list,
base.head)
if (connector->encoder->base.crtc == &crtc->base) {
connector->encoder->base.crtc = NULL;
connector->encoder->connectors_active = false;
}

WARN_ON(crtc->active);
crtc->base.enabled = false;
Expand Down Expand Up @@ -11568,6 +11568,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
drm_get_encoder_name(&encoder->base));
encoder->disable(encoder);
}
encoder->base.crtc = NULL;
encoder->connectors_active = false;

/* Inconsistent output/port/pipe state happens presumably due to
* a bug in one of the get_hw_state functions. Or someplace else
Expand All @@ -11578,8 +11580,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
base.head) {
if (connector->encoder != encoder)
continue;

intel_connector_break_all_links(connector);
connector->base.dpms = DRM_MODE_DPMS_OFF;
connector->base.encoder = NULL;
}
}
/* Enabled encoders without active connectors will be fixed in
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp)
case DP_LINK_BW_2_7:
break;
case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */
if ((IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) &&
if (((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) ||
INTEL_INFO(dev)->gen >= 8) &&
intel_dp->dpcd[DP_DPCD_REV] >= 0x12)
max_link_bw = DP_LINK_BW_5_4;
else
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
{
mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
mmio_data(0x200000, 0x1000, NV_MEM_ACCESS_RW);

mmio_list(0x40800c, 0x00000000, 8, 1);
mmio_list(0x408010, 0x80000000, 0, 0);
Expand All @@ -877,6 +877,8 @@ gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
mmio_list(0x418e24, 0x00000000, 8, 0);
mmio_list(0x418e28, 0x80000030, 0, 0);

mmio_list(0x4064c8, 0x018002c0, 0, 0);

mmio_list(0x418810, 0x80000000, 12, 2);
mmio_list(0x419848, 0x10000000, 12, 2);
mmio_list(0x419c2c, 0x10000000, 12, 2);
Expand Down
10 changes: 6 additions & 4 deletions drivers/gpu/drm/nouveau/core/subdev/bios/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,22 +168,24 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
*/
i = 16;
do {
if ((nv_rd32(bios, 0x300000) & 0xffff) == 0xaa55)
u32 data = le32_to_cpu(nv_rd32(bios, 0x300000)) & 0xffff;
if (data == 0xaa55)
break;
} while (i--);

if (!i)
goto out;

/* read entire bios image to system memory */
bios->size = ((nv_rd32(bios, 0x300000) >> 16) & 0xff) * 512;
bios->size = (le32_to_cpu(nv_rd32(bios, 0x300000)) >> 16) & 0xff;
bios->size = bios->size * 512;
if (!bios->size)
goto out;

bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data) {
for (i = 0; i < bios->size; i+=4)
nv_wo32(bios, i, nv_rd32(bios, 0x300000 + i));
for (i = 0; i < bios->size; i += 4)
((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i);
}

/* check the PCI record header */
Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/nouveau/nouveau_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,6 @@ bool nouveau_acpi_rom_supported(struct pci_dev *pdev)
acpi_status status;
acpi_handle dhandle, rom_handle;

if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected)
return false;

dhandle = ACPI_HANDLE(&pdev->dev);
if (!dhandle)
return false;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/nouveau_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,9 +764,9 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
}

ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
mutex_unlock(&chan->cli->mutex);
if (ret)
goto fail_unreserve;
mutex_unlock(&chan->cli->mutex);

/* Update the crtc struct and cleanup */
crtc->primary->fb = fb;
Expand Down
49 changes: 34 additions & 15 deletions drivers/gpu/drm/radeon/atombios_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1177,27 +1177,43 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,

/* Set NUM_BANKS. */
if (rdev->family >= CHIP_TAHITI) {
unsigned tileb, index, num_banks, tile_split_bytes;
unsigned index, num_banks;

/* Calculate the macrotile mode index. */
tile_split_bytes = 64 << tile_split;
tileb = 8 * 8 * target_fb->bits_per_pixel / 8;
tileb = min(tile_split_bytes, tileb);
if (rdev->family >= CHIP_BONAIRE) {
unsigned tileb, tile_split_bytes;

for (index = 0; tileb > 64; index++) {
tileb >>= 1;
}
/* Calculate the macrotile mode index. */
tile_split_bytes = 64 << tile_split;
tileb = 8 * 8 * target_fb->bits_per_pixel / 8;
tileb = min(tile_split_bytes, tileb);

if (index >= 16) {
DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
target_fb->bits_per_pixel, tile_split);
return -EINVAL;
}
for (index = 0; tileb > 64; index++)
tileb >>= 1;

if (index >= 16) {
DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n",
target_fb->bits_per_pixel, tile_split);
return -EINVAL;
}

if (rdev->family >= CHIP_BONAIRE)
num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3;
else
} else {
switch (target_fb->bits_per_pixel) {
case 8:
index = 10;
break;
case 16:
index = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
break;
default:
case 32:
index = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
break;
}

num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3;
}

fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks);
} else {
/* NI and older. */
Expand Down Expand Up @@ -1885,6 +1901,9 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
(ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
is_tvcv = true;

if (!radeon_crtc->adjusted_clock)
return -EINVAL;

atombios_crtc_set_pll(crtc, adjusted_mode);

if (ASIC_IS_DCE4(rdev))
Expand Down
44 changes: 25 additions & 19 deletions drivers/gpu/drm/radeon/atombios_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return;

if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3))
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3)
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);

if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3))
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3)
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
}
Expand Down Expand Up @@ -419,21 +419,23 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,

if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
/* DP bridge chips */
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
(dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else
panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
(dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else
panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
}
} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
/* eDP */
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
}
}

return panel_mode;
Expand Down Expand Up @@ -809,11 +811,15 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
else
dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;

drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp);
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
dp_info.tp3_supported = true;
else
if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp)
== 1) {
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
dp_info.tp3_supported = true;
else
dp_info.tp3_supported = false;
} else {
dp_info.tp3_supported = false;
}

memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
dp_info.rdev = rdev;
Expand Down
Loading

0 comments on commit 8a207d3

Please sign in to comment.