Merge branch 'drm-next-4.7' of git://people.freedesktop.org/~agd5f/linux into drm...
authorDave Airlie <airlied@redhat.com>
Thu, 12 May 2016 01:16:55 +0000 (11:16 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 12 May 2016 01:16:55 +0000 (11:16 +1000)
More amdgpu fixes for 4.7.  Highlights:
- enable async pageflips
- UVD fixes for polaris
- lots of GPUVM fixes
- whitespace and code cleanups
- misc bug fixes

* 'drm-next-4.7' of git://people.freedesktop.org/~agd5f/linux: (32 commits)
  drm/amd/powerplay: rewrite pp_sw_init to make code readable
  drm/amdgpu/dce11: fix audio offset for asics with >7 audio pins
  drm/amdgpu: fix and cleanup user fence handling v2
  drm/amdgpu: move VM fields into job
  drm/amdgpu: move the context from the IBs into the job
  drm/amdgpu: move context switch handling into common code v2
  drm/amdgpu: move preamble IB handling into common code
  drm/amdgpu/gfx7: fix pipeline sync
  amdgpu/uvd: separate context buffer from DPB
  drm/amdgpu: use fence_context to judge ctx switch v2
  drm/amd/amdgpu:  Added more named DRM info messages for debugging
  drm/amd/amdgpu: Add name field to amd_ip_funcs (v2)
  drm/amdgpu: Support DRM_MODE_PAGE_FLIP_ASYNC (v2)
  drm/amdgpu/dce11: don't share PLLs on Polaris
  drm/amdgpu: Drop unused parameter for *get_sleep_divider_id_from_clock
  drm/amdgpu: Simplify calculation in *get_sleep_divider_id_from_clock
  drm/amdgpu: Use max macro in *get_sleep_divider_id_from_clock
  drm/amd/powerplay: Use defined constants for minium engine clock
  drm/amdgpu: add missing licenses on a couple of files
  drm/amdgpu: fetch cu_info once at init
  ...

20 files changed:
MAINTAINERS
drivers/gpu/drm/etnaviv/etnaviv_gem.c
drivers/gpu/drm/etnaviv/etnaviv_gem.h
drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
drivers/gpu/drm/etnaviv/etnaviv_gpu.c
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_dpi.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_fb.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
drivers/gpu/drm/tegra/dc.c
include/linux/timer.h

index b81c719..216d447 100644 (file)
@@ -3906,7 +3906,6 @@ F:        include/uapi/drm/nouveau_drm.h
 
 DRM DRIVERS FOR NVIDIA TEGRA
 M:     Thierry Reding <thierry.reding@gmail.com>
-M:     Terje Bergström <tbergstrom@nvidia.com>
 L:     dri-devel@lists.freedesktop.org
 L:     linux-tegra@vger.kernel.org
 T:     git git://anongit.freedesktop.org/tegra/linux.git
index 281c6ec..df9bcba 100644 (file)
@@ -129,10 +129,9 @@ void etnaviv_gem_put_pages(struct etnaviv_gem_object *etnaviv_obj)
        /* when we start tracking the pin count, then do something here */
 }
 
-static int etnaviv_gem_mmap_obj(struct drm_gem_object *obj,
+static int etnaviv_gem_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
                struct vm_area_struct *vma)
 {
-       struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
        pgprot_t vm_page_prot;
 
        vma->vm_flags &= ~VM_PFNMAP;
@@ -151,9 +150,9 @@ static int etnaviv_gem_mmap_obj(struct drm_gem_object *obj,
                 * in particular in the case of mmap'd dmabufs)
                 */
                fput(vma->vm_file);
-               get_file(obj->filp);
+               get_file(etnaviv_obj->base.filp);
                vma->vm_pgoff = 0;
-               vma->vm_file  = obj->filp;
+               vma->vm_file  = etnaviv_obj->base.filp;
 
                vma->vm_page_prot = vm_page_prot;
        }
@@ -173,7 +172,7 @@ int etnaviv_gem_mmap(struct file *filp, struct vm_area_struct *vma)
        }
 
        obj = to_etnaviv_bo(vma->vm_private_data);
