From 4836d15789c85224662d3e037694d15ec9901631 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Wed, 19 Dec 2012 14:53:37 -0600 Subject: [PATCH 1/8] drm/omap: Add PM capabilities Added power management capabilities into the omapdrm and DMM drivers. During suspend, we don't need to do anything to maintain the state of the LUT. We have all the necessary information to recreate the mappings of the GEM object list maintained by the omapdrm driver. On resume, the DMM resume handler will first reprogram the LUT to point to the dummy page. The subsequent resume handler in the omapdrm will call into the DMM and reprogram each of the buffer objects. This will ensure that all of the necessary objects will be pinned into the DMM properly. Order of suspend/resume handlers is done by device creation. We create the DMM device before the omapdrm, so the correct order is maintained. Signed-off-by: Andy Gross Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_tiler.c | 34 ++++++++++++++++++++++++ drivers/staging/omapdrm/omap_drv.c | 14 ++++++++++ drivers/staging/omapdrm/omap_drv.h | 4 +++ drivers/staging/omapdrm/omap_gem.c | 28 +++++++++++++++++++ 4 files changed, 80 insertions(+) diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 59bf43899fc0..c42c5e500e02 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -903,12 +903,46 @@ int tiler_map_show(struct seq_file *s, void *arg) } #endif +#ifdef CONFIG_PM +static int omap_dmm_resume(struct device *dev) +{ + struct tcm_area area; + int i; + + if (!omap_dmm) + return -ENODEV; + + area = (struct tcm_area) { + .is2d = true, + .tcm = NULL, + .p1.x = omap_dmm->container_width - 1, + .p1.y = omap_dmm->container_height - 1, + }; + + /* initialize all LUTs to dummy page entries */ + for (i = 0; i < omap_dmm->num_lut; i++) { + area.tcm = omap_dmm->tcm[i]; + if (fill(&area, NULL, 0, 0, true)) + dev_err(dev, "refill failed"); + } + + return 0; +} + +static const struct dev_pm_ops omap_dmm_pm_ops = { + .resume = omap_dmm_resume, +}; +#endif + struct platform_driver omap_dmm_driver = { .probe = omap_dmm_probe, .remove = omap_dmm_remove, .driver = { .owner = THIS_MODULE, .name = DMM_DRIVER_NAME, +#ifdef CONFIG_PM + .pm = &omap_dmm_pm_ops, +#endif }, }; diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index dfdb4ba1e7c6..9d6a584113d2 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -368,6 +368,9 @@ static int dev_load(struct drm_device *dev, unsigned long flags) /* well, limp along without an fbdev.. maybe X11 will work? */ } + /* store off drm_device for use in pm ops */ + dev_set_drvdata(dev->dev, dev); + drm_kms_helper_poll_init(dev); return 0; @@ -393,6 +396,8 @@ static int dev_unload(struct drm_device *dev) kfree(dev->dev_private); dev->dev_private = NULL; + dev_set_drvdata(dev->dev, NULL); + return 0; } @@ -558,10 +563,19 @@ static int pdev_remove(struct platform_device *device) return 0; } +#ifdef CONFIG_PM +static const struct dev_pm_ops omapdrm_pm_ops = { + .resume = omap_gem_resume, +}; +#endif + struct platform_driver pdev = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &omapdrm_pm_ops, +#endif }, .probe = pdev_probe, .remove = pdev_remove, diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index cd1f22b0b124..f921027e7500 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -135,6 +135,10 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m); void omap_gem_describe_objects(struct list_head *list, struct seq_file *m); #endif +#ifdef CONFIG_PM +int omap_gem_resume(struct device *dev); +#endif + int omap_irq_enable_vblank(struct drm_device *dev, int crtc); void omap_irq_disable_vblank(struct drm_device *dev, int crtc); irqreturn_t omap_irq_handler(DRM_IRQ_ARGS); diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index c38992b76fc9..08f1e292ed20 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -964,6 +964,34 @@ void *omap_gem_vaddr(struct drm_gem_object *obj) return omap_obj->vaddr; } +#ifdef CONFIG_PM +/* re-pin objects in DMM in resume path: */ +int omap_gem_resume(struct device *dev) +{ + struct drm_device *drm_dev = dev_get_drvdata(dev); + struct omap_drm_private *priv = drm_dev->dev_private; + struct omap_gem_object *omap_obj; + int ret = 0; + + list_for_each_entry(omap_obj, &priv->obj_list, mm_list) { + if (omap_obj->block) { + struct drm_gem_object *obj = &omap_obj->base; + uint32_t npages = obj->size >> PAGE_SHIFT; + WARN_ON(!omap_obj->pages); /* this can't happen */ + ret = tiler_pin(omap_obj->block, + omap_obj->pages, npages, + omap_obj->roll, true); + if (ret) { + dev_err(dev, "could not repin: %d\n", ret); + return ret; + } + } + } + + return 0; +} +#endif + #ifdef CONFIG_DEBUG_FS void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m) { From 238083ad5d67d1c9ba6e7158a027e834a48bb23b Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Wed, 19 Dec 2012 14:53:38 -0600 Subject: [PATCH 2/8] drm/omap: Add OMAP5 support Add support for OMAP5 processor. The main differences are that the OMAP5 has 2 containers, one for 1D and one for 2D. Each container is 128MiB in size. Signed-off-by: Andy Gross Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_priv.h | 5 + drivers/staging/omapdrm/omap_dmm_tiler.c | 127 +++++++++++++++-------- drivers/staging/omapdrm/tcm.h | 2 + 3 files changed, 90 insertions(+), 44 deletions(-) diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/staging/omapdrm/omap_dmm_priv.h index 273ec12c028a..58bcd6ae0255 100644 --- a/drivers/staging/omapdrm/omap_dmm_priv.h +++ b/drivers/staging/omapdrm/omap_dmm_priv.h @@ -118,6 +118,11 @@ struct pat { #define DESCR_SIZE 128 #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE)) +/* For OMAP5, a fixed offset is added to all Y coordinates for 1D buffers. + * This is used in programming to address the upper portion of the LUT +*/ +#define OMAP5_LUT_OFFSET 128 + struct dmm; struct dmm_txn { diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index c42c5e500e02..391021537105 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -213,6 +213,11 @@ static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area, txn->last_pat->next_pa = (uint32_t)pat_pa; pat->area = *area; + + /* adjust Y coordinates based off of container parameters */ + pat->area.y0 += engine->tcm->y_offset; + pat->area.y1 += engine->tcm->y_offset; + pat->ctrl = (struct pat_ctrl){ .start = 1, .lut_id = engine->tcm->lut_id, @@ -622,6 +627,11 @@ static int omap_dmm_probe(struct platform_device *dev) omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5; omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5; + /* increment LUT by one if on OMAP5 */ + /* LUT has twice the height, and is split into a separate container */ + if (omap_dmm->lut_height != omap_dmm->container_height) + omap_dmm->num_lut++; + /* initialize DMM registers */ writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__0); writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__1); @@ -701,6 +711,9 @@ static int omap_dmm_probe(struct platform_device *dev) } /* init containers */ + /* Each LUT is associated with a TCM (container manager). We use the + lut_id to denote the lut_id used to identify the correct LUT for + programming during reill operations */ for (i = 0; i < omap_dmm->num_lut; i++) { omap_dmm->tcm[i] = sita_init(omap_dmm->container_width, omap_dmm->container_height, @@ -717,13 +730,23 @@ static int omap_dmm_probe(struct platform_device *dev) /* assign access mode containers to applicable tcm container */ /* OMAP 4 has 1 container for all 4 views */ + /* OMAP 5 has 2 containers, 1 for 2D and 1 for 1D */ containers[TILFMT_8BIT] = omap_dmm->tcm[0]; containers[TILFMT_16BIT] = omap_dmm->tcm[0]; containers[TILFMT_32BIT] = omap_dmm->tcm[0]; - containers[TILFMT_PAGE] = omap_dmm->tcm[0]; + + if (omap_dmm->container_height != omap_dmm->lut_height) { + /* second LUT is used for PAGE mode. Programming must use + y offset that is added to all y coordinates. LUT id is still + 0, because it is the same LUT, just the upper 128 lines */ + containers[TILFMT_PAGE] = omap_dmm->tcm[1]; + omap_dmm->tcm[1]->y_offset = OMAP5_LUT_OFFSET; + omap_dmm->tcm[1]->lut_id = 0; + } else { + containers[TILFMT_PAGE] = omap_dmm->tcm[0]; + } area = (struct tcm_area) { - .is2d = true, .tcm = NULL, .p1.x = omap_dmm->container_width - 1, .p1.y = omap_dmm->container_height - 1, @@ -835,64 +858,81 @@ int tiler_map_show(struct seq_file *s, void *arg) int h_adj; int w_adj; unsigned long flags; + int lut_idx; + if (!omap_dmm) { /* early return if dmm/tiler device is not initialized */ return 0; } - h_adj = omap_dmm->lut_height / ydiv; - w_adj = omap_dmm->lut_width / xdiv; + h_adj = omap_dmm->container_height / ydiv; + w_adj = omap_dmm->container_width / xdiv; - map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL); - global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL); + map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL); + global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL); if (!map || !global_map) goto error; - memset(global_map, ' ', (w_adj + 1) * h_adj); - for (i = 0; i < omap_dmm->lut_height; i++) { - map[i] = global_map + i * (w_adj + 1); - map[i][w_adj] = 0; - } - spin_lock_irqsave(&list_lock, flags); + for (lut_idx = 0; lut_idx < omap_dmm->num_lut; lut_idx++) { + memset(map, 0, sizeof(h_adj * sizeof(*map))); + memset(global_map, ' ', (w_adj + 1) * h_adj); - list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) { - if (block->fmt != TILFMT_PAGE) { - fill_map(map, xdiv, ydiv, &block->area, *m2dp, true); - if (!*++a2dp) - a2dp = a2d; - if (!*++m2dp) - m2dp = m2d; - map_2d_info(map, xdiv, ydiv, nice, &block->area); - } else { - bool start = read_map_pt(map, xdiv, ydiv, - &block->area.p0) - == ' '; - bool end = read_map_pt(map, xdiv, ydiv, &block->area.p1) - == ' '; - tcm_for_each_slice(a, block->area, p) - fill_map(map, xdiv, ydiv, &a, '=', true); - fill_map_pt(map, xdiv, ydiv, &block->area.p0, + for (i = 0; i < omap_dmm->container_height; i++) { + map[i] = global_map + i * (w_adj + 1); + map[i][w_adj] = 0; + } + + spin_lock_irqsave(&list_lock, flags); + + list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) { + if (block->area.tcm == omap_dmm->tcm[lut_idx]) { + if (block->fmt != TILFMT_PAGE) { + fill_map(map, xdiv, ydiv, &block->area, + *m2dp, true); + if (!*++a2dp) + a2dp = a2d; + if (!*++m2dp) + m2dp = m2d; + map_2d_info(map, xdiv, ydiv, nice, + &block->area); + } else { + bool start = read_map_pt(map, xdiv, + ydiv, &block->area.p0) == ' '; + bool end = read_map_pt(map, xdiv, ydiv, + &block->area.p1) == ' '; + + tcm_for_each_slice(a, block->area, p) + fill_map(map, xdiv, ydiv, &a, + '=', true); + fill_map_pt(map, xdiv, ydiv, + &block->area.p0, start ? '<' : 'X'); - fill_map_pt(map, xdiv, ydiv, &block->area.p1, + fill_map_pt(map, xdiv, ydiv, + &block->area.p1, end ? '>' : 'X'); - map_1d_info(map, xdiv, ydiv, nice, &block->area); + map_1d_info(map, xdiv, ydiv, nice, + &block->area); + } + } } - } - spin_unlock_irqrestore(&list_lock, flags); + spin_unlock_irqrestore(&list_lock, flags); - if (s) { - seq_printf(s, "BEGIN DMM TILER MAP\n"); - for (i = 0; i < 128; i++) - seq_printf(s, "%03d:%s\n", i, map[i]); - seq_printf(s, "END TILER MAP\n"); - } else { - dev_dbg(omap_dmm->dev, "BEGIN DMM TILER MAP\n"); - for (i = 0; i < 128; i++) - dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]); - dev_dbg(omap_dmm->dev, "END TILER MAP\n"); + if (s) { + seq_printf(s, "CONTAINER %d DUMP BEGIN\n", lut_idx); + for (i = 0; i < 128; i++) + seq_printf(s, "%03d:%s\n", i, map[i]); + seq_printf(s, "CONTAINER %d DUMP END\n", lut_idx); + } else { + dev_dbg(omap_dmm->dev, "CONTAINER %d DUMP BEGIN\n", + lut_idx); + for (i = 0; i < 128; i++) + dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]); + dev_dbg(omap_dmm->dev, "CONTAINER %d DUMP END\n", + lut_idx); + } } error: @@ -913,7 +953,6 @@ static int omap_dmm_resume(struct device *dev) return -ENODEV; area = (struct tcm_area) { - .is2d = true, .tcm = NULL, .p1.x = omap_dmm->container_width - 1, .p1.y = omap_dmm->container_height - 1, diff --git a/drivers/staging/omapdrm/tcm.h b/drivers/staging/omapdrm/tcm.h index d273e3ee0b4c..a8d5ce47686f 100644 --- a/drivers/staging/omapdrm/tcm.h +++ b/drivers/staging/omapdrm/tcm.h @@ -59,6 +59,8 @@ struct tcm { u16 width, height; /* container dimensions */ int lut_id; /* Lookup table identifier */ + unsigned int y_offset; /* offset to use for y coordinates */ + /* 'pvt' structure shall contain any tcm details (attr) along with linked list of allocated areas and mutex for mutually exclusive access to the list. It may also contain copies of width and height to notice From 32ac1a5286d56b3c822f4a1a8d0f7fc5d586de38 Mon Sep 17 00:00:00 2001 From: Cong Ding Date: Tue, 15 Jan 2013 20:46:50 +0100 Subject: [PATCH 3/8] staging: omapdrm/omap_gem_dmabuf.c: fix memory leakage There is a memory leakage in variable sg if it goes to error. Signed-off-by: Cong Ding Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem_dmabuf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/staging/omapdrm/omap_gem_dmabuf.c index b6c5b5c6c8c5..a3236abfca3d 100644 --- a/drivers/staging/omapdrm/omap_gem_dmabuf.c +++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c @@ -53,10 +53,10 @@ static struct sg_table *omap_gem_map_dma_buf( /* this should be after _get_paddr() to ensure we have pages attached */ omap_gem_dma_sync(obj, dir); -out: - if (ret) - return ERR_PTR(ret); return sg; +out: + kfree(sg); + return ERR_PTR(ret); } static void omap_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, From a4462f246c8821f625f45bce52c7ca7e0207dffe Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Sat, 26 Jan 2013 00:40:13 +0100 Subject: [PATCH 4/8] staging/omapdrm: Use kmemdup rather than duplicating its implementation Found with coccicheck. The semantic patch that makes this change is available in scripts/coccinelle/api/memdup.cocci. Signed-off-by: Peter Huewe Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 08f1e292ed20..f9297eb2599e 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -1267,12 +1267,12 @@ int omap_gem_set_sync_object(struct drm_gem_object *obj, void *syncobj) if ((omap_obj->flags & OMAP_BO_EXT_SYNC) && !syncobj) { /* clearing a previously set syncobj */ - syncobj = kzalloc(sizeof(*omap_obj->sync), GFP_ATOMIC); + syncobj = kmemdup(omap_obj->sync, sizeof(*omap_obj->sync), + GFP_ATOMIC); if (!syncobj) { ret = -ENOMEM; goto unlock; } - memcpy(syncobj, omap_obj->sync, sizeof(*omap_obj->sync)); omap_obj->flags &= ~OMAP_BO_EXT_SYNC; omap_obj->sync = syncobj; } else if (syncobj && !(omap_obj->flags & OMAP_BO_EXT_SYNC)) { From 8bb0daffb0b8e45188066255b4203446eae181f1 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 11 Feb 2013 12:43:09 -0500 Subject: [PATCH 5/8] drm/omap: move out of staging Now that the omapdss interface has been reworked so that omapdrm can use dispc directly, we have been able to fix the remaining functional kms issues with omapdrm. And in the mean time the PM sequencing and many other of that open issues have been solved. So I think it makes sense to finally move omapdrm out of staging. Signed-off-by: Rob Clark --- drivers/gpu/drm/Kconfig | 2 ++ drivers/gpu/drm/Makefile | 1 + drivers/{staging => gpu/drm}/omapdrm/Kconfig | 0 drivers/{staging => gpu/drm}/omapdrm/Makefile | 0 drivers/gpu/drm/omapdrm/TODO | 23 +++++++++++++ .../drm}/omapdrm/omap_connector.c | 2 +- .../{staging => gpu/drm}/omapdrm/omap_crtc.c | 2 +- .../drm}/omapdrm/omap_debugfs.c | 2 +- .../drm}/omapdrm/omap_dmm_priv.h | 0 .../drm}/omapdrm/omap_dmm_tiler.c | 0 .../drm}/omapdrm/omap_dmm_tiler.h | 0 .../{staging => gpu/drm}/omapdrm/omap_drv.c | 2 +- .../{staging => gpu/drm}/omapdrm/omap_drv.h | 4 +-- .../drm}/omapdrm/omap_encoder.c | 2 +- .../{staging => gpu/drm}/omapdrm/omap_fb.c | 2 +- .../{staging => gpu/drm}/omapdrm/omap_fbdev.c | 2 +- .../{staging => gpu/drm}/omapdrm/omap_gem.c | 2 +- .../drm}/omapdrm/omap_gem_dmabuf.c | 2 +- .../drm}/omapdrm/omap_gem_helpers.c | 2 +- .../{staging => gpu/drm}/omapdrm/omap_irq.c | 2 +- .../{staging => gpu/drm}/omapdrm/omap_plane.c | 2 +- .../{staging => gpu/drm}/omapdrm/tcm-sita.c | 0 .../{staging => gpu/drm}/omapdrm/tcm-sita.h | 0 drivers/{staging => gpu/drm}/omapdrm/tcm.h | 0 drivers/staging/Kconfig | 2 -- drivers/staging/Makefile | 1 - drivers/staging/omapdrm/TODO | 32 ------------------- .../omapdrm => include/uapi/drm}/omap_drm.h | 2 +- 28 files changed, 41 insertions(+), 50 deletions(-) rename drivers/{staging => gpu/drm}/omapdrm/Kconfig (100%) rename drivers/{staging => gpu/drm}/omapdrm/Makefile (100%) create mode 100644 drivers/gpu/drm/omapdrm/TODO rename drivers/{staging => gpu/drm}/omapdrm/omap_connector.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_crtc.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_debugfs.c (98%) rename drivers/{staging => gpu/drm}/omapdrm/omap_dmm_priv.h (100%) rename drivers/{staging => gpu/drm}/omapdrm/omap_dmm_tiler.c (100%) rename drivers/{staging => gpu/drm}/omapdrm/omap_dmm_tiler.h (100%) rename drivers/{staging => gpu/drm}/omapdrm/omap_drv.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_drv.h (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_encoder.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_fb.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_fbdev.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_gem.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_gem_dmabuf.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_gem_helpers.c (98%) rename drivers/{staging => gpu/drm}/omapdrm/omap_irq.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/omap_plane.c (99%) rename drivers/{staging => gpu/drm}/omapdrm/tcm-sita.c (100%) rename drivers/{staging => gpu/drm}/omapdrm/tcm-sita.h (100%) rename drivers/{staging => gpu/drm}/omapdrm/tcm.h (100%) delete mode 100644 drivers/staging/omapdrm/TODO rename {drivers/staging/omapdrm => include/uapi/drm}/omap_drm.h (99%) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index ed9e3af17b31..0ce5f52ac56e 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -215,3 +215,5 @@ source "drivers/gpu/drm/cirrus/Kconfig" source "drivers/gpu/drm/shmobile/Kconfig" source "drivers/gpu/drm/tegra/Kconfig" + +source "drivers/gpu/drm/omapdrm/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 6f58c81cfcbc..b6b43cbc18e4 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -50,4 +50,5 @@ obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_AST) += ast/ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-$(CONFIG_DRM_TEGRA) += tegra/ +obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-y += i2c/ diff --git a/drivers/staging/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig similarity index 100% rename from drivers/staging/omapdrm/Kconfig rename to drivers/gpu/drm/omapdrm/Kconfig diff --git a/drivers/staging/omapdrm/Makefile b/drivers/gpu/drm/omapdrm/Makefile similarity index 100% rename from drivers/staging/omapdrm/Makefile rename to drivers/gpu/drm/omapdrm/Makefile diff --git a/drivers/gpu/drm/omapdrm/TODO b/drivers/gpu/drm/omapdrm/TODO new file mode 100644 index 000000000000..4d8c18aa5dd7 --- /dev/null +++ b/drivers/gpu/drm/omapdrm/TODO @@ -0,0 +1,23 @@ +TODO +. Where should we do eviction (detatch_pages())? We aren't necessarily + accessing the pages via a GART, so maybe we need some other threshold + to put a cap on the # of pages that can be pin'd. + . Use mm_shrinker to trigger unpinning pages. + . This is mainly theoretical since most of these devices don't actually + have swap or harddrive. +. GEM/shmem backed pages can have existing mappings (kernel linear map, + etc..), which isn't really ideal. +. Revisit GEM sync object infrastructure.. TTM has some framework for this + already. Possibly this could be refactored out and made more common? + There should be some way to do this with less wheel-reinvention. + . This can be handled by the dma-buf fence/reservation stuff when it + lands + +Userspace: +. git://anongit.freedesktop.org/xorg/driver/xf86-video-omap + +Currently tested on +. OMAP3530 beagleboard +. OMAP4430 pandaboard +. OMAP4460 pandaboard +. OMAP5432 uEVM diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c similarity index 99% rename from drivers/staging/omapdrm/omap_connector.c rename to drivers/gpu/drm/omapdrm/omap_connector.c index 4cc9ee733c5f..44284fd981fc 100644 --- a/drivers/staging/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_connector.c + * drivers/gpu/drm/omapdrm/omap_connector.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c similarity index 99% rename from drivers/staging/omapdrm/omap_crtc.c rename to drivers/gpu/drm/omapdrm/omap_crtc.c index 510942e67020..2b97cf90071b 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_crtc.c + * drivers/gpu/drm/omapdrm/omap_crtc.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c similarity index 98% rename from drivers/staging/omapdrm/omap_debugfs.c rename to drivers/gpu/drm/omapdrm/omap_debugfs.c index e95540b3e2f6..c0aa40f8ad6a 100644 --- a/drivers/staging/omapdrm/omap_debugfs.c +++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_debugfs.c + * drivers/gpu/drm/omapdrm/omap_debugfs.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/gpu/drm/omapdrm/omap_dmm_priv.h similarity index 100% rename from drivers/staging/omapdrm/omap_dmm_priv.h rename to drivers/gpu/drm/omapdrm/omap_dmm_priv.h diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c similarity index 100% rename from drivers/staging/omapdrm/omap_dmm_tiler.c rename to drivers/gpu/drm/omapdrm/omap_dmm_tiler.c diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.h similarity index 100% rename from drivers/staging/omapdrm/omap_dmm_tiler.h rename to drivers/gpu/drm/omapdrm/omap_dmm_tiler.h diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c similarity index 99% rename from drivers/staging/omapdrm/omap_drv.c rename to drivers/gpu/drm/omapdrm/omap_drv.c index 9d6a584113d2..9083538bd16a 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_drv.c + * drivers/gpu/drm/omapdrm/omap_drv.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h similarity index 99% rename from drivers/staging/omapdrm/omap_drv.h rename to drivers/gpu/drm/omapdrm/omap_drv.h index f921027e7500..d4f997bb4ac0 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_drv.h + * drivers/gpu/drm/omapdrm/omap_drv.h * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark @@ -25,8 +25,8 @@ #include #include #include +#include #include -#include "omap_drm.h" #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) diff --git a/drivers/staging/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c similarity index 99% rename from drivers/staging/omapdrm/omap_encoder.c rename to drivers/gpu/drm/omapdrm/omap_encoder.c index e053160d2db3..7e1f2ab65372 100644 --- a/drivers/staging/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_encoder.c + * drivers/gpu/drm/omapdrm/omap_encoder.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c similarity index 99% rename from drivers/staging/omapdrm/omap_fb.c rename to drivers/gpu/drm/omapdrm/omap_fb.c index bf6421f26c40..9d5f6f696c72 100644 --- a/drivers/staging/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_fb.c + * drivers/gpu/drm/omapdrm/omap_fb.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c similarity index 99% rename from drivers/staging/omapdrm/omap_fbdev.c rename to drivers/gpu/drm/omapdrm/omap_fbdev.c index caefdf9430f8..11eed30efe06 100644 --- a/drivers/staging/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_fbdev.c + * drivers/gpu/drm/omapdrm/omap_fbdev.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c similarity index 99% rename from drivers/staging/omapdrm/omap_gem.c rename to drivers/gpu/drm/omapdrm/omap_gem.c index f9297eb2599e..e8302b02691d 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_gem.c + * drivers/gpu/drm/omapdrm/omap_gem.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c similarity index 99% rename from drivers/staging/omapdrm/omap_gem_dmabuf.c rename to drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c index a3236abfca3d..ac74d1bc67bf 100644 --- a/drivers/staging/omapdrm/omap_gem_dmabuf.c +++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_gem_dmabuf.c + * drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_gem_helpers.c b/drivers/gpu/drm/omapdrm/omap_gem_helpers.c similarity index 98% rename from drivers/staging/omapdrm/omap_gem_helpers.c rename to drivers/gpu/drm/omapdrm/omap_gem_helpers.c index ffb8cceaeb46..e4a66a35fc6a 100644 --- a/drivers/staging/omapdrm/omap_gem_helpers.c +++ b/drivers/gpu/drm/omapdrm/omap_gem_helpers.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_gem_helpers.c + * drivers/gpu/drm/omapdrm/omap_gem_helpers.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c similarity index 99% rename from drivers/staging/omapdrm/omap_irq.c rename to drivers/gpu/drm/omapdrm/omap_irq.c index 2629ba7be6c8..e01303ee00c3 100644 --- a/drivers/staging/omapdrm/omap_irq.c +++ b/drivers/gpu/drm/omapdrm/omap_irq.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_irq.c + * drivers/gpu/drm/omapdrm/omap_irq.c * * Copyright (C) 2012 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c similarity index 99% rename from drivers/staging/omapdrm/omap_plane.c rename to drivers/gpu/drm/omapdrm/omap_plane.c index bb989d7f026d..dd68d14ce615 100644 --- a/drivers/staging/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -1,5 +1,5 @@ /* - * drivers/staging/omapdrm/omap_plane.c + * drivers/gpu/drm/omapdrm/omap_plane.c * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark diff --git a/drivers/staging/omapdrm/tcm-sita.c b/drivers/gpu/drm/omapdrm/tcm-sita.c similarity index 100% rename from drivers/staging/omapdrm/tcm-sita.c rename to drivers/gpu/drm/omapdrm/tcm-sita.c diff --git a/drivers/staging/omapdrm/tcm-sita.h b/drivers/gpu/drm/omapdrm/tcm-sita.h similarity index 100% rename from drivers/staging/omapdrm/tcm-sita.h rename to drivers/gpu/drm/omapdrm/tcm-sita.h diff --git a/drivers/staging/omapdrm/tcm.h b/drivers/gpu/drm/omapdrm/tcm.h similarity index 100% rename from drivers/staging/omapdrm/tcm.h rename to drivers/gpu/drm/omapdrm/tcm.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 329bdb42109f..eca907bf8b6d 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -114,8 +114,6 @@ source "drivers/staging/media/Kconfig" source "drivers/staging/net/Kconfig" -source "drivers/staging/omapdrm/Kconfig" - source "drivers/staging/android/Kconfig" source "drivers/staging/ozwpan/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c7ec486680f7..d810ed729add 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -49,7 +49,6 @@ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ obj-$(CONFIG_MFD_NVEC) += nvec/ -obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ obj-$(CONFIG_USB_G_CCG) += ccg/ diff --git a/drivers/staging/omapdrm/TODO b/drivers/staging/omapdrm/TODO deleted file mode 100644 index abeeb00aaa12..000000000000 --- a/drivers/staging/omapdrm/TODO +++ /dev/null @@ -1,32 +0,0 @@ -TODO -. add video decode/encode support (via syslink3 + codec-engine) - . NOTE: with dmabuf this probably could be split into different driver - so perhaps this TODO doesn't belong here -. where should we do eviction (detatch_pages())? We aren't necessarily - accessing the pages via a GART, so maybe we need some other threshold - to put a cap on the # of pages that can be pin'd. (It is mostly only - of interest in case you have a swap partition/file.. which a lot of - these devices do not.. but it doesn't hurt for the driver to do the - right thing anyways.) - . Use mm_shrinker to trigger unpinning pages. Need to figure out how - to handle next issue first (I think?) - . Note TTM already has some mm_shrinker stuff.. maybe an argument to - move to TTM? Or maybe something that could be factored out in common? -. GEM/shmem backed pages can have existing mappings (kernel linear map, - etc..), which isn't really ideal. -. Revisit GEM sync object infrastructure.. TTM has some framework for this - already. Possibly this could be refactored out and made more common? - There should be some way to do this with less wheel-reinvention. -. Solve PM sequencing on resume. DMM/TILER must be reloaded before any - access is made from any component in the system. Which means on suspend - CRTC's should be disabled, and on resume the LUT should be reprogrammed - before CRTC's are re-enabled, to prevent DSS from trying to DMA from a - buffer mapped in DMM/TILER before LUT is reloaded. - -Userspace: -. git://github.com/robclark/xf86-video-omap.git - -Currently tested on -. OMAP3530 beagleboard -. OMAP4430 pandaboard -. OMAP4460 pandaboard diff --git a/drivers/staging/omapdrm/omap_drm.h b/include/uapi/drm/omap_drm.h similarity index 99% rename from drivers/staging/omapdrm/omap_drm.h rename to include/uapi/drm/omap_drm.h index f0ac34a8973e..1d0b1172664e 100644 --- a/drivers/staging/omapdrm/omap_drm.h +++ b/include/uapi/drm/omap_drm.h @@ -1,5 +1,5 @@ /* - * include/drm/omap_drm.h + * include/uapi/drm/omap_drm.h * * Copyright (C) 2011 Texas Instruments * Author: Rob Clark From 16ef3dfe460616f14120973f78fe640e79862654 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 24 Jan 2013 17:20:33 +0100 Subject: [PATCH 6/8] omapdrm: only take crtc->mutex in crtc callbacks Omapdrm doesn't do anything nefarious with crtc load detection or has any shared resources, so this is enough. We also need to adjust the WARN_ON. Signed-off-by: Daniel Vetter Signed-off-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_crtc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 2b97cf90071b..ac2258f59805 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -274,17 +274,16 @@ static void page_flip_worker(struct work_struct *work) struct omap_crtc *omap_crtc = container_of(work, struct omap_crtc, page_flip_work); struct drm_crtc *crtc = &omap_crtc->base; - struct drm_device *dev = crtc->dev; struct drm_display_mode *mode = &crtc->mode; struct drm_gem_object *bo; - drm_modeset_lock_all(dev); + mutex_lock(&crtc->mutex); omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, 0, 0, mode->hdisplay, mode->vdisplay, crtc->x << 16, crtc->y << 16, mode->hdisplay << 16, mode->vdisplay << 16, vblank_cb, crtc); - drm_modeset_unlock_all(dev); + mutex_unlock(&crtc->mutex); bo = omap_framebuffer_bo(crtc->fb, 0); drm_gem_object_unreference_unlocked(bo); @@ -417,7 +416,7 @@ static void apply_worker(struct work_struct *work) * the callbacks and list modification all serialized * with respect to modesetting ioctls from userspace. */ - drm_modeset_lock_all(dev); + mutex_lock(&crtc->mutex); dispc_runtime_get(); /* @@ -462,16 +461,15 @@ static void apply_worker(struct work_struct *work) out: dispc_runtime_put(); - drm_modeset_unlock_all(dev); + mutex_unlock(&crtc->mutex); } int omap_crtc_apply(struct drm_crtc *crtc, struct omap_drm_apply *apply) { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - struct drm_device *dev = crtc->dev; - WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); + WARN_ON(!mutex_is_locked(&crtc->mutex)); /* no need to queue it again if it is already queued: */ if (apply->queued) From dfe96ddcfa22b44100814b9435770f6ff1309d37 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 24 Jan 2013 17:20:34 +0100 Subject: [PATCH 7/8] omapdrm: simplify locking in the fb debugfs file We don't need to hold onto mode_config.mutex any more to keep the fb objects around. And locking dev->struct_mutex is also not required, since omap_gem_describe only reads data anyway. And for a debug interface it's better to grab fewer locks in case the driver is deadlocked already ... The only thing we need is to hold onto mode_config.fb_lock to ensure the user-created fbs don't disappear. The fbcon fb doesn't need any protection, since it lives as long as the driver (and so the debugfs files) itself. And if the teardown/setup isn't following the right sequence grabbing locks won't prevent a NULL deref on priv->fbdev if the fb is not yet (or no longer) there. Signed-off-by: Daniel Vetter Signed-off-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_debugfs.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_debugfs.c b/drivers/gpu/drm/omapdrm/omap_debugfs.c index c0aa40f8ad6a..c27f59da7f29 100644 --- a/drivers/gpu/drm/omapdrm/omap_debugfs.c +++ b/drivers/gpu/drm/omapdrm/omap_debugfs.c @@ -57,17 +57,6 @@ static int fb_show(struct seq_file *m, void *arg) struct drm_device *dev = node->minor->dev; struct omap_drm_private *priv = dev->dev_private; struct drm_framebuffer *fb; - int ret; - - ret = mutex_lock_interruptible(&dev->mode_config.mutex); - if (ret) - return ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) { - mutex_unlock(&dev->mode_config.mutex); - return ret; - } seq_printf(m, "fbcon "); omap_framebuffer_describe(priv->fbdev->fb, m); @@ -82,9 +71,6 @@ static int fb_show(struct seq_file *m, void *arg) } mutex_unlock(&dev->mode_config.fb_lock); - mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->mode_config.mutex); - return 0; } From 8e44770f093c003d11784060fea4ffc82ad576eb Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sat, 16 Feb 2013 16:40:36 -0500 Subject: [PATCH 8/8] drm/omap: remove fbdev debug enter/leave hooks This will result in badness for drivers that do not implement mode_set_base_atomic(). So don't pretend like we can support this. Signed-off-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_fbdev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 11eed30efe06..f0033bd3e4ae 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -131,9 +131,6 @@ static struct fb_ops omap_fb_ops = { .fb_pan_display = omap_fbdev_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, - - .fb_debug_enter = drm_fb_helper_debug_enter, - .fb_debug_leave = drm_fb_helper_debug_leave, }; static int omap_fbdev_create(struct drm_fb_helper *helper,