forked from Minki/linux
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 <andy.gross@ti.com> Signed-off-by: Rob Clark <rob@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4836d15789
commit
238083ad5d
@ -118,6 +118,11 @@ struct pat {
|
|||||||
#define DESCR_SIZE 128
|
#define DESCR_SIZE 128
|
||||||
#define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE))
|
#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;
|
||||||
|
|
||||||
struct dmm_txn {
|
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;
|
txn->last_pat->next_pa = (uint32_t)pat_pa;
|
||||||
|
|
||||||
pat->area = *area;
|
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){
|
pat->ctrl = (struct pat_ctrl){
|
||||||
.start = 1,
|
.start = 1,
|
||||||
.lut_id = engine->tcm->lut_id,
|
.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_width = ((pat_geom >> 16) & 0xF) << 5;
|
||||||
omap_dmm->lut_height = ((pat_geom >> 24) & 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 */
|
/* initialize DMM registers */
|
||||||
writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__0);
|
writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__0);
|
||||||
writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__1);
|
writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__1);
|
||||||
@ -701,6 +711,9 @@ static int omap_dmm_probe(struct platform_device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* init containers */
|
/* 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++) {
|
for (i = 0; i < omap_dmm->num_lut; i++) {
|
||||||
omap_dmm->tcm[i] = sita_init(omap_dmm->container_width,
|
omap_dmm->tcm[i] = sita_init(omap_dmm->container_width,
|
||||||
omap_dmm->container_height,
|
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 */
|
/* assign access mode containers to applicable tcm container */
|
||||||
/* OMAP 4 has 1 container for all 4 views */
|
/* 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_8BIT] = omap_dmm->tcm[0];
|
||||||
containers[TILFMT_16BIT] = omap_dmm->tcm[0];
|
containers[TILFMT_16BIT] = omap_dmm->tcm[0];
|
||||||
containers[TILFMT_32BIT] = 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) {
|
area = (struct tcm_area) {
|
||||||
.is2d = true,
|
|
||||||
.tcm = NULL,
|
.tcm = NULL,
|
||||||
.p1.x = omap_dmm->container_width - 1,
|
.p1.x = omap_dmm->container_width - 1,
|
||||||
.p1.y = omap_dmm->container_height - 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 h_adj;
|
||||||
int w_adj;
|
int w_adj;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int lut_idx;
|
||||||
|
|
||||||
|
|
||||||
if (!omap_dmm) {
|
if (!omap_dmm) {
|
||||||
/* early return if dmm/tiler device is not initialized */
|
/* early return if dmm/tiler device is not initialized */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h_adj = omap_dmm->lut_height / ydiv;
|
h_adj = omap_dmm->container_height / ydiv;
|
||||||
w_adj = omap_dmm->lut_width / xdiv;
|
w_adj = omap_dmm->container_width / xdiv;
|
||||||
|
|
||||||
map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL);
|
map = kmalloc(h_adj * sizeof(*map), GFP_KERNEL);
|
||||||
global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL);
|
global_map = kmalloc((w_adj + 1) * h_adj, GFP_KERNEL);
|
||||||
|
|
||||||
if (!map || !global_map)
|
if (!map || !global_map)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
memset(global_map, ' ', (w_adj + 1) * h_adj);
|
for (lut_idx = 0; lut_idx < omap_dmm->num_lut; lut_idx++) {
|
||||||
for (i = 0; i < omap_dmm->lut_height; i++) {
|
memset(map, 0, sizeof(h_adj * sizeof(*map)));
|
||||||
map[i] = global_map + i * (w_adj + 1);
|
memset(global_map, ' ', (w_adj + 1) * h_adj);
|
||||||
map[i][w_adj] = 0;
|
|
||||||
}
|
|
||||||
spin_lock_irqsave(&list_lock, flags);
|
|
||||||
|
|
||||||
list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) {
|
for (i = 0; i < omap_dmm->container_height; i++) {
|
||||||
if (block->fmt != TILFMT_PAGE) {
|
map[i] = global_map + i * (w_adj + 1);
|
||||||
fill_map(map, xdiv, ydiv, &block->area, *m2dp, true);
|
map[i][w_adj] = 0;
|
||||||
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);
|
spin_lock_irqsave(&list_lock, flags);
|
||||||
|
|
||||||
if (s) {
|
list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) {
|
||||||
seq_printf(s, "BEGIN DMM TILER MAP\n");
|
if (block->area.tcm == omap_dmm->tcm[lut_idx]) {
|
||||||
for (i = 0; i < 128; i++)
|
if (block->fmt != TILFMT_PAGE) {
|
||||||
seq_printf(s, "%03d:%s\n", i, map[i]);
|
fill_map(map, xdiv, ydiv, &block->area,
|
||||||
seq_printf(s, "END TILER MAP\n");
|
*m2dp, true);
|
||||||
} else {
|
if (!*++a2dp)
|
||||||
dev_dbg(omap_dmm->dev, "BEGIN DMM TILER MAP\n");
|
a2dp = a2d;
|
||||||
for (i = 0; i < 128; i++)
|
if (!*++m2dp)
|
||||||
dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]);
|
m2dp = m2d;
|
||||||
dev_dbg(omap_dmm->dev, "END TILER MAP\n");
|
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:
|
error:
|
||||||
@ -913,7 +953,6 @@ static int omap_dmm_resume(struct device *dev)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
area = (struct tcm_area) {
|
area = (struct tcm_area) {
|
||||||
.is2d = true,
|
|
||||||
.tcm = NULL,
|
.tcm = NULL,
|
||||||
.p1.x = omap_dmm->container_width - 1,
|
.p1.x = omap_dmm->container_width - 1,
|
||||||
.p1.y = omap_dmm->container_height - 1,
|
.p1.y = omap_dmm->container_height - 1,
|
||||||
|
@ -59,6 +59,8 @@ struct tcm {
|
|||||||
u16 width, height; /* container dimensions */
|
u16 width, height; /* container dimensions */
|
||||||
int lut_id; /* Lookup table identifier */
|
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
|
/* 'pvt' structure shall contain any tcm details (attr) along with
|
||||||
linked list of allocated areas and mutex for mutually exclusive access
|
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
|
to the list. It may also contain copies of width and height to notice
|
||||||
|
Loading…
Reference in New Issue
Block a user