-       return etnaviv_gem_mmap_obj(vma->vm_private_data, vma);
+       return obj->ops->mmap(obj, vma);
 }
 
 int etnaviv_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -545,6 +544,7 @@ static const struct etnaviv_gem_ops etnaviv_gem_shmem_ops = {
        .get_pages = etnaviv_gem_shmem_get_pages,
        .release = etnaviv_gem_shmem_release,
        .vmap = etnaviv_gem_vmap_impl,
+       .mmap = etnaviv_gem_mmap_obj,
 };
 
 void etnaviv_gem_free_object(struct drm_gem_object *obj)
@@ -886,10 +886,17 @@ static void etnaviv_gem_userptr_release(struct etnaviv_gem_object *etnaviv_obj)
        put_task_struct(etnaviv_obj->userptr.task);
 }
 
+static int etnaviv_gem_userptr_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
+               struct vm_area_struct *vma)
+{
+       return -EINVAL;
+}
+
 static const struct etnaviv_gem_ops etnaviv_gem_userptr_ops = {
        .get_pages = etnaviv_gem_userptr_get_pages,
        .release = etnaviv_gem_userptr_release,
        .vmap = etnaviv_gem_vmap_impl,
+       .mmap = etnaviv_gem_userptr_mmap_obj,
 };
 
 int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file,
index 02665d8..e63ff11 100644 (file)
@@ -79,6 +79,7 @@ struct etnaviv_gem_ops {
        int (*get_pages)(struct etnaviv_gem_object *);
        void (*release)(struct etnaviv_gem_object *);
        void *(*vmap)(struct etnaviv_gem_object *);
+       int (*mmap)(struct etnaviv_gem_object *, struct vm_area_struct *);
 };
 
 static inline bool is_active(struct etnaviv_gem_object *etnaviv_obj)
index 4e67395..b93618c 100644 (file)
@@ -84,10 +84,17 @@ static void *etnaviv_gem_prime_vmap_impl(struct etnaviv_gem_object *etnaviv_obj)
        return dma_buf_vmap(etnaviv_obj->base.import_attach->dmabuf);
 }
 
+static int etnaviv_gem_prime_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
+               struct vm_area_struct *vma)
+{
+       return dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0);
+}
+
 static const struct etnaviv_gem_ops etnaviv_gem_prime_ops = {
        /* .get_pages should never be called */
        .release = etnaviv_gem_prime_release,
        .vmap = etnaviv_gem_prime_vmap_impl,
+       .mmap = etnaviv_gem_prime_mmap_obj,
 };
 
 struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev,
index 306dde1..049d00d 100644 (file)
@@ -1528,8 +1528,8 @@ static int etnaviv_gpu_bind(struct device *dev, struct device *master,
        INIT_WORK(&gpu->recover_work, recover_worker);
        init_waitqueue_head(&gpu->fence_event);
 
-       setup_timer(&gpu->hangcheck_timer, hangcheck_handler,
-                       (unsigned long)gpu);
+       setup_deferrable_timer(&gpu->hangcheck_timer, hangcheck_handler,
+                              (unsigned long)gpu);
 
        priv->gpu[priv->num_gpus++] = gpu;
 
index 4ab5bfc..ac21b40 100644 (file)
@@ -147,11 +147,13 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
        val = CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F;
        writel(val, ctx->addr + DECON_CMU);
 
+       if (ctx->out_type & (IFTYPE_I80 | I80_HW_TRG))
+               decon_setup_trigger(ctx);
+
        /* lcd on and use command if */
        val = VIDOUT_LCD_ON;
        if (ctx->out_type & IFTYPE_I80) {
                val |= VIDOUT_COMMAND_IF;
-               decon_setup_trigger(ctx);
        } else {
                val |= VIDOUT_RGB_IF;
        }
@@ -376,9 +378,6 @@ static void decon_swreset(struct decon_context *ctx)
        writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1);
        writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN,
               ctx->addr + DECON_CRCCTRL);
-
-       if (ctx->out_type & IFTYPE_I80)
-               decon_setup_trigger(ctx);
 }
 
 static void decon_enable(struct exynos_drm_crtc *crtc)
