Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 12 Apr 2012 20:58:23 +0000 (13:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 12 Apr 2012 20:58:23 +0000 (13:58 -0700)
Pull drm fixes from Dave Airlie:
 "Mostly exynos and intel.

  Intel has 3 regression fixers (more info in intel merge commit), along
  with some other make hw work fixes, exynos has some cleanups and an
  ioctl fix.

  A couple of radeon fixes, couple of build fixes, and a savage
  userspace interface possible overflow fix."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (23 commits)
  drm/exynos: fixed exynos broken ioctl
  drm/i915: clear fencing tracking state when retiring requests
  drm/exynos: fix to pointer manager member of struct exynos_drm_subdrv
  drm/exynos: fix struct for operation callback functions to driver name
  drm/exynos: use define instead of default_win member in struct mixer_context
  drm/exynos: rename s/HDMI_OVERLAY_NUMBER/MIXER_WIN_NR
  drm/exynos: remove unused codes in hdmi and mixer
  drm/exynos: remove unnecessary type conversion of hdmi and mixer
  drm/i915: make rc6 module parameter read-only
  drm/i915: implement ColorBlt w/a
  drm/i915/ringbuffer: Exclude last 2 cachlines of ring on 845g
  Revert "drm/i915: reenable gmbus on gen3+ again"
  drm/radeon: only add the mm i2c bus if the hw_i2c module param is set
  vgaarb.h: fix build warnings
  drm/i915: properly compute dp dithering for user-created modes
  drm/radeon/kms: fix DVO setup on some r4xx chips
  drm/savage: fix integer overflows in savage_bci_cmdbuf()
  drm/radeon: replace udelay with mdelay for long timeouts
  drm/i915: Finish any pending operations on the framebuffer before disabling
  drm/i915: Removed IVB forced enable of sprite dest key.
  ...

31 files changed:
drivers/gpu/drm/exynos/exynos_drm_buf.c
drivers/gpu/drm/exynos/exynos_drm_core.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/exynos/exynos_drm_hdmi.c
drivers/gpu/drm/exynos/exynos_drm_hdmi.h
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_cp.c
drivers/gpu/drm/radeon/radeon_clocks.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/savage/savage_state.c
include/drm/exynos_drm.h
include/linux/vgaarb.h

index 4a3a5f7..de8d209 100644 (file)
 static int lowlevel_buffer_allocate(struct drm_device *dev,
                unsigned int flags, struct exynos_drm_gem_buf *buf)
 {
-       dma_addr_t start_addr, end_addr;
+       dma_addr_t start_addr;
        unsigned int npages, page_size, i = 0;
        struct scatterlist *sgl;
        int ret = 0;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (flags & EXYNOS_BO_NONCONTIG) {
+       if (IS_NONCONTIG_BUFFER(flags)) {
                DRM_DEBUG_KMS("not support allocation type.\n");
                return -EINVAL;
        }
@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
        }
 
        if (buf->size >= SZ_1M) {
-               npages = (buf->size >> SECTION_SHIFT) + 1;
+               npages = buf->size >> SECTION_SHIFT;
                page_size = SECTION_SIZE;
        } else if (buf->size >= SZ_64K) {
-               npages = (buf->size >> 16) + 1;
+               npages = buf->size >> 16;
                page_size = SZ_64K;
        } else {
-               npages = (buf->size >> PAGE_SHIFT) + 1;
+               npages = buf->size >> PAGE_SHIFT;
                page_size = PAGE_SIZE;
        }
 
@@ -76,26 +76,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
                return -ENOMEM;
        }
 
-               buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
-                               &buf->dma_addr, GFP_KERNEL);
-               if (!buf->kvaddr) {
-                       DRM_ERROR("failed to allocate buffer.\n");
-                       ret = -ENOMEM;
-                       goto err1;
-               }
-
-               start_addr = buf->dma_addr;
-               end_addr = buf->dma_addr + buf->size;
-
-               buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
-               if (!buf->pages) {
-                       DRM_ERROR("failed to allocate pages.\n");
-                       ret = -ENOMEM;
-                       goto err2;
-               }
-
-       start_addr = buf->dma_addr;
-       end_addr = buf->dma_addr + buf->size;
+       buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
+                       &buf->dma_addr, GFP_KERNEL);
+       if (!buf->kvaddr) {
+               DRM_ERROR("failed to allocate buffer.\n");
+               ret = -ENOMEM;
+               goto err1;
+       }
 
        buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
        if (!buf->pages) {
@@ -105,23 +92,17 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
        }
 
        sgl = buf->sgt->sgl;
+       start_addr = buf->dma_addr;
 
        while (i < npages) {
                buf->pages[i] = phys_to_page(start_addr);
                sg_set_page(sgl, buf->pages[i], page_size, 0);
                sg_dma_address(sgl) = start_addr;
                start_addr += page_size;
-               if (end_addr - start_addr < page_size)
-                       break;
                sgl = sg_next(sgl);
                i++;
        }
 
-       buf->pages[i] = phys_to_page(start_addr);
-
-       sgl = sg_next(sgl);
-       sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
-
        DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
                        (unsigned long)buf->kvaddr,
                        (unsigned long)buf->dma_addr,
@@ -150,7 +131,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
         * non-continuous memory would be released by exynos
         * gem framework.
         */
-       if (flags & EXYNOS_BO_NONCONTIG) {
+       if (IS_NONCONTIG_BUFFER(flags)) {
                DRM_DEBUG_KMS("not support allocation type.\n");
                return;
        }
index 411832e..eaf630d 100644 (file)
@@ -54,16 +54,18 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
                 *
                 * P.S. note that this driver is considered for modularization.
                 */
-               ret = subdrv->probe(dev, subdrv->manager.dev);
+               ret = subdrv->probe(dev, subdrv->dev);
                if (ret)
                        return ret;
        }
 
