diff options
-rw-r--r-- | drivers/media/video/tiler/tiler-main.c | 8 | ||||
-rw-r--r-- | drivers/media/video/tiler/tmm-pat.c | 31 | ||||
-rw-r--r-- | drivers/media/video/tiler/tmm.h | 2 |
3 files changed, 36 insertions, 5 deletions
diff --git a/drivers/media/video/tiler/tiler-main.c b/drivers/media/video/tiler/tiler-main.c index b863cc2..ede63bf 100644 --- a/drivers/media/video/tiler/tiler-main.c +++ b/drivers/media/video/tiler/tiler-main.c @@ -1212,6 +1212,7 @@ static s32 __init tiler_init(void) struct tcm_pt div_pt; struct tcm *sita = NULL; struct tmm *tmm_pat = NULL; + struct pat_area area = {0}; tiler.alloc = alloc_block; tiler.map = map_block; @@ -1258,12 +1259,17 @@ static s32 __init tiler_init(void) tcm[TILFMT_PAGE] = sita; /* Allocate tiler memory manager (must have 1 unique TMM per TCM ) */ - tmm_pat = tmm_pat_init(0); + tmm_pat = tmm_pat_init(0, dmac_va, dmac_pa); tmm[TILFMT_8BIT] = tmm_pat; tmm[TILFMT_16BIT] = tmm_pat; tmm[TILFMT_32BIT] = tmm_pat; tmm[TILFMT_PAGE] = tmm_pat; + /* Clear out all PAT entries */ + area.x1 = tiler.width - 1; + area.y1 = tiler.height - 1; + tmm_clear(tmm_pat, area); + tiler.nv12_packed = tcm[TILFMT_8BIT] == tcm[TILFMT_16BIT]; tiler_device = kmalloc(sizeof(*tiler_device), GFP_KERNEL); diff --git a/drivers/media/video/tiler/tmm-pat.c b/drivers/media/video/tiler/tmm-pat.c index e47f43f..6f916a8 100644 --- a/drivers/media/video/tiler/tmm-pat.c +++ b/drivers/media/video/tiler/tmm-pat.c @@ -61,6 +61,10 @@ struct fast { struct dmm_mem { struct list_head fast_list; struct dmm *dmm; + u32 *dmac_va; /* coherent memory */ + u32 dmac_pa; /* phys.addr of coherent memory */ + struct page *dummy_pg; /* dummy page */ + u32 dummy_pa; /* phys.addr of dummy page */ }; /* read mem values for a param */ @@ -163,6 +167,8 @@ static void tmm_pat_deinit(struct tmm *tmm) if (--refs == 0) free_page_cache(); + __free_page(pvt->dummy_pg); + mutex_unlock(&mtx); } @@ -262,7 +268,20 @@ static s32 tmm_pat_map(struct tmm *tmm, struct pat_area area, u32 page_pa) return dmm_pat_refill(pvt->dmm, &pat_desc, MANUAL); } -struct tmm *tmm_pat_init(u32 pat_id) +static void tmm_pat_clear(struct tmm *tmm, struct pat_area area) +{ + u16 w = (u8) area.x1 - (u8) area.x0; + u16 h = (u8) area.y1 - (u8) area.y0; + u16 i = (w + 1) * (h + 1); + struct dmm_mem *pvt = (struct dmm_mem *) tmm->pvt; + + while (i--) + pvt->dmac_va[i] = pvt->dummy_pa; + + tmm_pat_map(tmm, area, pvt->dmac_pa); +} + +struct tmm *tmm_pat_init(u32 pat_id, u32 *dmac_va, u32 dmac_pa) { struct tmm *tmm = NULL; struct dmm_mem *pvt = NULL; @@ -272,9 +291,15 @@ struct tmm *tmm_pat_init(u32 pat_id) tmm = kmalloc(sizeof(*tmm), GFP_KERNEL); if (tmm) pvt = kmalloc(sizeof(*pvt), GFP_KERNEL); - if (pvt) { + if (pvt) + pvt->dummy_pg = alloc_page(GFP_KERNEL | GFP_DMA); + if (pvt->dummy_pg) { /* private data */ pvt->dmm = dmm; + pvt->dmac_pa = dmac_pa; + pvt->dmac_va = dmac_va; + pvt->dummy_pa = page_to_phys(pvt->dummy_pg); + INIT_LIST_HEAD(&pvt->fast_list); /* increate tmm_pat references */ @@ -288,7 +313,7 @@ struct tmm *tmm_pat_init(u32 pat_id) tmm->get = tmm_pat_get_pages; tmm->free = tmm_pat_free_pages; tmm->map = tmm_pat_map; - tmm->clear = NULL; /* not yet supported */ + tmm->clear = tmm_pat_clear; return tmm; } diff --git a/drivers/media/video/tiler/tmm.h b/drivers/media/video/tiler/tmm.h index 9f2a99d..e3365d4 100644 --- a/drivers/media/video/tiler/tmm.h +++ b/drivers/media/video/tiler/tmm.h @@ -125,6 +125,6 @@ void tmm_deinit(struct tmm *tmm) * * Initialize TMM for PAT with given id. */ -struct tmm *tmm_pat_init(u32 pat_id); +struct tmm *tmm_pat_init(u32 pat_id, u32 *dmac_va, u32 dmac_pa); #endif |