@@ -434,13 +433,12 @@ static void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
 {
        struct decon_context *ctx = crtc->ctx;
 
-       if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
+       if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags) ||
+           (ctx->out_type & I80_HW_TRG))
                return;
 
        if (test_and_clear_bit(BIT_WIN_UPDATED, &ctx->flags))
                decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0);
-
-       drm_crtc_handle_vblank(&ctx->crtc->base);
 }
 
 static void decon_clear_channels(struct exynos_drm_crtc *crtc)
@@ -573,6 +571,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
 
                /* clear */
                writel(val, ctx->addr + DECON_VIDINTCON1);
+               drm_crtc_handle_vblank(&ctx->crtc->base);
        }
 
 out:
@@ -648,9 +647,8 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
 
        if (ctx->out_type & IFTYPE_HDMI) {
                ctx->first_win = 1;
-               ctx->out_type = IFTYPE_I80;
        } else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) {
-               ctx->out_type = IFTYPE_I80;
+               ctx->out_type |= IFTYPE_I80;
        }
 
        for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
index 50dd33d..785ffa6 100644 (file)
@@ -233,20 +233,15 @@ void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
        unsigned long flags;
 
        spin_lock_irqsave(&crtc->dev->event_lock, flags);
+
        e = exynos_crtc->event;
        if (e && e->base.file_priv == file) {
                exynos_crtc->event = NULL;
-               /*
-                * event will be destroyed by core part
-                * so below line should be removed later with core changes
-                */
-               e->base.destroy(&e->base);
-               /*
-                * event_space will be increased by core part
-                * so below line should be removed later with core changes.
-                */
-               file->event_space += sizeof(e->event);
                atomic_dec(&exynos_crtc->pending_update);
        }
+
        spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+
+       if (e && e->base.file_priv == file)
+               drm_event_cancel_free(crtc->dev, &e->base);
 }
index 75e570f..5e38e74 100644 (file)
@@ -15,6 +15,7 @@
 #include <drm/drm_panel.h>
 #include <drm/drm_atomic_helper.h>
 
+#include <linux/of_graph.h>
 #include <linux/regulator/consumer.h>
 
 #include <video/of_videomode.h>
@@ -164,67 +165,6 @@ static const struct drm_encoder_funcs exynos_dpi_encoder_funcs = {
        .destroy = drm_encoder_cleanup,
 };
 