-       if (subdrv->is_local)
+       if (!subdrv->manager)
                return 0;
 
+       subdrv->manager->dev = subdrv->dev;
+
        /* create and initialize a encoder for this sub driver. */
-       encoder = exynos_drm_encoder_create(dev, &subdrv->manager,
+       encoder = exynos_drm_encoder_create(dev, subdrv->manager,
                        (1 << MAX_CRTC) - 1);
        if (!encoder) {
                DRM_ERROR("failed to create encoder\n");
@@ -186,7 +188,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
 
        list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
                if (subdrv->open) {
-                       ret = subdrv->open(dev, subdrv->manager.dev, file);
+                       ret = subdrv->open(dev, subdrv->dev, file);
                        if (ret)
                                goto err;
                }
@@ -197,7 +199,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
 err:
        list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
                if (subdrv->close)
-                       subdrv->close(dev, subdrv->manager.dev, file);
+                       subdrv->close(dev, subdrv->dev, file);
        }
        return ret;
 }
@@ -209,7 +211,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
 
        list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
                if (subdrv->close)
-                       subdrv->close(dev, subdrv->manager.dev, file);
+                       subdrv->close(dev, subdrv->dev, file);
        }
 }
 EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close);
index fbd0a23..1d81417 100644 (file)
@@ -225,24 +225,25 @@ struct exynos_drm_private {
  * Exynos drm sub driver structure.
  *
  * @list: sub driver has its own list object to register to exynos drm driver.
+ * @dev: pointer to device object for subdrv device driver.
  * @drm_dev: pointer to drm_device and this pointer would be set
  *     when sub driver calls exynos_drm_subdrv_register().
- * @is_local: appear encoder and connector disrelated device.
+ * @manager: subdrv has its own manager to control a hardware appropriately
+ *     and we can access a hardware drawing on this manager.
  * @probe: this callback would be called by exynos drm driver after
  *     subdrv is registered to it.
  * @remove: this callback is used to release resources created
  *     by probe callback.
  * @open: this would be called with drm device file open.
  * @close: this would be called with drm device file close.
- * @manager: subdrv has its own manager to control a hardware appropriately
- *     and we can access a hardware drawing on this manager.
  * @encoder: encoder object owned by this sub driver.
  * @connector: connector object owned by this sub driver.
  */
 struct exynos_drm_subdrv {
        struct list_head list;
+       struct device *dev;
        struct drm_device *drm_dev;
-       bool is_local;
+       struct exynos_drm_manager *manager;
 
        int (*probe)(struct drm_device *drm_dev, struct device *dev);
        void (*remove)(struct drm_device *dev);
@@ -251,7 +252,6 @@ struct exynos_drm_subdrv {
        void (*close)(struct drm_device *drm_dev, struct device *dev,
                        struct drm_file *file);
 
-       struct exynos_drm_manager manager;
        struct drm_encoder *encoder;
        struct drm_connector *connector;
 };
index ecb6db2..29fdbfe 100644 (file)
@@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
 static void fimd_apply(struct device *subdrv_dev)
 {
        struct fimd_context *ctx = get_fimd_context(subdrv_dev);
-       struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
+       struct exynos_drm_manager *mgr = ctx->subdrv.manager;
        struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
        struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
        struct fimd_win_data *win_data;
@@ -577,6 +577,13 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = {
        .disable = fimd_win_disable,
 };
 
+static struct exynos_drm_manager fimd_manager = {
+       .pipe           = -1,
+       .ops            = &fimd_manager_ops,
+       .overlay_ops    = &fimd_overlay_ops,
+       .display_ops    = &fimd_display_ops,
+};
+
 static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
 {
        struct exynos_drm_private *dev_priv = drm_dev->dev_private;
@@ -628,7 +635,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
        struct fimd_context *ctx = (struct fimd_context *)dev_id;
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
        struct drm_device *drm_dev = subdrv->drm_dev;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
        u32 val;
 
        val = readl(ctx->regs + VIDINTCON1);
@@ -744,7 +751,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
 static int fimd_power_on(struct fimd_context *ctx, bool enable)
 {
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct device *dev = subdrv->manager.dev;
+       struct device *dev = subdrv->dev;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -867,13 +874,10 @@ static int __devinit fimd_probe(struct platform_device *pdev)
 
        subdrv = &ctx->subdrv;
 
+       subdrv->dev = dev;
+       subdrv->manager = &fimd_manager;
        subdrv->probe = fimd_subdrv_probe;
        subdrv->remove = fimd_subdrv_remove;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &fimd_manager_ops;
-       subdrv->manager.overlay_ops = &fimd_overlay_ops;
-       subdrv->manager.display_ops = &fimd_display_ops;
-       subdrv->manager.dev = dev;
 
        mutex_init(&ctx->lock);
 
index fa1aa94..26d5197 100644 (file)
@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg)
        return out_msg;
 }
 
-static unsigned int mask_gem_flags(unsigned int flags)
+static int check_gem_flags(unsigned int flags)
 {
-       return flags &= EXYNOS_BO_NONCONTIG;
+       if (flags & ~(EXYNOS_BO_MASK)) {
+               DRM_ERROR("invalid flags.\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
+{
+       if (!IS_NONCONTIG_BUFFER(flags)) {
+               if (size >= SZ_1M)
+                       return roundup(size, SECTION_SIZE);
+               else if (size >= SZ_64K)
+                       return roundup(size, SZ_64K);
+               else
+                       goto out;
+       }
+out:
+       return roundup(size, PAGE_SIZE);
 }
 
 static struct page **exynos_gem_get_pages(struct drm_gem_object *obj,
@@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
        struct exynos_drm_gem_buf *buf;
        int ret;
 
-       size = roundup(size, PAGE_SIZE);
-       DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
+       if (!size) {
+               DRM_ERROR("invalid size.\n");
+               return ERR_PTR(-EINVAL);
+       }
 
-       flags = mask_gem_flags(flags);
+       size = roundup_gem_size(size, flags);
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       ret = check_gem_flags(flags);
+       if (ret)
+               return ERR_PTR(ret);
 
        buf = exynos_drm_init_buf(dev, size);
        if (!buf)
@@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
        exynos_gem_obj = exynos_drm_gem_init(dev, size);
        if (!exynos_gem_obj) {
                ret = -ENOMEM;
-               goto err;
+               goto err_fini_buf;
        }
 
        exynos_gem_obj->buffer = buf;
@@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
                ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);
                if (ret < 0) {
                        drm_gem_object_release(&exynos_gem_obj->base);
-                       goto err;
+                       goto err_fini_buf;
                }
        } else {
                ret = exynos_drm_alloc_buf(dev, buf, flags);
                if (ret < 0) {
                        drm_gem_object_release(&exynos_gem_obj->base);
-                       goto err;
+                       goto err_fini_buf;
                }
        }
 
        return exynos_gem_obj;
-err:
+
+err_fini_buf:
        exynos_drm_fini_buf(dev, buf);
        return ERR_PTR(ret);
 }
index e40fbad..4ed8420 100644 (file)
@@ -29,6 +29,8 @@
 #define to_exynos_gem_obj(x)   container_of(x,\
                        struct exynos_drm_gem_obj, base)
 
+#define IS_NONCONTIG_BUFFER(f)         (f & EXYNOS_BO_NONCONTIG)
+
 /*
  * exynos drm gem buffer structure.
  *
index 14eb26b..3424463 100644 (file)
@@ -30,9 +30,8 @@
                                        struct drm_hdmi_context, subdrv);
 
 /* these callback points shoud be set by specific drivers. */
-static struct exynos_hdmi_display_ops *hdmi_display_ops;
-static struct exynos_hdmi_manager_ops *hdmi_manager_ops;
-static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops;
+static struct exynos_hdmi_ops *hdmi_ops;
+static struct exynos_mixer_ops *mixer_ops;
 
 struct drm_hdmi_context {
        struct exynos_drm_subdrv        subdrv;
@@ -40,31 +39,20 @@ struct drm_hdmi_context {
        struct exynos_drm_hdmi_context  *mixer_ctx;
 };
 
-void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
-                                       *display_ops)
+void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
 {
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (display_ops)
-               hdmi_display_ops = display_ops;
+       if (ops)
+               hdmi_ops = ops;
 }
 
-void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
-                                       *manager_ops)
+void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
 {
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (manager_ops)
-               hdmi_manager_ops = manager_ops;
-}
-
-void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
-                                       *overlay_ops)
-{
-       DRM_DEBUG_KMS("%s\n", __FILE__);
-
-       if (overlay_ops)
-               hdmi_overlay_ops = overlay_ops;
+       if (ops)
+               mixer_ops = ops;
 }
 
 static bool drm_hdmi_is_connected(struct device *dev)
@@ -73,8 +61,8 @@ static bool drm_hdmi_is_connected(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->is_connected)
-               return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx);
+       if (hdmi_ops && hdmi_ops->is_connected)
+               return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
 
        return false;
 }
