Skip to content

Commit

Permalink
Merge branch 'omapdrm-next' of git://people.freedesktop.org/~robclark…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Dave Airlie committed Feb 19, 2013
2 parents 3314fdf + 8e44770 commit 8e26875
Show file tree
Hide file tree
Showing 28 changed files with 220 additions and 122 deletions.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
1 change: 1 addition & 0 deletions drivers/gpu/drm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/
File renamed without changes.
File renamed without changes.
23 changes: 23 additions & 0 deletions drivers/gpu/drm/omapdrm/TODO
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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>
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();

/*
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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:
Expand All @@ -903,12 +943,45 @@ 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) {
.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
},
};

Expand Down
File renamed without changes.
Loading

0 comments on commit 8e26875

Please sign in to comment.