-/* of_* functions will be removed after merge of of_graph patches */
-static struct device_node *
-of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
-{
-       struct device_node *np;
-
-       for_each_child_of_node(parent, np) {
-               u32 r;
-
-               if (!np->name || of_node_cmp(np->name, name))
-                       continue;
-
-               if (of_property_read_u32(np, "reg", &r) < 0)
-                       r = 0;
-
-               if (reg == r)
-                       break;
-       }
-
-       return np;
-}
-
-static struct device_node *of_graph_get_port_by_reg(struct device_node *parent,
-                                                   u32 reg)
-{
-       struct device_node *ports, *port;
-
-       ports = of_get_child_by_name(parent, "ports");
-       if (ports)
-               parent = ports;
-
-       port = of_get_child_by_name_reg(parent, "port", reg);
-
-       of_node_put(ports);
-
-       return port;
-}
-
-static struct device_node *
-of_graph_get_endpoint_by_reg(struct device_node *port, u32 reg)
-{
-       return of_get_child_by_name_reg(port, "endpoint", reg);
-}
-
-static struct device_node *
-of_graph_get_remote_port_parent(const struct device_node *node)
-{
-       struct device_node *np;
-       unsigned int depth;
-
-       np = of_parse_phandle(node, "remote-endpoint", 0);
-
-       /* Walk 3 levels up only if there is 'ports' node. */
-       for (depth = 3; depth && np; depth--) {
-               np = of_get_next_parent(np);
-               if (depth == 2 && of_node_cmp(np->name, "ports"))
-                       break;
-       }
-       return np;
-}
-
 enum {
        FIMD_PORT_IN0,
        FIMD_PORT_IN1,
@@ -237,12 +177,7 @@ static struct device_node *exynos_dpi_of_find_panel_node(struct device *dev)
 {
        struct device_node *np, *ep;
 
-       np = of_graph_get_port_by_reg(dev->of_node, FIMD_PORT_RGB);
-       if (!np)
-               return NULL;
-
-       ep = of_graph_get_endpoint_by_reg(np, 0);
-       of_node_put(np);
+       ep = of_graph_get_endpoint_by_regs(dev->of_node, FIMD_PORT_RGB, 0);
        if (!ep)
                return NULL;
 
index 8ff355d..6c4dd49 100644 (file)
@@ -431,6 +431,7 @@ static struct drm_driver exynos_drm_driver = {
        .gem_prime_import_sg_table      = exynos_drm_gem_prime_import_sg_table,
        .gem_prime_vmap         = exynos_drm_gem_prime_vmap,
        .gem_prime_vunmap       = exynos_drm_gem_prime_vunmap,
+       .gem_prime_mmap         = exynos_drm_gem_prime_mmap,
        .ioctls                 = exynos_ioctls,
        .num_ioctls             = ARRAY_SIZE(exynos_ioctls),
        .fops                   = &exynos_drm_driver_fops,
index 72c3565..601ecf8 100644 (file)
@@ -1632,50 +1632,6 @@ static const struct drm_encoder_funcs exynos_dsi_encoder_funcs = {
 
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
 
-/* of_* functions will be removed after merge of of_graph patches */
-static struct device_node *
-of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
-{
-       struct device_node *np;
-
-       for_each_child_of_node(parent, np) {
-               u32 r;
-
-               if (!np->name || of_node_cmp(np->name, name))
-                       continue;
-
-               if (of_property_read_u32(np, "reg", &r) < 0)
-                       r = 0;
-
-               if (reg == r)
-                       break;
-       }
-
-       return np;
-}
-
-static struct device_node *of_graph_get_port_by_reg(struct device_node *parent,
-                                                   u32 reg)
-{
-       struct device_node *ports, *port;
-
-       ports = of_get_child_by_name(parent, "ports");
-       if (ports)
-               parent = ports;
-
-       port = of_get_child_by_name_reg(parent, "port", reg);
-
-       of_node_put(ports);
-
-       return port;
-}
-
-static struct device_node *
-of_graph_get_endpoint_by_reg(struct device_node *port, u32 reg)
-{
-       return of_get_child_by_name_reg(port, "endpoint", reg);
-}
-
 static int exynos_dsi_of_read_u32(const struct device_node *np,
                                  const char *propname, u32 *out_value)
 {
@@ -1697,7 +1653,7 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
 {
        struct device *dev = dsi->dev;
        struct device_node *node = dev->of_node;
-       struct device_node *port, *ep;
+       struct device_node *ep;
        int ret;
 
        ret = exynos_dsi_of_read_u32(node, "samsung,pll-clock-frequency",
@@ -1705,16 +1661,9 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
        if (ret < 0)
                return ret;
 
-       port = of_graph_get_port_by_reg(node, DSI_PORT_OUT);
-       if (!port) {
-               dev_err(dev, "no output port specified\n");
-               return -EINVAL;
-       }
-
-       ep = of_graph_get_endpoint_by_reg(port, 0);
-       of_node_put(port);
+       ep = of_graph_get_endpoint_by_regs(node, DSI_PORT_OUT, 0);
        if (!ep) {
-               dev_err(dev, "no endpoint specified in output port\n");
+               dev_err(dev, "no output port with endpoint specified\n");
                return -EINVAL;
        }
 
index 81cc553..f851a40 100644 (file)
@@ -97,20 +97,9 @@ static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
                                     &exynos_fb->exynos_gem[0]->base, handle);
 }
 
-static int exynos_drm_fb_dirty(struct drm_framebuffer *fb,
-                               struct drm_file *file_priv, unsigned flags,
-                               unsigned color, struct drm_clip_rect *clips,
-                               unsigned num_clips)
-{
-       /* TODO */
-
-       return 0;
-}
-
 static const struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
        .destroy        = exynos_drm_fb_destroy,
        .create_handle  = exynos_drm_fb_create_handle,
-       .dirty          = exynos_drm_fb_dirty,
 };
 
 struct drm_framebuffer *
index cec508f..3efe1aa 100644 (file)
@@ -397,9 +397,16 @@ static void fimd_clear_channels(struct exynos_drm_crtc *crtc)
 static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
                const struct drm_display_mode *mode)
 {
-       unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
+       unsigned long ideal_clk;
        u32 clkdiv;
 
+       if (mode->clock == 0) {
+               DRM_ERROR("Mode has zero clock value.\n");
+               return 0xff;
+       }
+
+       ideal_clk = mode->clock * 1000;
+
        if (ctx->i80_if) {
                /*
                 * The frame done interrupt should be occurred prior to the
index 193d360..4935523 100644 (file)
@@ -383,8 +383,8 @@ static void g2d_userptr_put_dma_addr(struct drm_device *drm_dev,
                return;
 
 out:
-       exynos_gem_unmap_sgt_from_dma(drm_dev, g2d_userptr->sgt,
-                                       DMA_BIDIRECTIONAL);
+       dma_unmap_sg(to_dma_dev(drm_dev), g2d_userptr->sgt->sgl,
+                       g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
 
        pages = frame_vector_pages(g2d_userptr->vec);
        if (!IS_ERR(pages)) {
@@ -501,10 +501,10 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
 
        g2d_userptr->sgt = sgt;
 
-       ret = exynos_gem_map_sgt_with_dma(drm_dev, g2d_userptr->sgt,
-                                               DMA_BIDIRECTIONAL);
-       if (ret < 0) {
+       if (!dma_map_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents,
+                               DMA_BIDIRECTIONAL)) {
                DRM_ERROR("failed to map sgt with dma region.\n");
+               ret = -ENOMEM;
                goto err_sg_free_table;
        }
 
index 6fb98f4..72d9414 100644 (file)
@@ -378,28 +378,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
        return 0;
 }
 
-int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
-                               struct sg_table *sgt,
-                               enum dma_data_direction dir)
-{
-       int nents;
-
-       nents = dma_map_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents, dir);
-       if (!nents) {
-               DRM_ERROR("failed to map sgl with dma.\n");
-               return nents;
-       }
-
-       return 0;
-}
-
-void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
-                               struct sg_table *sgt,
-                               enum dma_data_direction dir)
-{
-       dma_unmap_sg(to_dma_dev(drm_dev), sgt->sgl, sgt->nents, dir);
-}
-
 void exynos_drm_gem_free_object(struct drm_gem_object *obj)
 {
        exynos_drm_gem_destroy(to_exynos_gem(obj));
@@ -503,22 +481,12 @@ out:
        }
 }
 
-int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+static int exynos_drm_gem_mmap_obj(struct drm_gem_object *obj,
+                                  struct vm_area_struct *vma)
 {
-       struct exynos_drm_gem *exynos_gem;
-       struct drm_gem_object *obj;
+       struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj);
        int ret;
 
-       /* set vm_area_struct. */
-       ret = drm_gem_mmap(filp, vma);
-       if (ret < 0) {
-               DRM_ERROR("failed to mmap.\n");
-               return ret;
-       }
-
-       obj = vma->vm_private_data;
-       exynos_gem = to_exynos_gem(obj);
-
        DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem->flags);
 
        /* non-cachable as default. */
@@ -543,6 +511,26 @@ err_close_vm:
        return ret;
 }
 
+int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+       struct drm_gem_object *obj;
+       int ret;
+
+       /* set vm_area_struct. */
+       ret = drm_gem_mmap(filp, vma);
+       if (ret < 0) {
+               DRM_ERROR("failed to mmap.\n");
+               return ret;
+       }
+
+       obj = vma->vm_private_data;
+
+       if (obj->import_attach)
+               return dma_buf_mmap(obj->dma_buf, vma, 0);
+
+       return exynos_drm_gem_mmap_obj(obj, vma);
+}
+
 /* low-level interface prime helpers */
 struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj)
 {
@@ -617,3 +605,15 @@ void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
 {
        /* Nothing to do */
 }
+
+int exynos_drm_gem_prime_mmap(struct drm_gem_object *obj,
+                             struct vm_area_struct *vma)
+{
+       int ret;
+
+       ret = drm_gem_mmap_obj(obj, obj->size, vma);
+       if (ret < 0)
+               return ret;
+
+       return exynos_drm_gem_mmap_obj(obj, vma);
+}
index 0022305..7810074 100644 (file)
@@ -121,16 +121,6 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 /* set vm_flags and we can change the vm attribute to other one at here. */
 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
 
-/* map sgt with dma region. */
-int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
-                               struct sg_table *sgt,
-                               enum dma_data_direction dir);
-
-/* unmap sgt from dma region. */
-void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev,
-                               struct sg_table *sgt,
-                               enum dma_data_direction dir);
-
 /* low-level interface prime helpers */
 struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj);
 struct drm_gem_object *