@@ -86,9 +74,9 @@ static int drm_hdmi_get_edid(struct device *dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->get_edid)
-               return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx,
-                               connector, edid, len);
+       if (hdmi_ops && hdmi_ops->get_edid)
+               return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid,
+                                         len);
 
        return 0;
 }
@@ -99,9 +87,8 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->check_timing)
-               return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx,
-                               timing);
+       if (hdmi_ops && hdmi_ops->check_timing)
+               return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
 
        return 0;
 }
@@ -112,8 +99,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->power_on)
-               return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode);
+       if (hdmi_ops && hdmi_ops->power_on)
+               return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode);
 
        return 0;
 }
@@ -130,13 +117,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev)
 {
        struct drm_hdmi_context *ctx = to_context(subdrv_dev);
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank)
-               return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx,
-                                                       manager->pipe);
+       if (mixer_ops && mixer_ops->enable_vblank)
+               return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
+                                               manager->pipe);
 
        return 0;
 }
@@ -147,8 +134,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank)
-               return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx);
+       if (mixer_ops && mixer_ops->disable_vblank)
+               return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
 }
 
 static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
@@ -160,9 +147,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup)
-               hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector,
-                                               mode, adjusted_mode);
+       if (hdmi_ops && hdmi_ops->mode_fixup)
+               hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode,
+                                    adjusted_mode);
 }
 
 static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
@@ -171,8 +158,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->mode_set)
-               hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
+       if (hdmi_ops && hdmi_ops->mode_set)
+               hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
 }
 
 static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
@@ -182,9 +169,8 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol)
-               hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width,
-                                                       height);
+       if (hdmi_ops && hdmi_ops->get_max_resol)
+               hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
 }
 
 static void drm_hdmi_commit(struct device *subdrv_dev)
@@ -193,8 +179,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->commit)
-               hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx);
+       if (hdmi_ops && hdmi_ops->commit)
+               hdmi_ops->commit(ctx->hdmi_ctx->ctx);
 }
 
 static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
