提交 12267166 编写于 作者: L Linus Torvalds

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

Pull drm fixes from Dave Airlie:
 "Nothing too astounding or major: radeon, i915, vmwgfx, armada and
  exynos.

  Biggest ones:
   - vmwgfx has one big locking regression fix
   - i915 has come displayport fixes
   - radeon has some stability and a memory alloc failure
   - armada and exynos have some vblank fixes"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (24 commits)
  drm/exynos: correct connector->dpms field before resuming
  drm/exynos: enable vblank after DPMS on
  drm/exynos: init kms poll at the end of initialization
  drm/exynos: propagate plane initialization errors
  drm/exynos: vidi: fix build warning
  drm/exynos: remove explicit encoder/connector de-initialization
  drm/exynos: init vblank with real number of crtcs
  drm/vmwgfx: Filter out modes those cannot be supported by the current VRAM size.
  drm/vmwgfx: Fix hash key computation
  drm/vmwgfx: fix lock breakage
  drm/i915/dp: only use training pattern 3 on platforms that support it
  drm/radeon: remove some buggy dead code
  drm/i915: Ignore VBT backlight check on Macbook 2, 1
  drm/radeon: remove invalid pci id
  drm/radeon: dpm fixes for asrock systems
  radeon: clean up coding style differences in radeon_get_bios()
  drm/radeon: Use drm_malloc_ab instead of kmalloc_array
  drm/radeon/dpm: disable ulv support on SI
  drm/i915: Fix GMBUSFREQ on vlv/chv
  drm/i915: Ignore long hpds on eDP ports
  ...