@@ -139,5 +129,7 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
                                     struct sg_table *sgt);
 void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj);
 void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+int exynos_drm_gem_prime_mmap(struct drm_gem_object *obj,
+                             struct vm_area_struct *vma);
 
 #endif
index 0f87acb..6cd0994 100644 (file)
@@ -146,6 +146,7 @@ struct hdmi_context {
        struct clk                      **clk_muxes;
        struct regulator_bulk_data      regul_bulk[ARRAY_SIZE(supply)];
        struct regulator                *reg_hdmi_en;
+       struct exynos_drm_clk           phy_clk;
 };
 
 static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
@@ -1445,7 +1446,6 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
 
 static void hdmi_conf_apply(struct hdmi_context *hdata)
 {
-       hdmiphy_conf_apply(hdata);
        hdmi_start(hdata, false);
        hdmi_conf_init(hdata);
        hdmi_audio_init(hdata);
@@ -1478,10 +1478,8 @@ static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
                           SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
 }
 
-static void hdmi_enable(struct drm_encoder *encoder)
+static void hdmiphy_enable(struct hdmi_context *hdata)
 {
-       struct hdmi_context *hdata = encoder_to_hdmi(encoder);
-
        if (hdata->powered)
                return;
 
@@ -1497,11 +1495,40 @@ static void hdmi_enable(struct drm_encoder *encoder)
 
        hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
 
-       hdmi_conf_apply(hdata);
+       hdmiphy_conf_apply(hdata);
 
        hdata->powered = true;
 }
 