@@ -209,8 +195,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               if (hdmi_manager_ops && hdmi_manager_ops->disable)
-                       hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx);
+               if (hdmi_ops && hdmi_ops->disable)
+                       hdmi_ops->disable(ctx->hdmi_ctx->ctx);
                break;
        default:
                DRM_DEBUG_KMS("unkown dps mode: %d\n", mode);
@@ -235,8 +221,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set)
-               hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
+       if (mixer_ops && mixer_ops->win_mode_set)
+               mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
 }
 
 static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
@@ -245,8 +231,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit)
-               hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
+       if (mixer_ops && mixer_ops->win_commit)
+               mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
 }
 
 static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
@@ -255,8 +241,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable)
-               hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
+       if (mixer_ops && mixer_ops->win_disable)
+               mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
 }
 
 static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
@@ -265,6 +251,12 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
        .disable = drm_mixer_disable,
 };
 
+static struct exynos_drm_manager hdmi_manager = {
+       .pipe           = -1,
+       .ops            = &drm_hdmi_manager_ops,
+       .overlay_ops    = &drm_hdmi_overlay_ops,
+       .display_ops    = &drm_hdmi_display_ops,
+};
 
 static int hdmi_subdrv_probe(struct drm_device *drm_dev,
                struct device *dev)
@@ -332,12 +324,9 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
 
        subdrv = &ctx->subdrv;
 
+       subdrv->dev = dev;
+       subdrv->manager = &hdmi_manager;
        subdrv->probe = hdmi_subdrv_probe;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &drm_hdmi_manager_ops;
-       subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops;
-       subdrv->manager.display_ops = &drm_hdmi_display_ops;
-       subdrv->manager.dev = dev;
 
        platform_set_drvdata(pdev, subdrv);
 
index 44497cf..f3ae192 100644 (file)
@@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context {
        void                    *ctx;
 };
 
-struct exynos_hdmi_display_ops {
+struct exynos_hdmi_ops {
+       /* display */
        bool (*is_connected)(void *ctx);
        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);
-};
 
-struct exynos_hdmi_manager_ops {
+       /* manager */
        void (*mode_fixup)(void *ctx, struct drm_connector *connector,
                                struct drm_display_mode *mode,
                                struct drm_display_mode *adjusted_mode);
@@ -57,22 +57,17 @@ struct exynos_hdmi_manager_ops {
        void (*disable)(void *ctx);
 };
 
-struct exynos_hdmi_overlay_ops {
+struct exynos_mixer_ops {
+       /* manager */
        int (*enable_vblank)(void *ctx, int pipe);
        void (*disable_vblank)(void *ctx);
+
+       /* overlay */
        void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
        void (*win_commit)(void *ctx, int zpos);
        void (*win_disable)(void *ctx, int zpos);
 };
 
-extern struct platform_driver hdmi_driver;
-extern struct platform_driver mixer_driver;
-
-void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
-                                       *display_ops);
-void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
-                                       *manager_ops);
-void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
-                                       *overlay_ops);
-
+void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
+void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
 #endif
