mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
Merge branch 'omapdrm-next' of git://people.freedesktop.org/~robclark/linux into drm-next
* 'omapdrm-next' of git://people.freedesktop.org/~robclark/linux: drm/omap: remove fbdev debug enter/leave hooks omapdrm: simplify locking in the fb debugfs file omapdrm: only take crtc->mutex in crtc callbacks drm/omap: move out of staging staging/omapdrm: Use kmemdup rather than duplicating its implementation staging: omapdrm/omap_gem_dmabuf.c: fix memory leakage drm/omap: Add OMAP5 support drm/omap: Add PM capabilities
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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/
|
||||
|
||||
23
drivers/gpu/drm/omapdrm/TODO
Normal file
23
drivers/gpu/drm/omapdrm/TODO
Normal file
@@ -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
|
||||
@@ -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 <rob@ti.com>
|
||||
@@ -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 <rob@ti.com>
|
||||
@@ -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)
|
||||
@@ -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 <rob.clark@linaro.org>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -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,
|
||||
start ? '<' : 'X');
|
||||
fill_map_pt(map, xdiv, ydiv, &block->area.p1,
|
||||
end ? '>' : 'X');
|
||||
map_1d_info(map, xdiv, ydiv, nice, &block->area);
|
||||
for (i = 0; i < omap_dmm->container_height; i++) {
|
||||
map[i] = global_map + i * (w_adj + 1);
|
||||
map[i][w_adj] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&list_lock, flags);
|
||||
spin_lock_irqsave(&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");
|
||||
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,
|
||||
end ? '>' : 'X');
|
||||
map_1d_info(map, xdiv, ydiv, nice,
|
||||
&block->area);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&list_lock, flags);
|
||||
|
||||
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:
|
||||
@@ -903,12 +943,45 @@ error:
|
||||
}
|
||||
#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) {
|
||||
.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
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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 <rob@ti.com>
|
||||
@@ -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,
|
||||
@@ -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 <rob@ti.com>
|
||||
@@ -25,8 +25,8 @@
|
||||
#include <linux/types.h>
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/omap_drm.h>
|
||||
#include <linux/platform_data/omap_drm.h>
|
||||
#include "omap_drm.h"
|
||||
|
||||
|
||||
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
|
||||
@@ -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);
|
||||
@@ -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 <rob@ti.com>
|
||||
@@ -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 <rob@ti.com>
|
||||
@@ -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 <rob@ti.com>
|
||||
@@ -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,
|
||||
@@ -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 <rob.clark@linaro.org>
|
||||
@@ -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)
|
||||
{
|
||||
@@ -1239,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)) {
|
||||
@@ -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 <rob.clark@linaro.org>
|
||||
@@ -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,
|
||||
@@ -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 <rob.clark@linaro.org>
|
||||
@@ -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 <rob.clark@linaro.org>
|
||||
@@ -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 <rob.clark@linaro.org>
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* include/drm/omap_drm.h
|
||||
* include/uapi/drm/omap_drm.h
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments
|
||||
* Author: Rob Clark <rob@ti.com>
|
||||
Reference in New Issue
Block a user