+static void hdmiphy_disable(struct hdmi_context *hdata)
+{
+       if (!hdata->powered)
+               return;
+
+       hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
+
+       hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
+
+       hdmi_set_refclk(hdata, false);
+
+       regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
+                       PMU_HDMI_PHY_ENABLE_BIT, 0);
+
+       regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
+
+       pm_runtime_put_sync(hdata->dev);
+
+       hdata->powered = false;
+}
+
+static void hdmi_enable(struct drm_encoder *encoder)
+{
+       struct hdmi_context *hdata = encoder_to_hdmi(encoder);
+
+       hdmiphy_enable(hdata);
+       hdmi_conf_apply(hdata);
+}
+
 static void hdmi_disable(struct drm_encoder *encoder)
 {
        struct hdmi_context *hdata = encoder_to_hdmi(encoder);
@@ -1525,22 +1552,9 @@ static void hdmi_disable(struct drm_encoder *encoder)
        if (funcs && funcs->disable)
                (*funcs->disable)(crtc);
 
-       hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
-
        cancel_delayed_work(&hdata->hotplug_work);
 
-       hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
-
-       hdmi_set_refclk(hdata, false);
-
-       regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
-                       PMU_HDMI_PHY_ENABLE_BIT, 0);
-
-       regulator_bulk_disable(ARRAY_SIZE(supply), hdata->regul_bulk);
-
-       pm_runtime_put_sync(hdata->dev);
-
-       hdata->powered = false;
+       hdmiphy_disable(hdata);
 }
 
 static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
@@ -1625,6 +1639,17 @@ static int hdmi_clk_init(struct hdmi_context *hdata)
 }
 
 
+static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
+{
+       struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
+                                                 phy_clk);
+
+       if (enable)
+               hdmiphy_enable(hdata);
+       else
+               hdmiphy_disable(hdata);
+}
+
 static int hdmi_resources_init(struct hdmi_context *hdata)
 {
        struct device *dev = hdata->dev;
@@ -1658,7 +1683,8 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
        }
        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk);
        if (ret) {
-               DRM_ERROR("failed to get regulators\n");
+               if (ret != -EPROBE_DEFER)
+                       DRM_ERROR("failed to get regulators\n");
                return ret;
        }
 