index c277a3a..f92fe4c 100644 (file)
@@ -24,6 +24,10 @@ struct exynos_plane {
 
 static const uint32_t formats[] = {
        DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_NV12,
+       DRM_FORMAT_NV12M,
+       DRM_FORMAT_NV12MT,
 };
 
 static int
index 8e1339f..7b9c153 100644 (file)
@@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode)
 static void vidi_apply(struct device *subdrv_dev)
 {
        struct vidi_context *ctx = get_vidi_context(subdrv_dev);
-       struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
+       struct exynos_drm_manager *mgr = ctx->subdrv.manager;
        struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
        struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
        struct vidi_win_data *win_data;
@@ -374,6 +374,13 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = {
        .disable = vidi_win_disable,
 };
 
+static struct exynos_drm_manager vidi_manager = {
+       .pipe           = -1,
+       .ops            = &vidi_manager_ops,
+       .overlay_ops    = &vidi_overlay_ops,
+       .display_ops    = &vidi_display_ops,
+};
+
 static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc)
 {
        struct exynos_drm_private *dev_priv = drm_dev->dev_private;
@@ -425,7 +432,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
        struct vidi_context *ctx = container_of(work, struct vidi_context,
                                        work);
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
 
        if (manager->pipe < 0)
                return;
@@ -471,7 +478,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev)
 static int vidi_power_on(struct vidi_context *ctx, bool enable)
 {
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct device *dev = subdrv->manager.dev;
+       struct device *dev = subdrv->dev;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -611,13 +618,10 @@ static int __devinit vidi_probe(struct platform_device *pdev)
        ctx->raw_edid = (struct edid *)fake_edid_info;
 
        subdrv = &ctx->subdrv;
+       subdrv->dev = dev;
+       subdrv->manager = &vidi_manager;
        subdrv->probe = vidi_subdrv_probe;
        subdrv->remove = vidi_subdrv_remove;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &vidi_manager_ops;
-       subdrv->manager.overlay_ops = &vidi_overlay_ops;
-       subdrv->manager.display_ops = &vidi_display_ops;
-       subdrv->manager.dev = dev;
 
        mutex_init(&ctx->lock);
 
index 575a8cb..b003538 100644 (file)
@@ -40,7 +40,6 @@
 
 #include "exynos_hdmi.h"
 
-#define HDMI_OVERLAY_NUMBER    3
 #define MAX_WIDTH              1920
 #define MAX_HEIGHT             1080
 #define get_hdmi_context(dev)  platform_get_drvdata(to_platform_device(dev))
@@ -1194,7 +1193,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata,
 
 static bool hdmi_is_connected(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
 
        if (val)
@@ -1207,7 +1206,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
                                u8 *edid, int len)
 {
        struct edid *raw_edid;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1275,7 +1274,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
 
 static int hdmi_check_timing(void *ctx, void *timing)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        struct fb_videomode *check_timing = timing;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1312,13 +1311,6 @@ static int hdmi_display_power_on(void *ctx, int mode)
        return 0;
 }
 
-static struct exynos_hdmi_display_ops display_ops = {
-       .is_connected   = hdmi_is_connected,
-       .get_edid       = hdmi_get_edid,
-       .check_timing   = hdmi_check_timing,
-       .power_on       = hdmi_display_power_on,
-};
-
 static void hdmi_set_acr(u32 freq, u8 *acr)
 {
        u32 n, cts;
@@ -1914,7 +1906,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
                                struct drm_display_mode *adjusted_mode)
 {
        struct drm_display_mode *m;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        int index;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1951,7 +1943,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
 
 static void hdmi_mode_set(void *ctx, void *mode)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        int conf_idx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1974,7 +1966,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width,
 
 static void hdmi_commit(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1985,7 +1977,7 @@ static void hdmi_commit(void *ctx)
 
 static void hdmi_disable(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1996,7 +1988,14 @@ static void hdmi_disable(void *ctx)
        }
 }
 
-static struct exynos_hdmi_manager_ops manager_ops = {
+static struct exynos_hdmi_ops hdmi_ops = {
+       /* display */
+       .is_connected   = hdmi_is_connected,
+       .get_edid       = hdmi_get_edid,
+       .check_timing   = hdmi_check_timing,
+       .power_on       = hdmi_display_power_on,
+
+       /* manager */
        .mode_fixup     = hdmi_mode_fixup,
        .mode_set       = hdmi_mode_set,
        .get_max_resol  = hdmi_get_max_resol,
@@ -2020,7 +2019,7 @@ static void hdmi_hotplug_func(struct work_struct *work)
 static irqreturn_t hdmi_irq_handler(int irq, void *arg)
 {
        struct exynos_drm_hdmi_context *ctx = arg;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
+       struct hdmi_context *hdata = ctx->ctx;
        u32 intc_flag;
 
        intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
@@ -2173,7 +2172,7 @@ static int hdmi_runtime_suspend(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __func__);
 
-       hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx);
+       hdmi_resource_poweroff(ctx->ctx);
 
        return 0;
 }
@@ -2184,7 +2183,7 @@ static int hdmi_runtime_resume(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __func__);
 
-       hdmi_resource_poweron((struct hdmi_context *)ctx->ctx);
+       hdmi_resource_poweron(ctx->ctx);
 
        return 0;
 }
@@ -2322,8 +2321,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
        hdata->irq = res->start;
 
        /* register specific callbacks to common hdmi. */
-       exynos_drm_display_ops_register(&display_ops);
-       exynos_drm_manager_ops_register(&manager_ops);
+       exynos_hdmi_ops_register(&hdmi_ops);
 
        hdmi_resource_poweron(hdata);
 
@@ -2351,7 +2349,7 @@ err_data:
 static int __devexit hdmi_remove(struct platform_device *pdev)
 {
        struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
+       struct hdmi_context *hdata = ctx->ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
index 4d5f41e..e15438c 100644 (file)
@@ -37,7 +37,8 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_hdmi.h"
 
-#define HDMI_OVERLAY_NUMBER    3
+#define MIXER_WIN_NR           3
+#define MIXER_DEFAULT_WIN      0
 
 #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
 
@@ -75,16 +76,12 @@ struct mixer_resources {
 };
 
 struct mixer_context {
-       struct fb_videomode     *default_timing;
-       unsigned int            default_win;
-       unsigned int            default_bpp;
        unsigned int            irq;
        int                     pipe;
        bool                    interlace;
-       bool                    vp_enabled;
 
        struct mixer_resources  mixer_res;
-       struct hdmi_win_data    win_data[HDMI_OVERLAY_NUMBER];
+       struct hdmi_win_data    win_data[MIXER_WIN_NR];
 };
 
 static const u8 filter_y_horiz_tap8[] = {
@@ -643,9 +640,9 @@ static void mixer_win_mode_set(void *ctx,
 
        win = overlay->zpos;
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -683,9 +680,9 @@ static void mixer_win_commit(void *ctx, int zpos)
        DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -706,9 +703,9 @@ static void mixer_win_disable(void *ctx, int zpos)
        DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -722,9 +719,12 @@ static void mixer_win_disable(void *ctx, int zpos)
        spin_unlock_irqrestore(&res->reg_slock, flags);
 }
 
-static struct exynos_hdmi_overlay_ops overlay_ops = {
+static struct exynos_mixer_ops mixer_ops = {
+       /* manager */
        .enable_vblank          = mixer_enable_vblank,
        .disable_vblank         = mixer_disable_vblank,
+
+       /* overlay */
        .win_mode_set           = mixer_win_mode_set,
        .win_commit             = mixer_win_commit,
        .win_disable            = mixer_win_disable,
@@ -771,8 +771,7 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
 static irqreturn_t mixer_irq_handler(int irq, void *arg)
 {
        struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
-       struct mixer_context *ctx =
-                       (struct mixer_context *)drm_hdmi_ctx->ctx;
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
        struct mixer_resources *res = &ctx->mixer_res;
        u32 val, val_base;
 
@@ -902,7 +901,7 @@ static int mixer_runtime_resume(struct device *dev)
 
        DRM_DEBUG_KMS("resume - start\n");
 
-       mixer_resource_poweron((struct mixer_context *)ctx->ctx);
+       mixer_resource_poweron(ctx->ctx);
 
        return 0;
 }
@@ -913,7 +912,7 @@ static int mixer_runtime_suspend(struct device *dev)
 
        DRM_DEBUG_KMS("suspend - start\n");
 
-       mixer_resource_poweroff((struct mixer_context *)ctx->ctx);
+       mixer_resource_poweroff(ctx->ctx);
 
        return 0;
 }
@@ -926,8 +925,7 @@ static const struct dev_pm_ops mixer_pm_ops = {
 static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
                                 struct platform_device *pdev)
 {
-       struct mixer_context *mixer_ctx =
-                       (struct mixer_context *)ctx->ctx;
+       struct mixer_context *mixer_ctx = ctx->ctx;
        struct device *dev = &pdev->dev;
        struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
        struct resource *res;
@@ -1076,7 +1074,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
                goto fail;
 
        /* register specific callback point to common hdmi. */
-       exynos_drm_overlay_ops_register(&overlay_ops);
+       exynos_mixer_ops_register(&mixer_ops);
 
        mixer_resource_poweron(ctx);
 
@@ -1093,7 +1091,7 @@ static int mixer_remove(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct exynos_drm_hdmi_context *drm_hdmi_ctx =
                                        platform_get_drvdata(pdev);
-       struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx;
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
 
        dev_info(dev, "remove successful\n");
 
index dfa55e7..ae8a64f 100644 (file)
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(semaphores,
                "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
 
 int i915_enable_rc6 __read_mostly = -1;
-module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
+module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
 MODULE_PARM_DESC(i915_enable_rc6,
                "Enable power-saving render C-state 6. "
                "Different stages can be selected via bitmask values "
index 4c65c63..0e3c6ac 100644 (file)
@@ -1493,6 +1493,7 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj)
 {
        list_del_init(&obj->ring_list);
        obj->last_rendering_seqno = 0;
+       obj->last_fenced_seqno = 0;
 }
 
 static void
@@ -1521,6 +1522,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
        BUG_ON(!list_empty(&obj->gpu_write_list));
        BUG_ON(!obj->active);
        obj->ring = NULL;
+       obj->last_fenced_ring = NULL;
 
        i915_gem_object_move_off_active(obj);
        obj->fenced_gpu_access = false;
index 2abf4eb..b4bb1ef 100644 (file)
 #define  GT_FIFO_FREE_ENTRIES                  0x120008
 #define    GT_FIFO_NUM_RESERVED_ENTRIES                20
 
+#define GEN6_UCGCTL1                           0x9400
+# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE               (1 << 5)
+
 #define GEN6_UCGCTL2                           0x9404
 # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE               (1 << 13)
 # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE              (1 << 12)
index 91b35fd..bae38ac 100644 (file)
@@ -2245,6 +2245,33 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 }
 
 static int
+intel_finish_fb(struct drm_framebuffer *old_fb)
+{
+       struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
+       struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+       bool was_interruptible = dev_priv->mm.interruptible;
+       int ret;
+
+       wait_event(dev_priv->pending_flip_queue,
+                  atomic_read(&dev_priv->mm.wedged) ||
+                  atomic_read(&obj->pending_flip) == 0);
+
+       /* Big Hammer, we also need to ensure that any pending
+        * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+        * current scanout is retired before unpinning the old
+        * framebuffer.
+        *
+        * This should only fail upon a hung GPU, in which case we
+        * can safely continue.
+        */
+       dev_priv->mm.interruptible = false;
+       ret = i915_gem_object_finish_gpu(obj);
+       dev_priv->mm.interruptible = was_interruptible;
+
+       return ret;
+}
+
+static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                    struct drm_framebuffer *old_fb)
 {
@@ -2282,25 +2309,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                return ret;
        }
 
-       if (old_fb) {
-               struct drm_i915_private *dev_priv = dev->dev_private;
-               struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
-
-               wait_event(dev_priv->pending_flip_queue,
-                          atomic_read(&dev_priv->mm.wedged) ||
-                          atomic_read(&obj->pending_flip) == 0);
-
-               /* Big Hammer, we also need to ensure that any pending
-                * MI_WAIT_FOR_EVENT inside a user batch buffer on the
-                * current scanout is retired before unpinning the old
-                * framebuffer.
-                *
-                * This should only fail upon a hung GPU, in which case we
-                * can safely continue.
-                */
-               ret = i915_gem_object_finish_gpu(obj);
-               (void) ret;
-       }
+       if (old_fb)
+               intel_finish_fb(old_fb);
 
        ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
                                         LEAVE_ATOMIC_MODE_SET);
@@ -3371,6 +3381,23 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
        struct drm_device *dev = crtc->dev;
 
+       /* Flush any pending WAITs before we disable the pipe. Note that
+        * we need to drop the struct_mutex in order to acquire it again
+        * during the lowlevel dpms routines around a couple of the
+        * operations. It does not look trivial nor desirable to move
+        * that locking higher. So instead we leave a window for the
+        * submission of further commands on the fb before we can actually
+        * disable it. This race with userspace exists anyway, and we can
+        * only rely on the pipe being disabled by userspace after it
+        * receives the hotplug notification and has flushed any pending
+        * batches.
+        */
+       if (crtc->fb) {
+               mutex_lock(&dev->struct_mutex);
+               intel_finish_fb(crtc->fb);
+               mutex_unlock(&dev->struct_mutex);
+       }
+
        crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
        assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
        assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
@@ -8529,6 +8556,10 @@ static void gen6_init_clock_gating(struct drm_device *dev)
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
 
+       I915_WRITE(GEN6_UCGCTL1,
+                  I915_READ(GEN6_UCGCTL1) |
+                  GEN6_BLBUNIT_CLOCK_GATE_DISABLE);
+
        /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
         * gating disable must be set.  Failure to set it results in
         * flickering pixels due to Z write ordering failures after
index 110552f..4b63791 100644 (file)
@@ -219,14 +219,38 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
        return (max_link_clock * max_lanes * 8) / 10;
 }
 
+static bool
+intel_dp_adjust_dithering(struct intel_dp *intel_dp,
+                         struct drm_display_mode *mode,
+                         struct drm_display_mode *adjusted_mode)
+{
+       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
+       int max_lanes = intel_dp_max_lane_count(intel_dp);
+       int max_rate, mode_rate;
+
+       mode_rate = intel_dp_link_required(mode->clock, 24);
+       max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+
+       if (mode_rate > max_rate) {
+               mode_rate = intel_dp_link_required(mode->clock, 18);
+               if (mode_rate > max_rate)
+                       return false;
+
+               if (adjusted_mode)
+                       adjusted_mode->private_flags
+                               |= INTEL_MODE_DP_FORCE_6BPC;
+
+               return true;
+       }
+
+       return true;
+}
+
 static int
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
-       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
-       int max_lanes = intel_dp_max_lane_count(intel_dp);
-       int max_rate, mode_rate;
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
                if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
@@ -236,16 +260,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
                        return MODE_PANEL;
        }
 
-       mode_rate = intel_dp_link_required(mode->clock, 24);
-       max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
-
-       if (mode_rate > max_rate) {
-                       mode_rate = intel_dp_link_required(mode->clock, 18);
-                       if (mode_rate > max_rate)
-                               return MODE_CLOCK_HIGH;
-                       else
-                               mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC;
-       }
+       if (!intel_dp_adjust_dithering(intel_dp, mode, NULL))
+               return MODE_CLOCK_HIGH;
 
        if (mode->clock < 10000)
                return MODE_CLOCK_LOW;
@@ -672,7 +688,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
        int lane_count, clock;
        int max_lane_count = intel_dp_max_lane_count(intel_dp);
        int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
-       int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+       int bpp;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
@@ -686,6 +702,11 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                mode->clock = intel_dp->panel_fixed_mode->clock;
        }
 
+       if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode))
+               return false;
+
+       bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
index 601c86e..8fdc957 100644 (file)
@@ -390,7 +390,7 @@ int intel_setup_gmbus(struct drm_device *dev)
                bus->has_gpio = intel_gpio_setup(bus, i);
 
                /* XXX force bit banging until GMBUS is fully debugged */
