From 59d1222bb2dd3b22e557870cf0aab30ce30eab01 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 20 Jan 2013 16:11:20 +0000 Subject: [PATCH] --- yaml --- r: 349373 b: refs/heads/master c: 1c8c38c588ea91f8deeae21284840459d1bb58e3 h: refs/heads/master i: 349371: af7182f435f49ab6a308af3fb1bd61d031ac4dfe v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/exynos/Kconfig | 4 +- .../gpu/drm/exynos/exynos_drm_connector.c | 33 ++--- .../gpu/drm/exynos/exynos_drm_dmabuf.c | 24 ++-- trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h | 4 +- trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c | 2 +- .../drivers/gpu/drm/exynos/exynos_drm_hdmi.c | 9 +- .../drivers/gpu/drm/exynos/exynos_drm_hdmi.h | 4 +- trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c | 2 +- .../gpu/drm/exynos/exynos_drm_rotator.c | 4 +- .../drivers/gpu/drm/exynos/exynos_drm_vidi.c | 26 ++-- trunk/drivers/gpu/drm/exynos/exynos_hdmi.c | 121 ++++++++++++------ trunk/drivers/gpu/drm/exynos/exynos_mixer.c | 9 +- trunk/drivers/gpu/drm/i915/i915_reg.h | 1 + trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 19 ++- trunk/drivers/gpu/drm/radeon/ni.c | 8 +- trunk/drivers/gpu/drm/radeon/r600.c | 8 +- trunk/drivers/gpu/drm/radeon/radeon_cs.c | 2 - trunk/drivers/gpu/drm/radeon/radeon_cursor.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_display.c | 2 +- 20 files changed, 161 insertions(+), 126 deletions(-) diff --git a/[refs] b/[refs] index 075536db8cb2..4826035ca3c5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f0f21aa53a30fffd69899794da3a077960f27771 +refs/heads/master: 1c8c38c588ea91f8deeae21284840459d1bb58e3 diff --git a/trunk/drivers/gpu/drm/exynos/Kconfig b/trunk/drivers/gpu/drm/exynos/Kconfig index 046bcda36abe..1d1f1e5e33f0 100644 --- a/trunk/drivers/gpu/drm/exynos/Kconfig +++ b/trunk/drivers/gpu/drm/exynos/Kconfig @@ -24,7 +24,7 @@ config DRM_EXYNOS_DMABUF config DRM_EXYNOS_FIMD bool "Exynos DRM FIMD" - depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM + depends on DRM_EXYNOS && !FB_S3C help Choose this option if you want to use Exynos FIMD for DRM. @@ -48,7 +48,7 @@ config DRM_EXYNOS_G2D config DRM_EXYNOS_IPP bool "Exynos DRM IPP" - depends on DRM_EXYNOS && !ARCH_MULTIPLATFORM + depends on DRM_EXYNOS help Choose this option if you want to use IPP feature for DRM. diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c index 4c5b6859c9ea..ab37437bad8a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -18,6 +18,7 @@ #include "exynos_drm_drv.h" #include "exynos_drm_encoder.h" +#define MAX_EDID 256 #define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\ drm_connector) @@ -95,9 +96,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) to_exynos_connector(connector); struct exynos_drm_manager *manager = exynos_connector->manager; struct exynos_drm_display_ops *display_ops = manager->display_ops; - struct edid *edid = NULL; - unsigned int count = 0; - int ret; + unsigned int count; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -115,21 +114,27 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) * because lcd panel has only one mode. */ if (display_ops->get_edid) { - edid = display_ops->get_edid(manager->dev, connector); - if (IS_ERR_OR_NULL(edid)) { - ret = PTR_ERR(edid); - edid = NULL; - DRM_ERROR("Panel operation get_edid failed %d\n", ret); - goto out; + int ret; + void *edid; + + edid = kzalloc(MAX_EDID, GFP_KERNEL); + if (!edid) { + DRM_ERROR("failed to allocate edid\n"); + return 0; } - count = drm_add_edid_modes(connector, edid); - if (count < 0) { - DRM_ERROR("Add edid modes failed %d\n", count); - goto out; + ret = display_ops->get_edid(manager->dev, connector, + edid, MAX_EDID); + if (ret < 0) { + DRM_ERROR("failed to get edid data.\n"); + kfree(edid); + edid = NULL; + return 0; } drm_mode_connector_update_edid_property(connector, edid); + count = drm_add_edid_modes(connector, edid); + kfree(edid); } else { struct exynos_drm_panel_info *panel; struct drm_display_mode *mode = drm_mode_create(connector->dev); @@ -156,8 +161,6 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) count = 1; } -out: - kfree(edid); return count; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index ba0a3aa78547..9df97714b6c0 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -19,7 +19,6 @@ struct exynos_drm_dmabuf_attachment { struct sg_table sgt; enum dma_data_direction dir; - bool is_mapped; }; static int exynos_gem_attach_dma_buf(struct dma_buf *dmabuf, @@ -73,10 +72,17 @@ static struct sg_table * DRM_DEBUG_PRIME("%s\n", __FILE__); + if (WARN_ON(dir == DMA_NONE)) + return ERR_PTR(-EINVAL); + /* just return current sgt if already requested. */ - if (exynos_attach->dir == dir && exynos_attach->is_mapped) + if (exynos_attach->dir == dir) return &exynos_attach->sgt; + /* reattaching is not allowed. */ + if (WARN_ON(exynos_attach->dir != DMA_NONE)) + return ERR_PTR(-EBUSY); + buf = gem_obj->buffer; if (!buf) { DRM_ERROR("buffer is null.\n"); @@ -101,17 +107,13 @@ static struct sg_table * wr = sg_next(wr); } - if (dir != DMA_NONE) { - nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); - if (!nents) { - DRM_ERROR("failed to map sgl with iommu.\n"); - sg_free_table(sgt); - sgt = ERR_PTR(-EIO); - goto err_unlock; - } + nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); + if (!nents) { + DRM_ERROR("failed to map sgl with iommu.\n"); + sgt = ERR_PTR(-EIO); + goto err_unlock; } - exynos_attach->is_mapped = true; exynos_attach->dir = dir; attach->priv = exynos_attach; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h index 4606fac7241a..b9e51bc09e81 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -148,8 +148,8 @@ struct exynos_drm_overlay { struct exynos_drm_display_ops { enum exynos_drm_output_type type; bool (*is_connected)(struct device *dev); - struct edid *(*get_edid)(struct device *dev, - struct drm_connector *connector); + int (*get_edid)(struct device *dev, struct drm_connector *connector, + u8 *edid, int len); void *(*get_panel)(struct device *dev); int (*check_timing)(struct device *dev, void *timing); int (*power_on)(struct device *dev, int mode); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 9a4c08e7453c..36c3905536a6 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -324,7 +324,7 @@ static void g2d_userptr_put_dma_addr(struct drm_device *drm_dev, g2d_userptr = NULL; } -static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, +dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, unsigned long userptr, unsigned long size, struct drm_file *filp, diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 28644539b305..850e9950b7da 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -108,17 +108,18 @@ static bool drm_hdmi_is_connected(struct device *dev) return false; } -static struct edid *drm_hdmi_get_edid(struct device *dev, - struct drm_connector *connector) +static int drm_hdmi_get_edid(struct device *dev, + struct drm_connector *connector, u8 *edid, int len) { struct drm_hdmi_context *ctx = to_context(dev); DRM_DEBUG_KMS("%s\n", __FILE__); if (hdmi_ops && hdmi_ops->get_edid) - return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector); + return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, + len); - return NULL; + return 0; } static int drm_hdmi_check_timing(struct device *dev, void *timing) diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index d80516fc9ed7..784a7e9a766c 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h @@ -30,8 +30,8 @@ struct exynos_drm_hdmi_context { struct exynos_hdmi_ops { /* display */ bool (*is_connected)(void *ctx); - struct edid *(*get_edid)(void *ctx, - struct drm_connector *connector); + int (*get_edid)(void *ctx, struct drm_connector *connector, + u8 *edid, int len); int (*check_timing)(void *ctx, void *timing); int (*power_on)(void *ctx, int mode); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 1a556354e92f..0bda96454a02 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -869,7 +869,7 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node, } } -static void ipp_handle_cmd_work(struct device *dev, +void ipp_handle_cmd_work(struct device *dev, struct exynos_drm_ippdrv *ippdrv, struct drm_exynos_ipp_cmd_work *cmd_work, struct drm_exynos_ipp_cmd_node *c_node) diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.c index f976e29def6e..e9e83ef688f0 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -734,7 +734,7 @@ static int rotator_remove(struct platform_device *pdev) return 0; } -static struct rot_limit_table rot_limit_tbl = { +struct rot_limit_table rot_limit_tbl = { .ycbcr420_2p = { .min_w = 32, .min_h = 32, @@ -751,7 +751,7 @@ static struct rot_limit_table rot_limit_tbl = { }, }; -static struct platform_device_id rotator_driver_ids[] = { +struct platform_device_id rotator_driver_ids[] = { { .name = "exynos-rot", .driver_data = (unsigned long)&rot_limit_tbl, diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 13ccbd4bcfaa..d0ca3c4e06c6 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -98,12 +98,10 @@ static bool vidi_display_is_connected(struct device *dev) return ctx->connected ? true : false; } -static struct edid *vidi_get_edid(struct device *dev, - struct drm_connector *connector) +static int vidi_get_edid(struct device *dev, struct drm_connector *connector, + u8 *edid, int len) { struct vidi_context *ctx = get_vidi_context(dev); - struct edid *edid; - int edid_len; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -113,18 +111,13 @@ static struct edid *vidi_get_edid(struct device *dev, */ if (!ctx->raw_edid) { DRM_DEBUG_KMS("raw_edid is null.\n"); - return ERR_PTR(-EFAULT); + return -EFAULT; } - edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; - edid = kzalloc(edid_len, GFP_KERNEL); - if (!edid) { - DRM_DEBUG_KMS("failed to allocate edid\n"); - return ERR_PTR(-ENOMEM); - } + memcpy(edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions) + * EDID_LENGTH, len)); - memcpy(edid, ctx->raw_edid, edid_len); - return edid; + return 0; } static void *vidi_get_panel(struct device *dev) @@ -521,6 +514,7 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, struct exynos_drm_manager *manager; struct exynos_drm_display_ops *display_ops; struct drm_exynos_vidi_connection *vidi = data; + struct edid *raw_edid; int edid_len; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -557,11 +551,11 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, } if (vidi->connection) { - struct edid *raw_edid = (struct edid *)(uint32_t)vidi->edid; - if (!drm_edid_is_valid(raw_edid)) { - DRM_DEBUG_KMS("edid data is invalid.\n"); + if (!vidi->edid) { + DRM_DEBUG_KMS("edid data is null.\n"); return -EINVAL; } + raw_edid = (struct edid *)(uint32_t)vidi->edid; edid_len = (1 + raw_edid->extensions) * EDID_LENGTH; ctx->raw_edid = kzalloc(edid_len, GFP_KERNEL); if (!ctx->raw_edid) { diff --git a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c index fbab3c468603..41ff79d8ac8e 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -97,7 +98,8 @@ struct hdmi_context { void __iomem *regs; void *parent_ctx; - int irq; + int external_irq; + int internal_irq; struct i2c_client *ddc_port; struct i2c_client *hdmiphy_port; @@ -1389,7 +1391,8 @@ static bool hdmi_is_connected(void *ctx) return hdata->hpd; } -static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector) +static int hdmi_get_edid(void *ctx, struct drm_connector *connector, + u8 *edid, int len) { struct edid *raw_edid; struct hdmi_context *hdata = ctx; @@ -1397,18 +1400,22 @@ static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector) DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); if (!hdata->ddc_port) - return ERR_PTR(-ENODEV); + return -ENODEV; raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter); - if (!raw_edid) - return ERR_PTR(-ENODEV); - - hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid); - DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", - (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), - raw_edid->width_cm, raw_edid->height_cm); + if (raw_edid) { + hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid); + memcpy(edid, raw_edid, min((1 + raw_edid->extensions) + * EDID_LENGTH, len)); + DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", + (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), + raw_edid->width_cm, raw_edid->height_cm); + kfree(raw_edid); + } else { + return -ENODEV; + } - return raw_edid; + return 0; } static int hdmi_v13_check_timing(struct fb_videomode *check_timing) @@ -1645,16 +1652,16 @@ static void hdmi_conf_reset(struct hdmi_context *hdata) /* resetting HDMI core */ hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT); - usleep_range(10000, 12000); + mdelay(10); hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT); - usleep_range(10000, 12000); + mdelay(10); } static void hdmi_conf_init(struct hdmi_context *hdata) { struct hdmi_infoframe infoframe; - /* disable HPD interrupts from HDMI IP block, use GPIO instead */ + /* disable HPD interrupts */ hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); @@ -1772,7 +1779,7 @@ static void hdmi_v13_timing_apply(struct hdmi_context *hdata) u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS); if (val & HDMI_PHY_STATUS_READY) break; - usleep_range(1000, 2000); + mdelay(1); } /* steady state not achieved */ if (tries == 0) { @@ -1939,7 +1946,7 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata) u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0); if (val & HDMI_PHY_STATUS_READY) break; - usleep_range(1000, 2000); + mdelay(1); } /* steady state not achieved */ if (tries == 0) { @@ -1991,9 +1998,9 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata) /* reset hdmiphy */ hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT); - usleep_range(10000, 12000); + mdelay(10); hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT); - usleep_range(10000, 12000); + mdelay(10); } static void hdmiphy_poweron(struct hdmi_context *hdata) @@ -2041,7 +2048,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) return; } - usleep_range(10000, 12000); + mdelay(10); /* operation mode */ operation[0] = 0x1f; @@ -2163,13 +2170,6 @@ static void hdmi_commit(void *ctx) DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - mutex_lock(&hdata->hdmi_mutex); - if (!hdata->powered) { - mutex_unlock(&hdata->hdmi_mutex); - return; - } - mutex_unlock(&hdata->hdmi_mutex); - hdmi_conf_apply(hdata); } @@ -2265,7 +2265,7 @@ static struct exynos_hdmi_ops hdmi_ops = { .dpms = hdmi_dpms, }; -static irqreturn_t hdmi_irq_thread(int irq, void *arg) +static irqreturn_t hdmi_external_irq_thread(int irq, void *arg) { struct exynos_drm_hdmi_context *ctx = arg; struct hdmi_context *hdata = ctx->ctx; @@ -2280,6 +2280,31 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg) return IRQ_HANDLED; } +static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg) +{ + struct exynos_drm_hdmi_context *ctx = arg; + struct hdmi_context *hdata = ctx->ctx; + u32 intc_flag; + + intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); + /* clearing flags for HPD plug/unplug */ + if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) { + DRM_DEBUG_KMS("unplugged\n"); + hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, + HDMI_INTC_FLAG_HPD_UNPLUG); + } + if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) { + DRM_DEBUG_KMS("plugged\n"); + hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, + HDMI_INTC_FLAG_HPD_PLUG); + } + + if (ctx->drm_dev) + drm_helper_hpd_irq_event(ctx->drm_dev); + + return IRQ_HANDLED; +} + static int hdmi_resources_init(struct hdmi_context *hdata) { struct device *dev = hdata->dev; @@ -2530,24 +2555,39 @@ static int hdmi_probe(struct platform_device *pdev) hdata->hdmiphy_port = hdmi_hdmiphy; - hdata->irq = gpio_to_irq(hdata->hpd_gpio); - if (hdata->irq < 0) { - DRM_ERROR("failed to get GPIO irq\n"); - ret = hdata->irq; + hdata->external_irq = gpio_to_irq(hdata->hpd_gpio); + if (hdata->external_irq < 0) { + DRM_ERROR("failed to get GPIO external irq\n"); + ret = hdata->external_irq; + goto err_hdmiphy; + } + + hdata->internal_irq = platform_get_irq(pdev, 0); + if (hdata->internal_irq < 0) { + DRM_ERROR("failed to get platform internal irq\n"); + ret = hdata->internal_irq; goto err_hdmiphy; } hdata->hpd = gpio_get_value(hdata->hpd_gpio); - ret = request_threaded_irq(hdata->irq, NULL, - hdmi_irq_thread, IRQF_TRIGGER_RISING | + ret = request_threaded_irq(hdata->external_irq, NULL, + hdmi_external_irq_thread, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "hdmi", drm_hdmi_ctx); + "hdmi_external", drm_hdmi_ctx); if (ret) { - DRM_ERROR("failed to register hdmi interrupt\n"); + DRM_ERROR("failed to register hdmi external interrupt\n"); goto err_hdmiphy; } + ret = request_threaded_irq(hdata->internal_irq, NULL, + hdmi_internal_irq_thread, IRQF_ONESHOT, + "hdmi_internal", drm_hdmi_ctx); + if (ret) { + DRM_ERROR("failed to register hdmi internal interrupt\n"); + goto err_free_irq; + } + /* Attach HDMI Driver to common hdmi. */ exynos_hdmi_drv_attach(drm_hdmi_ctx); @@ -2558,6 +2598,8 @@ static int hdmi_probe(struct platform_device *pdev) return 0; +err_free_irq: + free_irq(hdata->external_irq, drm_hdmi_ctx); err_hdmiphy: i2c_del_driver(&hdmiphy_driver); err_ddc: @@ -2575,7 +2617,8 @@ static int hdmi_remove(struct platform_device *pdev) pm_runtime_disable(dev); - free_irq(hdata->irq, hdata); + free_irq(hdata->internal_irq, hdata); + free_irq(hdata->external_irq, hdata); /* hdmiphy i2c driver */ @@ -2594,7 +2637,8 @@ static int hdmi_suspend(struct device *dev) DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - disable_irq(hdata->irq); + disable_irq(hdata->internal_irq); + disable_irq(hdata->external_irq); hdata->hpd = false; if (ctx->drm_dev) @@ -2619,7 +2663,8 @@ static int hdmi_resume(struct device *dev) hdata->hpd = gpio_get_value(hdata->hpd_gpio); - enable_irq(hdata->irq); + enable_irq(hdata->external_irq); + enable_irq(hdata->internal_irq); if (!pm_runtime_suspended(dev)) { DRM_DEBUG_KMS("%s : Already resumed\n", __func__); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index c414584bfbae..c187ea33b748 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -600,7 +600,7 @@ static void vp_win_reset(struct mixer_context *ctx) /* waiting until VP_SRESET_PROCESSING is 0 */ if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING) break; - usleep_range(10000, 12000); + mdelay(10); } WARN(tries == 0, "failed to reset Video Processor\n"); } @@ -776,13 +776,6 @@ static void mixer_win_commit(void *ctx, int win) DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); - mutex_lock(&mixer_ctx->mixer_mutex); - if (!mixer_ctx->powered) { - mutex_unlock(&mixer_ctx->mixer_mutex); - return; - } - mutex_unlock(&mixer_ctx->mixer_mutex); - if (win > 1 && mixer_ctx->vp_enabled) vp_video_buffer(mixer_ctx, win); else diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index b401788e1791..59afb7eb6db6 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -533,6 +533,7 @@ #define MI_MODE 0x0209c # define VS_TIMER_DISPATCH (1 << 6) # define MI_FLUSH_ENABLE (1 << 12) +# define ASYNC_FLIP_PERF_DISABLE (1 << 14) #define GEN6_GT_MODE 0x20d0 #define GEN6_GT_MODE_HI (1 << 9) diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index ae253e04c391..1f46a8bf2b05 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -505,13 +505,20 @@ static int init_render_ring(struct intel_ring_buffer *ring) struct drm_i915_private *dev_priv = dev->dev_private; int ret = init_ring_common(ring); - if (INTEL_INFO(dev)->gen > 3) { + if (INTEL_INFO(dev)->gen > 3) I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH)); - if (IS_GEN7(dev)) - I915_WRITE(GFX_MODE_GEN7, - _MASKED_BIT_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) | - _MASKED_BIT_ENABLE(GFX_REPLAY_MODE)); - } + + /* We need to disable the AsyncFlip performance optimisations in order + * to use MI_WAIT_FOR_EVENT within the CS. It should already be + * programmed to '1' on all products. + */ + if (INTEL_INFO(dev)->gen >= 6) + I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); + + if (IS_GEN7(dev)) + I915_WRITE(GFX_MODE_GEN7, + _MASKED_BIT_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) | + _MASKED_BIT_ENABLE(GFX_REPLAY_MODE)); if (INTEL_INFO(dev)->gen >= 5) { ret = init_pipe_control(ring); diff --git a/trunk/drivers/gpu/drm/radeon/ni.c b/trunk/drivers/gpu/drm/radeon/ni.c index 835992d8d067..59acabb45c9b 100644 --- a/trunk/drivers/gpu/drm/radeon/ni.c +++ b/trunk/drivers/gpu/drm/radeon/ni.c @@ -1216,7 +1216,7 @@ void cayman_dma_stop(struct radeon_device *rdev) int cayman_dma_resume(struct radeon_device *rdev) { struct radeon_ring *ring; - u32 rb_cntl, dma_cntl, ib_cntl; + u32 rb_cntl, dma_cntl; u32 rb_bufsz; u32 reg_offset, wb_offset; int i, r; @@ -1265,11 +1265,7 @@ int cayman_dma_resume(struct radeon_device *rdev) WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8); /* enable DMA IBs */ - ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE; -#ifdef __BIG_ENDIAN - ib_cntl |= DMA_IB_SWAP_ENABLE; -#endif - WREG32(DMA_IB_CNTL + reg_offset, ib_cntl); + WREG32(DMA_IB_CNTL + reg_offset, DMA_IB_ENABLE | CMD_VMID_FORCE); dma_cntl = RREG32(DMA_CNTL + reg_offset); dma_cntl &= ~CTXEMPTY_INT_ENABLE; diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index bc2540b17c5e..3cb9d6089373 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -2313,7 +2313,7 @@ void r600_dma_stop(struct radeon_device *rdev) int r600_dma_resume(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; - u32 rb_cntl, dma_cntl, ib_cntl; + u32 rb_cntl, dma_cntl; u32 rb_bufsz; int r; @@ -2353,11 +2353,7 @@ int r600_dma_resume(struct radeon_device *rdev) WREG32(DMA_RB_BASE, ring->gpu_addr >> 8); /* enable DMA IBs */ - ib_cntl = DMA_IB_ENABLE; -#ifdef __BIG_ENDIAN - ib_cntl |= DMA_IB_SWAP_ENABLE; -#endif - WREG32(DMA_IB_CNTL, ib_cntl); + WREG32(DMA_IB_CNTL, DMA_IB_ENABLE); dma_cntl = RREG32(DMA_CNTL); dma_cntl &= ~CTXEMPTY_INT_ENABLE; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cs.c b/trunk/drivers/gpu/drm/radeon/radeon_cs.c index 5407459e56d2..469661fd1903 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cs.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cs.c @@ -286,8 +286,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) p->chunks[p->chunk_ib_idx].kpage[1] == NULL) { kfree(p->chunks[p->chunk_ib_idx].kpage[0]); kfree(p->chunks[p->chunk_ib_idx].kpage[1]); - p->chunks[p->chunk_ib_idx].kpage[0] = NULL; - p->chunks[p->chunk_ib_idx].kpage[1] = NULL; return -ENOMEM; } } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cursor.c b/trunk/drivers/gpu/drm/radeon/radeon_cursor.c index 0d67674b64b1..ad6df625e8b8 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cursor.c @@ -241,8 +241,7 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, y = 0; } - /* fixed on DCE6 and newer */ - if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(rdev)) { + if (ASIC_IS_AVIVO(rdev)) { int i = 0; struct drm_crtc *crtc_p; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c index ff3def784619..1da2386d7cf7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_display.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c @@ -1122,7 +1122,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, if (ret) { kfree(radeon_fb); drm_gem_object_unreference_unlocked(obj); - return ERR_PTR(ret); + return NULL; } return &radeon_fb->base;