diff options
author | Lajos Molnar <molnar@ti.com> | 2011-07-15 18:11:11 -0500 |
---|---|---|
committer | Erik Gilling <konkers@android.com> | 2011-07-18 16:11:47 -0700 |
commit | 3b362566ddbe503d9306840e6465bdbc5055f691 (patch) | |
tree | f73084724124adb72ae47b90044135b0d9ec722a | |
parent | 3d85f0dc0ed5bccd10be7ed4e28df0c18e8ccd5b (diff) | |
download | kernel_samsung_tuna-3b362566ddbe503d9306840e6465bdbc5055f691.zip kernel_samsung_tuna-3b362566ddbe503d9306840e6465bdbc5055f691.tar.gz kernel_samsung_tuna-3b362566ddbe503d9306840e6465bdbc5055f691.tar.bz2 |
OMAP:OMAPLFB: Added reference counting for NV12 buffers on display
Added reference count for each time an NV12 buffer is queued to
the display. It is decremented when the buffer is swapped with
another one (including the same one queued again).
This is a crude solution since SGX is not keeping proper readops
count for displayed buffers.
Using atomic operations to change the reference count as the
incrementing and decrementing are done in different blocks
(graphics and display) under different locks. This should
still be OK because the incrementing and the checking is in
the graphics context.
Requires corresponding change in DDK.
Change-Id: I361577a3104e002cf9e5c5452fb2ce967545766b
Signed-off-by: Lajos Molnar <molnar@ti.com>
-rw-r--r-- | drivers/gpu/pvr/devicemem.c | 1 | ||||
-rw-r--r-- | drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c | 11 | ||||
-rw-r--r-- | drivers/gpu/pvr/pvrsrv.c | 14 | ||||
-rw-r--r-- | drivers/gpu/pvr/servicesext.h | 1 | ||||
-rw-r--r-- | drivers/video/omap2/dsscomp/dsscomp.h | 5 | ||||
-rw-r--r-- | drivers/video/omap2/dsscomp/gralloc.c | 29 |
6 files changed, 59 insertions, 2 deletions
diff --git a/drivers/gpu/pvr/devicemem.c b/drivers/gpu/pvr/devicemem.c index 79324ad..b2be580 100644 --- a/drivers/gpu/pvr/devicemem.c +++ b/drivers/gpu/pvr/devicemem.c @@ -556,6 +556,7 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie, psSyncData->ui32ReadOpsComplete = 0; psSyncData->ui32LastOpDumpVal = 0; psSyncData->ui32LastReadOpDumpVal = 0; + psSyncData->ui32DisplayRefCount = 0; #if defined(PDUMP) PDUMPCOMMENT("Allocating kernel sync object"); diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c index 50a6e63..8114e3c 100644 --- a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c +++ b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c @@ -837,6 +837,17 @@ static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie, BUG_ON(i + 1 >= ui32NumMemInfos); psDssData->ovls[k].ba = (u32)LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0).uiAddr; + /* + * :HACK: increment display ref count and save pointer + * to it in stride which is not used for 2D buffers. + */ + atomic_inc(container_of(&ppsMemInfos[i]->psKernelSyncInfo->psSyncData->ui32DisplayRefCount, atomic_t, counter)); + pr_debug("syncData++ = %p.%d\n", + &ppsMemInfos[i]->psKernelSyncInfo->psSyncData->ui32DisplayRefCount, + ppsMemInfos[i]->psKernelSyncInfo->psSyncData->ui32DisplayRefCount); + psDssData->ovls[k].cfg.stride = + (u32) &ppsMemInfos[i]->psKernelSyncInfo->psSyncData->ui32DisplayRefCount; + i++; psLinuxMemArea = ppsMemInfos[i]->sMemBlk.hOSMemHandle; psDssData->ovls[k].uv = (u32)LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0).uiAddr; diff --git a/drivers/gpu/pvr/pvrsrv.c b/drivers/gpu/pvr/pvrsrv.c index a1e02ef..e137fd0 100644 --- a/drivers/gpu/pvr/pvrsrv.c +++ b/drivers/gpu/pvr/pvrsrv.c @@ -1168,6 +1168,20 @@ IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData) } } +IMG_EXPORT +void PVRSVRSignalOSEventObject(void) +{ + SYS_DATA *psSysData; + SysAcquireData(&psSysData); + if (psSysData && psSysData->psGlobalEventObject) + { + IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM; + if(hOSEventKM) + { + OSEventObjectSignalKM(hOSEventKM); + } + } +} IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags) diff --git a/drivers/gpu/pvr/servicesext.h b/drivers/gpu/pvr/servicesext.h index 2731db5..9a359c7 100644 --- a/drivers/gpu/pvr/servicesext.h +++ b/drivers/gpu/pvr/servicesext.h @@ -641,6 +641,7 @@ typedef struct _PVRSRV_SYNC_DATA_ IMG_UINT32 ui32LastOpDumpVal; IMG_UINT32 ui32LastReadOpDumpVal; + IMG_INT32 ui32DisplayRefCount; } PVRSRV_SYNC_DATA; typedef struct _PVRSRV_CLIENT_SYNC_INFO_ diff --git a/drivers/video/omap2/dsscomp/dsscomp.h b/drivers/video/omap2/dsscomp/dsscomp.h index ae6f04c..ecee062 100644 --- a/drivers/video/omap2/dsscomp/dsscomp.h +++ b/drivers/video/omap2/dsscomp/dsscomp.h @@ -33,6 +33,7 @@ #define DEBUG_COMPOSITIONS (1 << 1) #define DEBUG_PHASES (1 << 2) #define DEBUG_WAITS (1 << 3) +#define DEBUG_SYNC (1 << 4) /* * Utility macros @@ -87,6 +88,7 @@ struct dsscomp_data { void (*extra_cb)(dsscomp_t comp, int status); void (*gralloc_cb_fn)(void *, int); void *gralloc_cb_arg; + void *gralloc_global_event; bool must_apply; /* whether composition must be applied */ }; @@ -99,6 +101,9 @@ void dsscomp_gralloc_init(struct dsscomp_dev *cdev); void dsscomp_gralloc_exit(void); int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_mgr_data *d); +/* for SGX PVR integration */ +void PVRSVRSignalOSEventObject(void); + /* basic operation - if not using queues */ int set_dss_ovl_info(struct dss2_ovl_info *oi); int set_dss_mgr_info(struct dss2_mgr_info *mi); diff --git a/drivers/video/omap2/dsscomp/gralloc.c b/drivers/video/omap2/dsscomp/gralloc.c index a4954bc..f118469 100644 --- a/drivers/video/omap2/dsscomp/gralloc.c +++ b/drivers/video/omap2/dsscomp/gralloc.c @@ -41,6 +41,27 @@ static void unpin_tiler_blocks(struct list_head *slots) list_splice_init(slots, &free_slots); } +static void dsscomp_gralloc_decref(dsscomp_t comp) +{ + int i; + + for (i = 0; i < comp->frm.num_ovls; i++) { + if (comp->frm.ovls[i].cfg.color_mode == OMAP_DSS_COLOR_NV12 && + comp->frm.ovls[i].cfg.stride) { + atomic_t *refCnt = container_of( + (int *) comp->frm.ovls[i].cfg.stride, + atomic_t, counter); + atomic_dec(refCnt); + if (debug & DEBUG_SYNC) + dev_info(DEV(cdev), "syncData-- = %p.%d", + refCnt, refCnt->counter); + } + } + + /* trigger SGX global event */ + PVRSVRSignalOSEventObject(); +} + static void dsscomp_gralloc_cb(dsscomp_t comp, int status) { if (status & DSS_COMPLETION_RELEASED) { @@ -51,14 +72,18 @@ static void dsscomp_gralloc_cb(dsscomp_t comp, int status) if ((status == DSS_COMPLETION_DISPLAYED) || (status & DSS_COMPLETION_RELEASED)) { /* complete composition if eclipsed or displayed */ - if (comp->gralloc_cb_fn) { + if (comp->gralloc_cb_fn && comp->gralloc_cb_arg) { if (debug & DEBUG_PHASES) dev_info(DEV(cdev), "[%p] complete flip\n", comp); comp->gralloc_cb_fn(comp->gralloc_cb_arg, 1); } - comp->gralloc_cb_fn = NULL; + comp->gralloc_cb_arg = NULL; } + + if (status & DSS_COMPLETION_RELEASED) + /* release display ref counts */ + dsscomp_gralloc_decref(comp); } /* This is just test code for now that does the setup + apply. |