-               if (bus->has_gpio && IS_GEN2(dev))
+               if (bus->has_gpio)
                        bus->force_bit = true;
        }
 
index e25581a..f75806e 100644 (file)
@@ -1038,7 +1038,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
         * of the buffer.
         */
        ring->effective_size = ring->size;
-       if (IS_I830(ring->dev))
+       if (IS_I830(ring->dev) || IS_845G(ring->dev))
                ring->effective_size -= 128;
 
        return 0;
index a464771..e90dfb6 100644 (file)
@@ -95,7 +95,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
        /* must disable */
        sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
        sprctl |= SPRITE_ENABLE;
-       sprctl |= SPRITE_DEST_KEY;
 
        /* Sizes are 0 based */
        src_w--;
index e607c4d..2d39f99 100644 (file)
@@ -230,6 +230,10 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
                return;
 
+       /* some R4xx chips have the wrong frev */
+       if (rdev->family <= CHIP_RV410)
+               frev = 1;
+
        switch (frev) {
        case 1:
                switch (crev) {
index 81801c1..fe33d35 100644 (file)
@@ -2553,7 +2553,7 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev)
         * or the chip could hang on a subsequent access
         */
        if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) {
-               udelay(5000);
+               mdelay(5);
        }
 
        /* This function is required to workaround a hardware bug in some (all?)
index 391bd26..de71243 100644 (file)
@@ -2839,7 +2839,7 @@ void r600_rlc_stop(struct radeon_device *rdev)
                /* r7xx asics need to soft reset RLC before halting */
                WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
                RREG32(SRBM_SOFT_RESET);