@@ -1710,6 +1736,10 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
        if (pipe < 0)
                return pipe;
 
+       hdata->phy_clk.enable = hdmiphy_clk_enable;
+
+       exynos_drm_crtc_from_pipe(drm_dev, pipe)->pipe_clk = &hdata->phy_clk;
+
        encoder->possible_crtcs = 1 << pipe;
 
        DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
@@ -1777,7 +1807,8 @@ static int hdmi_probe(struct platform_device *pdev)
 
        ret = hdmi_resources_init(hdata);
        if (ret) {
-               DRM_ERROR("hdmi_resources_init failed\n");
+               if (ret != -EPROBE_DEFER)
+                       DRM_ERROR("hdmi_resources_init failed\n");
                return ret;
        }
 
index bfbc215..998452a 100644 (file)
@@ -430,12 +430,13 @@ static void dsi_set_mipi_phy(void __iomem *base,
         * wait for phy's clock ready
         */
        delay_count = 100;
-       while (delay_count--) {
+       while (delay_count) {
                val = readl(base +  PHY_STATUS);
                if ((BIT(0) | BIT(2)) & val)
                        break;
 
                udelay(1);
+               delay_count--;
        }
 
        if (!delay_count)
index e102c9e..3f94785 100644 (file)
@@ -201,35 +201,6 @@ static int compare_of(struct device *dev, void *data)
        return dev->of_node == data;
 }
 
-static int kirin_drm_connectors_register(struct drm_device *dev)
-{
-       struct drm_connector *connector;
-       struct drm_connector *failed_connector;
-       int ret;
-
-       mutex_lock(&dev->mode_config.mutex);
-       drm_for_each_connector(connector, dev) {
-               ret = drm_connector_register(connector);
-               if (ret) {
-                       failed_connector = connector;
-                       goto err;
-               }
-       }
-       mutex_unlock(&dev->mode_config.mutex);
-
-       return 0;
-
-err:
-       drm_for_each_connector(connector, dev) {
-               if (failed_connector == connector)
-                       break;
-               drm_connector_unregister(connector);
-       }
-       mutex_unlock(&dev->mode_config.mutex);
-
-       return ret;
-}
-
 static int kirin_drm_bind(struct device *dev)
 {
        struct drm_driver *driver = &kirin_drm_driver;
@@ -251,7 +222,7 @@ static int kirin_drm_bind(struct device *dev)
                goto err_kms_cleanup;
 
        /* connectors should be registered after drm device register */
-       ret = kirin_drm_connectors_register(drm_dev);
+       ret = drm_connector_register_all(drm_dev);
        if (ret)
                goto err_drm_dev_unregister;
 
@@ -273,7 +244,12 @@ err_drm_dev_unref:
 
 static void kirin_drm_unbind(struct device *dev)
 {
-       drm_put_dev(dev_get_drvdata(dev));
+       struct drm_device *drm_dev = dev_get_drvdata(dev);
+
+       drm_connector_unregister_all(drm_dev);
+       drm_dev_unregister(drm_dev);
+       kirin_drm_kms_cleanup(drm_dev);
+       drm_dev_unref(drm_dev);
 }
 
 static const struct component_master_ops kirin_drm_ops = {
index fb2b4b0..3b85a31 100644 (file)
@@ -1722,7 +1722,6 @@ static int tegra_dc_init(struct host1x_client *client)
        if (err < 0)
                goto cleanup;
 
-       drm_mode_crtc_set_gamma_size(&dc->base, 256);
        drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
 
        /*
index 61aa61d..20ac746 100644 (file)
@@ -145,6 +145,8 @@ static inline void init_timer_on_stack_key(struct timer_list *timer,
 
 #define setup_timer(timer, fn, data)                                   \
        __setup_timer((timer), (fn), (data), 0)
+#define setup_deferrable_timer(timer, fn, data)                                \
+       __setup_timer((timer), (fn), (data), TIMER_DEFERRABLE)
 #define setup_timer_on_stack(timer, fn, data)                          \
        __setup_timer_on_stack((timer), (fn), (data), 0)
 #define setup_deferrable_timer_on_stack(timer, fn, data)               \