aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <molnar@ti.com>2011-07-15 18:11:11 -0500
committerErik Gilling <konkers@android.com>2011-07-18 16:11:47 -0700
commit3b362566ddbe503d9306840e6465bdbc5055f691 (patch)
treef73084724124adb72ae47b90044135b0d9ec722a
parent3d85f0dc0ed5bccd10be7ed4e28df0c18e8ccd5b (diff)
downloadkernel_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.c1
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c11
-rw-r--r--drivers/gpu/pvr/pvrsrv.c14
-rw-r--r--drivers/gpu/pvr/servicesext.h1
-rw-r--r--drivers/video/omap2/dsscomp/dsscomp.h5
-rw-r--r--drivers/video/omap2/dsscomp/gralloc.c29
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.