-               udelay(15000);
+               mdelay(15);
                WREG32(SRBM_SOFT_RESET, 0);
                RREG32(SRBM_SOFT_RESET);
        }
index 84c5462..75ed17c 100644 (file)
@@ -407,7 +407,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
        fw_data = (const __be32 *)dev_priv->me_fw->data;
@@ -500,7 +500,7 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
        fw_data = (const __be32 *)dev_priv->pfp_fw->data;
@@ -1797,7 +1797,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
 
index 6ae0c75..9c6b29a 100644 (file)
@@ -633,7 +633,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp &= ~(R300_SCLK_FORCE_VAP);
                                tmp |= RADEON_SCLK_FORCE_CP;
                                WREG32_PLL(RADEON_SCLK_CNTL, tmp);
-                               udelay(15000);
+                               mdelay(15);
 
                                tmp = RREG32_PLL(R300_SCLK_CNTL2);
                                tmp &= ~(R300_SCLK_FORCE_TCL |
@@ -651,12 +651,12 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                        tmp |= (RADEON_ENGIN_DYNCLK_MODE |
                                (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
                        WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
                        tmp |= RADEON_SCLK_DYN_START_CNTL;
                        WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
                           to lockup randomly, leave them as set by BIOS.
@@ -696,7 +696,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                        tmp |= RADEON_SCLK_MORE_FORCEON;
                                }
                                WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
-                               udelay(15000);
+                               mdelay(15);
                        }
 
                        /* RV200::A11 A12, RV250::A11 A12 */
@@ -709,7 +709,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp |= RADEON_TCL_BYPASS_DISABLE;
                                WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
                        }