......@@ -260,7 +260,7 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
* Tell the DRM core that vblank IRQs aren't going to happen for
* a while. This cleans up any pending vblank events for us.
*/
drm_vblank_off(dev, dcrtc->num);
drm_crtc_vblank_off(&dcrtc->crtc);
/* Handle any pending flip event. */
spin_lock_irq(&dev->event_lock);
......@@ -289,6 +289,8 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
armada_drm_crtc_update(dcrtc);
if (dpms_blanked(dpms))
armada_drm_vblank_off(dcrtc);
else
drm_crtc_vblank_on(&dcrtc->crtc);
}
}
......@@ -526,7 +528,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
/* Wait for pending flips to complete */
wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
drm_vblank_pre_modeset(crtc->dev, dcrtc->num);
drm_crtc_vblank_off(crtc);
crtc->mode = *adj;
......@@ -617,7 +619,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
armada_drm_crtc_update(dcrtc);
drm_vblank_post_modeset(crtc->dev, dcrtc->num);
drm_crtc_vblank_on(crtc);
armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms));
return 0;
......@@ -945,18 +947,15 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
armada_reg_queue_end(work->regs, i);
/*
* Hold the old framebuffer for the work - DRM appears to drop our
* reference to the old framebuffer in drm_mode_page_flip_ioctl().
* Ensure that we hold a reference on the new framebuffer.
* This has to match the behaviour in mode_set.
*/
drm_framebuffer_reference(work->old_fb);
drm_framebuffer_reference(fb);
ret = armada_drm_crtc_queue_frame_work(dcrtc, work);
if (ret) {
/*
* Undo our reference above; DRM does not drop the reference
* to this object on error, so that's okay.
*/
drm_framebuffer_unreference(work->old_fb);
/* Undo our reference above */
drm_framebuffer_unreference(fb);
kfree(work);
return ret;
}
......
......@@ -190,6 +190,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
if (ret)
goto err_comp;
dev->irq_enabled = true;
dev->vblank_disable_allowed = 1;
ret = armada_fbdev_init(dev);
......@@ -331,7 +332,7 @@ static struct drm_driver armada_drm_driver = {
.desc = "Armada SoC DRM",
.date = "20120730",
.driver_features = DRIVER_GEM | DRIVER_MODESET |
DRIVER_PRIME,
DRIVER_HAVE_IRQ | DRIVER_PRIME,
.ioctls = armada_ioctls,
.fops = &armada_drm_fops,
};
......
......@@ -1355,13 +1355,8 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
void *data)
{
struct exynos_drm_display *display = dev_get_drvdata(dev);
struct exynos_dp_device *dp = display->ctx;
struct drm_encoder *encoder = dp->encoder;
exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);
exynos_dp_connector_destroy(&dp->connector);
encoder->funcs->destroy(encoder);
}
static const struct component_ops exynos_dp_ops = {
......
......@@ -71,13 +71,16 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
!atomic_read(&exynos_crtc->pending_flip),
HZ/20))
atomic_set(&exynos_crtc->pending_flip, 0);
drm_vblank_off(crtc->dev, exynos_crtc->pipe);
drm_crtc_vblank_off(crtc);
}
if (manager->ops->dpms)
manager->ops->dpms(manager, mode);
exynos_crtc->dpms = mode;
if (mode == DRM_MODE_DPMS_ON)
drm_crtc_vblank_on(crtc);
}
static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
......
......@@ -338,14 +338,10 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
int exynos_dpi_remove(struct device *dev)
{
struct drm_encoder *encoder = exynos_dpi_display.encoder;
struct exynos_dpi *ctx = exynos_dpi_display.ctx;
exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF);
exynos_dpi_connector_destroy(&ctx->connector);
encoder->funcs->destroy(encoder);
if (ctx->panel)
drm_panel_detach(ctx->panel);
......
......@@ -87,16 +87,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
plane = exynos_plane_init(dev, possible_crtcs,
DRM_PLANE_TYPE_OVERLAY);
if (IS_ERR(plane))
goto err_mode_config_cleanup;
}
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(dev);
if (!IS_ERR(plane))
continue;
ret = drm_vblank_init(dev, MAX_CRTC);
if (ret)
ret = PTR_ERR(plane);
goto err_mode_config_cleanup;
}
/* setup possible_clones. */
exynos_drm_encoder_setup(dev);
......@@ -106,15 +102,16 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
/* Try to bind all sub drivers. */
ret = component_bind_all(dev->dev, dev);
if (ret)
goto err_cleanup_vblank;
goto err_mode_config_cleanup;
/* Probe non kms sub drivers and virtual display driver. */
ret = exynos_drm_device_subdrv_probe(dev);
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret)
goto err_unbind_all;
/* force connectors detection */
drm_helper_hpd_irq_event(dev);
/* Probe non kms sub drivers and virtual display driver. */
ret = exynos_drm_device_subdrv_probe(dev);
if (ret)
goto err_cleanup_vblank;
/*
* enable drm irq mode.
......@@ -133,12 +130,18 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
*/
dev->vblank_disable_allowed = true;
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(dev);
/* force connectors detection */
drm_helper_hpd_irq_event(dev);
return 0;
err_unbind_all:
component_unbind_all(dev->dev, dev);
err_cleanup_vblank:
drm_vblank_cleanup(dev);
err_unbind_all:
component_unbind_all(dev->dev, dev);
err_mode_config_cleanup:
drm_mode_config_cleanup(dev);
drm_release_iommu_mapping(dev);
......@@ -155,8 +158,8 @@ static int exynos_drm_unload(struct drm_device *dev)
exynos_drm_fbdev_fini(dev);
drm_kms_helper_poll_fini(dev);
component_unbind_all(dev->dev, dev);
drm_vblank_cleanup(dev);
component_unbind_all(dev->dev, dev);
drm_mode_config_cleanup(dev);
drm_release_iommu_mapping(dev);
......@@ -191,8 +194,12 @@ static int exynos_drm_resume(struct drm_device *dev)
drm_modeset_lock_all(dev);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->funcs->dpms)
connector->funcs->dpms(connector, connector->dpms);
if (connector->funcs->dpms) {
int dpms = connector->dpms;
connector->dpms = DRM_MODE_DPMS_OFF;
connector->funcs->dpms(connector, dpms);
}
}
drm_modeset_unlock_all(dev);
......
......@@ -1660,13 +1660,9 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
void *data)
{
struct exynos_dsi *dsi = exynos_dsi_display.ctx;
struct drm_encoder *encoder = dsi->encoder;
exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF);
exynos_dsi_connector_destroy(&dsi->connector);
encoder->funcs->destroy(encoder);
mipi_dsi_host_unregister(&dsi->dsi_host);
}
......
......@@ -630,7 +630,6 @@ static int vidi_remove(struct platform_device *pdev)
{
struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);
struct vidi_context *ctx = mgr->ctx;
struct drm_encoder *encoder = ctx->encoder;
if (ctx->raw_edid != (struct edid *)fake_edid_info) {
kfree(ctx->raw_edid);
......@@ -639,9 +638,6 @@ static int vidi_remove(struct platform_device *pdev)
return -EINVAL;
}
encoder->funcs->destroy(encoder);
drm_connector_cleanup(&ctx->connector);
return 0;
}
......
......@@ -2312,12 +2312,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
static void hdmi_unbind(struct device *dev, struct device *master, void *data)
{
struct exynos_drm_display *display = get_hdmi_display(dev);
struct drm_encoder *encoder = display->encoder;
struct hdmi_context *hdata = display->ctx;
hdmi_connector_destroy(&hdata->connector);
encoder->funcs->destroy(encoder);
}
static const struct component_ops hdmi_component_ops = {
......
......@@ -4585,7 +4585,7 @@ static void vlv_update_cdclk(struct drm_device *dev)
* BSpec erroneously claims we should aim for 4MHz, but
* in fact 1MHz is the correct frequency.
*/
I915_WRITE(GMBUSFREQ_VLV, dev_priv->vlv_cdclk_freq);
I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->vlv_cdclk_freq, 1000));
}
/* Adjust CDclk dividers to allow high res or save power if possible */
......@@ -12885,6 +12885,9 @@ static struct intel_quirk intel_quirks[] = {
/* Acer C720 Chromebook (Core i3 4005U) */
{ 0x0a16, 0x1025, 0x0a11, quirk_backlight_present },
/* Apple Macbook 2,1 (Core 2 T7400) */
{ 0x27a2, 0x8086, 0x7270, quirk_backlight_present },
/* Toshiba CB35 Chromebook (Celeron 2955U) */
{ 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
......
......@@ -2806,6 +2806,13 @@ intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset,
ssize_t ret;
int i;
/*
* Sometime we just get the same incorrect byte repeated
* over the entire buffer. Doing just one throw away read
* initially seems to "solve" it.
*/
drm_dp_dpcd_read(aux, DP_DPCD_REV, buffer, 1);
for (i = 0; i < 3; i++) {
ret = drm_dp_dpcd_read(aux, offset, buffer, size);
if (ret == size)
......@@ -3724,9 +3731,10 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
}
}
/* Training Pattern 3 support */
/* Training Pattern 3 support, both source and sink */
if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 &&
intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) {
intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED &&
(IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)) {
intel_dp->use_tps3 = true;
DRM_DEBUG_KMS("Displayport TPS3 supported\n");
} else
......@@ -4491,6 +4499,18 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
if (intel_dig_port->base.type != INTEL_OUTPUT_EDP)
intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) {
/*
* vdd off can generate a long pulse on eDP which
* would require vdd on to handle it, and thus we
* would end up in an endless cycle of
* "vdd off -> long hpd -> vdd on -> detect -> vdd off -> ..."
*/
DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n",
port_name(intel_dig_port->port));
return false;
}
DRM_DEBUG_KMS("got hpd irq on port %c - %s\n",
port_name(intel_dig_port->port),
long_hpd ? "long" : "short");
......
......@@ -3005,7 +3005,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
u32 vgt_cache_invalidation;
u32 hdp_host_path_cntl, tmp;
u32 disabled_rb_mask;
int i, j, num_shader_engines, ps_thread_count;
int i, j, ps_thread_count;
switch (rdev->family) {
case CHIP_CYPRESS:
......@@ -3303,8 +3303,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
rdev->config.evergreen.tile_config |=
((gb_addr_config & 0x30000000) >> 28) << 12;
num_shader_engines = (gb_addr_config & NUM_SHADER_ENGINES(3) >> 12) + 1;
if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) {
u32 efuse_straps_4;
u32 efuse_straps_3;
......
......@@ -2725,7 +2725,11 @@ int kv_dpm_init(struct radeon_device *rdev)
pi->sram_end = SMC_RAM_END;
pi->enable_nb_dpm = true;
/* Enabling nb dpm on an asrock system prevents dpm from working */
if (rdev->pdev->subsystem_vendor == 0x1849)
pi->enable_nb_dpm = false;
else
pi->enable_nb_dpm = true;
pi->caps_power_containment = true;
pi->caps_cac = true;
......@@ -2740,10 +2744,19 @@ int kv_dpm_init(struct radeon_device *rdev)
pi->caps_sclk_ds = true;
pi->enable_auto_thermal_throttling = true;
pi->disable_nb_ps3_in_battery = false;
if (radeon_bapm == 0)
if (radeon_bapm == -1) {
/* There are stability issues reported on with
* bapm enabled on an asrock system.
*/
if (rdev->pdev->subsystem_vendor == 0x1849)
pi->bapm_enable = false;
else
pi->bapm_enable = true;
} else if (radeon_bapm == 0) {
pi->bapm_enable = false;
else
} else {
pi->bapm_enable = true;
}
pi->voltage_drop_t = 0;
pi->caps_sclk_throttle_low_notification = false;
pi->caps_fps = false; /* true? */
......
......@@ -658,12 +658,10 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
if (r == false) {
if (r == false)
r = radeon_read_disabled_bios(rdev);
}
if (r == false) {
if (r == false)
r = radeon_read_platform_bios(rdev);
}
if (r == false || rdev->bios == NULL) {
DRM_ERROR("Unable to locate a BIOS ROM\n");
rdev->bios = NULL;
......
......@@ -450,7 +450,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo
kfree(parser->track);
kfree(parser->relocs);
kfree(parser->relocs_ptr);
kfree(parser->vm_bos);
drm_free_large(parser->vm_bos);
for (i = 0; i < parser->nchunks; i++)
drm_free_large(parser->chunks[i].kdata);
kfree(parser->chunks);
......
......@@ -314,7 +314,7 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring
}
/* and then save the content of the ring */
*data = kmalloc_array(size, sizeof(uint32_t), GFP_KERNEL);
*data = drm_malloc_ab(size, sizeof(uint32_t));
if (!*data) {
mutex_unlock(&rdev->ring_lock);
return 0;
......@@ -356,7 +356,7 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
}
radeon_ring_unlock_commit(rdev, ring, false);
kfree(data);
drm_free_large(data);
return 0;
}
......
......@@ -132,8 +132,8 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev,
struct radeon_cs_reloc *list;
unsigned i, idx;
list = kmalloc_array(vm->max_pde_used + 2,
sizeof(struct radeon_cs_reloc), GFP_KERNEL);
list = drm_malloc_ab(vm->max_pde_used + 2,
sizeof(struct radeon_cs_reloc));
if (!list)
return NULL;
......
......@@ -6256,7 +6256,7 @@ static void si_parse_pplib_clock_info(struct radeon_device *rdev,
if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) &&
index == 0) {
/* XXX disable for A0 tahiti */
si_pi->ulv.supported = true;
si_pi->ulv.supported = false;
si_pi->ulv.pl = *pl;
si_pi->ulv.one_pcie_lane_in_ulv = false;
si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT;
......
......@@ -246,7 +246,8 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man,
struct drm_hash_item *hash;
int ret;
ret = drm_ht_find_item(&man->resources, user_key, &hash);
ret = drm_ht_find_item(&man->resources, user_key | (res_type << 24),
&hash);
if (likely(ret != 0))
return -EINVAL;
......
......@@ -688,7 +688,11 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
goto out_err0;
}
if (unlikely(dev_priv->prim_bb_mem < dev_priv->vram_size))
/*
* Limit back buffer size to VRAM size. Remove this once
* screen targets are implemented.
*/
if (dev_priv->prim_bb_mem > dev_priv->vram_size)
dev_priv->prim_bb_mem = dev_priv->vram_size;
mutex_unlock(&dev_priv->hw_mutex);
......
......@@ -187,7 +187,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
* can do this since the caller in the drm core doesn't check anything
* which is protected by any looks.
*/
drm_modeset_unlock(&crtc->mutex);
drm_modeset_unlock_crtc(crtc);
drm_modeset_lock_all(dev_priv->dev);
/* A lot of the code assumes this */
......@@ -252,7 +252,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
ret = 0;
out:
drm_modeset_unlock_all(dev_priv->dev);
drm_modeset_lock(&crtc->mutex, NULL);
drm_modeset_lock_crtc(crtc);
return ret;
}
......@@ -273,7 +273,7 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
* can do this since the caller in the drm core doesn't check anything
* which is protected by any looks.
*/
drm_modeset_unlock(&crtc->mutex);
drm_modeset_unlock_crtc(crtc);
drm_modeset_lock_all(dev_priv->dev);
vmw_cursor_update_position(dev_priv, shown,
......@@ -281,7 +281,7 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
du->cursor_y + du->hotspot_y);
drm_modeset_unlock_all(dev_priv->dev);
drm_modeset_lock(&crtc->mutex, NULL);
drm_modeset_lock_crtc(crtc);
return 0;
}
......@@ -1950,6 +1950,14 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
};
int i;
u32 assumed_bpp = 2;
/*
* If using screen objects, then assume 32-bpp because that's what the
* SVGA device is assuming
*/
if (dev_priv->sou_priv)
assumed_bpp = 4;
/* Add preferred mode */
{
......@@ -1960,8 +1968,9 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
mode->vdisplay = du->pref_height;
vmw_guess_mode_timing(mode);
if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2,
mode->vdisplay)) {
if (vmw_kms_validate_mode_vram(dev_priv,
mode->hdisplay * assumed_bpp,
mode->vdisplay)) {
drm_mode_probed_add(connector, mode);
} else {
drm_mode_destroy(dev, mode);
......@@ -1983,7 +1992,8 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
bmode->vdisplay > max_height)
continue;
if (!vmw_kms_validate_mode_vram(dev_priv, bmode->hdisplay * 2,
if (!vmw_kms_validate_mode_vram(dev_priv,
bmode->hdisplay * assumed_bpp,
bmode->vdisplay))
continue;
......
......@@ -74,7 +74,6 @@
{0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
{0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
{0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
{0x1002, 0x4C6E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
{0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
{0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册