aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Gross <andy.gross@ti.com>2012-04-11 16:56:53 -0500
committerAndy Green <andy.green@linaro.org>2012-04-13 17:47:05 +0800
commit5a1aaccc663546ec659bd1cf39029febae8a7f87 (patch)
tree3684ccab4a357a7830170cc2509b0e1e21996f47
parent2b51d222daf0cdde909343c72763595916036a81 (diff)
staging: drm/omap: Add support for OMAP5 DMMtilt-3.3-omap5-eng-21
Added support for the OMAP5 DMM. The OMAP5 DMM supports 256MiB of tiler address space; 128MiB of 1D and 128MiB of 2D. The PAT programming was changed to accomodate the new LUT layout. Debugfs entries were also changed to display the full LUT information. Signed-off-by: Andy Gross <andy.gross@ti.com>
-rw-r--r--drivers/staging/omapdrm/omap_dmm_priv.h5
-rw-r--r--drivers/staging/omapdrm/omap_dmm_tiler.c152
-rw-r--r--drivers/staging/omapdrm/omap_dmm_tiler.h2
-rw-r--r--drivers/staging/omapdrm/tcm.h1
4 files changed, 106 insertions, 54 deletions
diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/staging/omapdrm/omap_dmm_priv.h
index 2f529ab4b7c..a2df9958724 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 68da290141a..463ca855597 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.c
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -172,7 +172,8 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)
* corresponding slot is cleared (ie. dummy_pa is programmed)
*/
static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
- struct page **pages, uint32_t npages, uint32_t roll)
+ struct page **pages, uint32_t npages, uint32_t roll,
+ uint32_t y_offset)
{
dma_addr_t pat_pa = 0;
uint32_t *data;
@@ -181,9 +182,8 @@ static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
int columns = (1 + area->x1 - area->x0);
int rows = (1 + area->y1 - area->y0);
int i = columns*rows;
- u32 *lut = omap_dmm->lut + (engine->tcm->lut_id * omap_dmm->lut_width *
- omap_dmm->lut_height) +
- (area->y0 * omap_dmm->lut_width) + area->x0;
+ u32 *lut = engine->tcm->lut + (area->y0 * omap_dmm->lut_width) +
+ area->x0;
pat = alloc_dma(txn, sizeof(struct pat), &pat_pa);
@@ -191,9 +191,13 @@ static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
txn->last_pat->next_pa = (uint32_t)pat_pa;
pat->area = *area;
+
+ pat->area.y0 += y_offset;
+ pat->area.y1 += y_offset;
+
pat->ctrl = (struct pat_ctrl){
.start = 1,
- .lut_id = engine->tcm->lut_id,
+ .lut_id = 0,
};
data = alloc_dma(txn, 4*i, &pat->data_pa);
@@ -273,18 +277,23 @@ static int fill(struct tcm_area *area, struct page **pages,
int ret = 0;
struct tcm_area slice, area_s;
struct dmm_txn *txn;
+ u32 y_offset = 0;
txn = dmm_txn_init(omap_dmm, area->tcm);
if (IS_ERR_OR_NULL(txn))
return PTR_ERR(txn);
+ if (cpu_is_omap54xx() && !area->is2d)
+ y_offset = OMAP5_LUT_OFFSET;
+
tcm_for_each_slice(slice, *area, area_s) {
struct pat_area p_area = {
- .x0 = slice.p0.x, .y0 = slice.p0.y,
- .x1 = slice.p1.x, .y1 = slice.p1.y,
+ .x0 = slice.p0.x, .y0 = slice.p0.y,
+ .x1 = slice.p1.x, .y1 = slice.p1.y,
};
- ret = dmm_txn_append(txn, &p_area, pages, npages, roll);
+ ret = dmm_txn_append(txn, &p_area, pages, npages, roll,
+ y_offset);
if (ret)
goto fail;
@@ -595,6 +604,16 @@ 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;
+ /* adjust parameters for OMAP5
+ * Even though there is 1 LUT, it is twice the size of the LUT in OMAP4.
+ * Programming 1D areas requires an offset be added to all of the Y
+ * coordinates
+ */
+ if (cpu_is_omap54xx()) {
+ omap_dmm->num_lut++;
+ omap_dmm->lut_height = 128;
+ }
+
/* initialize DMM registers */
writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__0);
writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__1);
@@ -697,22 +716,29 @@ static int omap_dmm_probe(struct platform_device *dev)
goto fail;
}
+ /* get offset into LUT table for this container */
+ omap_dmm->tcm[i]->lut = omap_dmm->lut +
+ (i * omap_dmm->lut_width * omap_dmm->lut_height);
omap_dmm->tcm[i]->lut_id = i;
}
/* 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 (cpu_is_omap54xx())
+ containers[TILFMT_PAGE] = omap_dmm->tcm[1];
+ else
+ containers[TILFMT_PAGE] = omap_dmm->tcm[0];
INIT_LIST_HEAD(&omap_dmm->alloc_head);
spin_lock_init(&omap_dmm->list_lock);
area = (struct tcm_area) {
.is2d = true,
- .tcm = NULL,
+ .tcm = omap_dmm->tcm[0],
.p1.x = omap_dmm->container_width - 1,
.p1.y = omap_dmm->container_height - 1,
};
@@ -721,8 +747,13 @@ static int omap_dmm_probe(struct platform_device *dev)
omap_dmm->lut[i] = omap_dmm->dummy_pa;
/* 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(omap_dmm->dev, "refill failed");
+
+ if (cpu_is_omap54xx()) {
+ area.tcm = omap_dmm->tcm[1];
+ area.is2d = false;
+
if (fill(&area, NULL, 0, 0, true))
dev_err(omap_dmm->dev, "refill failed");
}
@@ -825,6 +856,7 @@ 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 */
@@ -834,55 +866,69 @@ int tiler_map_show(struct seq_file *s, void *arg)
h_adj = omap_dmm->lut_height / ydiv;
w_adj = omap_dmm->lut_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(&omap_dmm->list_lock, flags);
-
- 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 (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);
+
+ 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(&omap_dmm->list_lock, flags);
+
+ list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) {
+ if (block->area.tcm->lut_id == 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(&omap_dmm->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");
+ spin_unlock_irqrestore(&omap_dmm->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:
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h
index 740911df5fc..e2ce4d7948f 100644
--- a/drivers/staging/omapdrm/omap_dmm_tiler.h
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.h
@@ -141,7 +141,7 @@ static inline bool validfmt(enum tiler_fmt fmt)
static inline int dmm_is_available(void)
{
- return cpu_is_omap44xx();
+ return cpu_is_omap44xx() || cpu_is_omap54xx();
}
#endif
diff --git a/drivers/staging/omapdrm/tcm.h b/drivers/staging/omapdrm/tcm.h
index d273e3ee0b4..d5ba4be089c 100644
--- a/drivers/staging/omapdrm/tcm.h
+++ b/drivers/staging/omapdrm/tcm.h
@@ -57,6 +57,7 @@ struct tcm_area {
struct tcm {
u16 width, height; /* container dimensions */
+ u32 *lut; /* ptr to LUT table */
int lut_id; /* Lookup table identifier */
/* 'pvt' structure shall contain any tcm details (attr) along with