-                       udelay(15000);
+                       mdelay(15);
 
                        /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */
                        tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -722,14 +722,14 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                RADEON_PIXCLK_TMDS_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
                        tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
                                RADEON_PIXCLK_DAC_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
                }
        } else {
                /* Turn everything OFF (ForceON to everything) */
@@ -861,7 +861,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                        }
                        WREG32_PLL(RADEON_SCLK_CNTL, tmp);
 
-                       udelay(16000);
+                       mdelay(16);
 
                        if ((rdev->family == CHIP_R300) ||
                            (rdev->family == CHIP_R350)) {
@@ -870,7 +870,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                        R300_SCLK_FORCE_GA |
                                        R300_SCLK_FORCE_CBA);
                                WREG32_PLL(R300_SCLK_CNTL2, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        if (rdev->flags & RADEON_IS_IGP) {
@@ -878,7 +878,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp &= ~(RADEON_FORCEON_MCLKA |
                                         RADEON_FORCEON_YCLKA);
                                WREG32_PLL(RADEON_MCLK_CNTL, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        if ((rdev->family == CHIP_RV200) ||
@@ -887,7 +887,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
                                tmp |= RADEON_SCLK_MORE_FORCEON;
                                WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -900,7 +900,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                 RADEON_PIXCLK_TMDS_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
-                       udelay(16000);
+                       mdelay(16);
 
                        tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
                        tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
index 81fc100..2cad9fd 100644 (file)
@@ -2845,7 +2845,7 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
                                        case 4:
                                                val = RBIOS16(index);
                                                index += 2;
-                                               udelay(val * 1000);
+                                               mdelay(val);
                                                break;
                                        case 6:
                                                slave_addr = id & 0xff;
@@ -3044,7 +3044,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
                                        udelay(150);
                                        break;
                                case 2:
-                                       udelay(1000);
+                                       mdelay(1);
                                        break;
                                case 3:
                                        while (tmp--) {
@@ -3075,13 +3075,13 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
                                                /*mclk_cntl |= 0x00001111;*//* ??? */
                                                WREG32_PLL(RADEON_MCLK_CNTL,
                                                           mclk_cntl);
-                                               udelay(10000);
+                                               mdelay(10);
 #endif
                                                WREG32_PLL
                                                    (RADEON_CLK_PWRMGT_CNTL,
                                                     tmp &
                                                     ~RADEON_CG_NO1_DEBUG_0);
-                                               udelay(10000);
+                                               mdelay(10);
                                        }
                                        break;
                                default:
index 85bcfc8..3edec1c 100644 (file)
@@ -900,6 +900,10 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
        struct radeon_i2c_chan *i2c;
        int ret;
 
+       /* don't add the mm_i2c bus unless hw_i2c is enabled */
+       if (rec->mm_i2c && (radeon_hw_i2c == 0))
+               return NULL;
+
        i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
        if (i2c == NULL)
                return NULL;
index 2f46e0c..42db254 100644 (file)
@@ -88,7 +88,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
                lvds_pll_cntl |= RADEON_LVDS_PLL_EN;
                WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
-               udelay(1000);
+               mdelay(1);
 
                lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
                lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
@@ -101,7 +101,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                                  (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT));
                if (is_mac)
                        lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                break;
        case DRM_MODE_DPMS_STANDBY:
@@ -118,10 +118,10 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                        WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                        lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
                }
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                break;
        }
 
@@ -656,7 +656,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
 
        WREG32(RADEON_DAC_MACRO_CNTL, tmp);
 
-       udelay(2000);
+       mdelay(2);
 
        if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT)
                found = connector_status_connected;
@@ -1499,7 +1499,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
        tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
        WREG32(RADEON_DAC_CNTL2, tmp);
 
-       udelay(10000);
+       mdelay(10);
 
        if (ASIC_IS_R300(rdev)) {
                if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B)
index 031aaaf..b6d8608 100644 (file)
@@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
         * for locking on FreeBSD.
         */
        if (cmdbuf->size) {
-               kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL);
+               kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL);
                if (kcmd_addr == NULL)
                        return -ENOMEM;
 
@@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
                cmdbuf->vb_addr = kvb_addr;
        }
        if (cmdbuf->nbox) {
-               kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect),
-                                   GFP_KERNEL);
+               kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect),
+                                         GFP_KERNEL);
                if (kbox_addr == NULL) {
                        ret = -ENOMEM;
                        goto done;
index 3963116..e478de4 100644 (file)
@@ -85,7 +85,7 @@ struct drm_exynos_gem_mmap {
 struct drm_exynos_vidi_connection {
        unsigned int connection;
        unsigned int extensions;
-       uint64_t *edid;
+       uint64_t edid;
 };
 
 struct drm_exynos_plane_set_zpos {
@@ -96,7 +96,8 @@ struct drm_exynos_plane_set_zpos {
 /* memory type definitions. */
 enum e_drm_exynos_gem_mem_type {
        /* Physically Non-Continuous memory. */
-       EXYNOS_BO_NONCONTIG     = 1 << 0
+       EXYNOS_BO_NONCONTIG     = 1 << 0,
+       EXYNOS_BO_MASK          = EXYNOS_BO_NONCONTIG
 };
 
 #define DRM_EXYNOS_GEM_CREATE          0x00
index 9c3120d..b572f80 100644 (file)
@@ -47,6 +47,8 @@
  */
 #define VGA_DEFAULT_DEVICE     (NULL)
 
+struct pci_dev;
+
 /* For use by clients */
 
 /**