[PATCH 2/2] 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 --- 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 273ec12..58bcd6a 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 c42c5e5..3910215 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(0x, omap_dmm->base + DMM_PAT_VIEW__0); writel(0x, 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 *
[PATCH 2/2] 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 --- 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 273ec12..58bcd6a 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 c42c5e5..3910215 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(0x, omap_dmm->base + DMM_PAT_VIEW__0); writel(0x, 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] = globa
[PATCH 2/2] drm/omap: Add OMAP5 support
On Tue, Dec 18, 2012 at 12:02 AM, Andy Gross wrote: > 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 > --- > 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 273ec12..58bcd6a 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 c42c5e5..3910215 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(0x, omap_dmm->base + DMM_PAT_VIEW__0); > writel(0x, 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); >
Re: [PATCH 2/2] drm/omap: Add OMAP5 support
On Tue, Dec 18, 2012 at 12:02 AM, Andy Gross wrote: > 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 > --- > 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 273ec12..58bcd6a 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 c42c5e5..3910215 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(0x, omap_dmm->base + DMM_PAT_VIEW__0); > writel(0x, 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); >
[PATCH 2/2] 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 --- 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 273ec12..58bcd6a 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 c42c5e5..3910215 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(0x, omap_dmm->base + DMM_PAT_VIEW__0); writel(0x, 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); -
[PATCH 2/2] 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 --- 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 273ec12..58bcd6a 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 c42c5e5..3910215 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(0x, omap_dmm->base + DMM_PAT_VIEW__0); writel(0x, 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); -