[PATCH 2/2] drm/omap: Add OMAP5 support

Rob Clark rob at ti.com
Tue Dec 18 16:15:18 PST 2012


On Tue, Dec 18, 2012 at 12:02 AM, Andy Gross <andy.gross at ti.com> 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 <andy.gross at ti.com>

Signed-off-by: Rob Clark <rob at ti.com>

> ---
>  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(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,
> +               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:
> @@ -913,7 +953,6 @@ static int omap_dmm_resume(struct device *dev)
>                 return -ENODEV;
>
>         area = (struct tcm_area) {
> -               .is2d = true,
>                 .tcm = NULL,
>                 .p1.x = omap_dmm->container_width - 1,
>                 .p1.y = omap_dmm->container_height - 1,
> diff --git a/drivers/staging/omapdrm/tcm.h b/drivers/staging/omapdrm/tcm.h
> index d273e3e..a8d5ce4 100644
> --- a/drivers/staging/omapdrm/tcm.h
> +++ b/drivers/staging/omapdrm/tcm.h
> @@ -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
> --
> 1.7.5.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list