summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMax Krummenacher <max.krummenacher@toradex.com>2015-03-09 16:33:55 +0100
committerMax Krummenacher <max.krummenacher@toradex.com>2015-03-09 16:35:34 +0100
commitb38048c4b7a66bf03ccfc15c2edd23f51d08b3b9 (patch)
treee88022733f2346316d1ebb07a1135f9f5d5f0518 /drivers
parent2fb42416d67952647374e53563e2bbae2bded1f0 (diff)
parent33597e348b2d60dd5c71890ef7b7d3d3fd6e4e97 (diff)
update to upstream rel_imx_3.10.17_1.0.2_ga
Merge remote-tracking branch 'freescale-imx/imx_3.10.17_1.0.0_ga' into toradex_imx_3.10.17_1.0.0_ga-next
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c11
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c56
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h8
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c5
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c158
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c5
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c127
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h10
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h58
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h13
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c14
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c58
-rw-r--r--drivers/regulator/Kconfig6
-rw-r--r--drivers/regulator/pfuze100-regulator.c185
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c1
17 files changed, 482 insertions, 237 deletions
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
index 541975b93e08..9cc7f0ea31d8 100644
--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
@@ -6559,6 +6559,17 @@ gckHARDWARE_DumpGPUState(
dmaAddress1 = dmaAddress2 =
dmaLow = dmaHigh = 0;
+ gckOS_Delay(gcvNULL, gcdPOWEROFF_TIMEOUT);
+
+ if (Hardware->chipPowerState != gcvPOWER_ON
+ && Hardware->chipPowerState != gcvPOWER_IDLE
+ )
+ {
+ gcmkPRINT("[galcore]: Can't dump when GPU is power off or clock off.");
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
/* Verify whether DMA is running. */
gcmkONERROR(_VerifyDMA(
os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
index 879d467e3620..ea69d81d5e67 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
@@ -165,6 +165,8 @@ gckKERNEL_Construct(
kernel->dvfs = gcvNULL;
#endif
+ kernel->vidmemMutex = gcvNULL;
+
/* Initialize the gckKERNEL object. */
kernel->object.type = gcvOBJ_KERNEL;
kernel->os = Os;
@@ -297,6 +299,9 @@ gckKERNEL_Construct(
gcmkONERROR(gckOS_CreateSyncTimeline(Os, &kernel->timeline));
#endif
+ /* Construct a video memory mutex. */
+ gcmkONERROR(gckOS_GetVideoMemoryMutex(Os, &kernel->vidmemMutex));
+
/* Return pointer to the gckKERNEL object. */
*Kernel = kernel;
@@ -529,7 +534,7 @@ gckKERNEL_Destroy(
return gcvSTATUS_OK;
}
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/oom.h>
@@ -565,30 +570,33 @@ static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel)
struct mm_struct *mm;
struct signal_struct *sig;
gcuDATABASE_INFO info;
- int oom_adj;
+ int oom_adj, pid;
task_lock(p);
mm = p->mm;
sig = p->signal;
+ pid = p->pid;
if (!mm || !sig) {
task_unlock(p);
continue;
}
oom_adj = sig->oom_adj;
+ task_unlock(p);
if (oom_adj < min_adj) {
- task_unlock(p);
continue;
}
+ read_unlock(&tasklist_lock);
+
tasksize = 0;
- if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
+ if (gckKERNEL_QueryProcessDB(Kernel, pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
tasksize += info.counters.bytes / PAGE_SIZE;
}
- if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
+ if (gckKERNEL_QueryProcessDB(Kernel, pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
tasksize += info.counters.bytes / PAGE_SIZE;
}
- task_unlock(p);
+ read_lock(&tasklist_lock);
if (tasksize <= 0)
continue;
@@ -667,7 +675,7 @@ _AllocateMemory(
gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
gcmkVERIFY_ARGUMENT(Bytes != 0);
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
_AllocateMemory_Retry:
#endif
/* Get initial pool. */
@@ -767,7 +775,7 @@ _AllocateMemory_Retry:
{
gckOS_Print("gpu virtual memory 0x%x cannot be allocated in force contiguous request!\n", physAddr);
- gcmkONERROR(gckVIDMEM_Free(node));
+ gcmkONERROR(gckVIDMEM_Free(Kernel, node));
node = gcvNULL;
}
@@ -797,7 +805,8 @@ _AllocateMemory_Retry:
if (gcmIS_SUCCESS(status))
{
/* Allocate memory. */
- status = gckVIDMEM_AllocateLinear(videoMemory,
+ status = gckVIDMEM_AllocateLinear(Kernel,
+ videoMemory,
Bytes,
Alignment,
Type,
@@ -858,10 +867,18 @@ _AllocateMemory_Retry:
if (node == gcvNULL)
{
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
if(forceContiguous == gcvTRUE)
{
- if(force_contiguous_lowmem_shrink(Kernel) == 0)
+ int ret;
+ /* Acquire the mutex. */
+ gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE));
+
+ ret = force_contiguous_lowmem_shrink(Kernel);
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+
+ if(ret == 0)
{
/* Sleep 1 millisecond. */
gckOS_Delay(gcvNULL, 1);
@@ -1249,14 +1266,6 @@ gckKERNEL_Dispatch(
node->VidMem.logical = gcvNULL;
}
#endif
- /* Free video memory. */
- gcmkONERROR(
- gckVIDMEM_Free(node));
-
- gcmkONERROR(
- gckKERNEL_RemoveProcessDB(Kernel,
- processID, gcvDB_VIDEO_MEMORY,
- node));
if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
{
@@ -1280,6 +1289,15 @@ gckKERNEL_Dispatch(
node));
}
+ /* Free video memory. */
+ gcmkONERROR(
+ gckVIDMEM_Free(Kernel, node));
+
+ gcmkONERROR(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_VIDEO_MEMORY,
+ node));
+
break;
case gcvHAL_LOCK_VIDEO_MEMORY:
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
index d7ff9cf16372..769479843436 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
@@ -453,6 +453,8 @@ struct _gckKERNEL
#if gcdANDROID_NATIVE_FENCE_SYNC
gctHANDLE timeline;
#endif
+
+ gctPOINTER vidmemMutex;
};
struct _FrequencyHistory
@@ -766,9 +768,6 @@ typedef union _gcuVIDMEM_NODE
/* Actual physical address */
gctUINT32 addresses[gcdMAX_GPU_COUNT];
- /* Mutex. */
- gctPOINTER mutex;
-
/* Locked counter. */
gctINT32 lockeds[gcdMAX_GPU_COUNT];
@@ -824,9 +823,6 @@ struct _gckVIDMEM
/* Allocation threshold. */
gctSIZE_T threshold;
- /* The heap mutex. */
- gctPOINTER mutex;
-
#if gcdUSE_VIDMEM_PER_PID
/* The Pid this VidMem belongs to. */
gctUINT32 pid;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
index ce2c18a102b6..ae12dffba3e6 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
@@ -1060,6 +1060,7 @@ _AllocateLinear(
/* Free the command buffer. */
gcmkCHECK_STATUS(gckVIDMEM_Free(
+ Command->kernel->kernel,
node
));
}
@@ -1082,7 +1083,7 @@ _FreeLinear(
gcmkERR_BREAK(gckVIDMEM_Unlock(Kernel->kernel, Node, gcvSURF_TYPE_UNKNOWN, gcvNULL));
/* Free the linear buffer. */
- gcmkERR_BREAK(gckVIDMEM_Free(Node));
+ gcmkERR_BREAK(gckVIDMEM_Free(Kernel->kernel, Node));
}
while (gcvFALSE);
@@ -1676,7 +1677,7 @@ _TaskFreeVideoMemory(
= (gcsTASK_FREE_VIDEO_MEMORY_PTR) TaskHeader->task;
/* Free video memory. */
- gcmkERR_BREAK(gckVIDMEM_Free(gcmUINT64_TO_PTR(task->node)));
+ gcmkERR_BREAK(gckVIDMEM_Free(Command->kernel->kernel, gcmUINT64_TO_PTR(task->node)));
/* Update the reference counter. */
TaskHeader->container->referenceCount -= 1;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
index b181f55ec55e..6a0f8e0e2856 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
@@ -165,7 +165,6 @@ gckKERNEL_FindDatabase(
gceSTATUS status;
gcsDATABASE_PTR database, previous;
gctSIZE_T slot;
- gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d LastProcessID=%d",
Kernel, ProcessID, LastProcessID);
@@ -173,11 +172,6 @@ gckKERNEL_FindDatabase(
/* Compute the hash for the database. */
slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Check whether we are getting the last known database. */
if (LastProcessID)
{
@@ -221,9 +215,6 @@ gckKERNEL_FindDatabase(
}
}
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
-
/* Return the database. */
*Database = database;
@@ -232,11 +223,6 @@ gckKERNEL_FindDatabase(
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
/* Return the status. */
gcmkFOOTER();
@@ -267,16 +253,10 @@ gckKERNEL_DeleteDatabase(
)
{
gceSTATUS status;
- gctBOOL acquired = gcvFALSE;
gcsDATABASE_PTR database;
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Check slot value. */
gcmkVERIFY_ARGUMENT(Database->slot < gcmCOUNTOF(Kernel->db->db));
@@ -323,19 +303,11 @@ gckKERNEL_DeleteDatabase(
/* Keep database as the last database. */
Kernel->db->lastDatabase = Database;
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
-
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
/* Return the status. */
gcmkFOOTER();
@@ -371,16 +343,10 @@ gckKERNEL_NewRecord(
)
{
gceSTATUS status;
- gctBOOL acquired = gcvFALSE;
gcsDATABASE_RECORD_PTR record = gcvNULL;
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
if (Kernel->db->freeRecord != gcvNULL)
{
/* Allocate the record from the free list. */
@@ -403,9 +369,6 @@ gckKERNEL_NewRecord(
record->next = Database->list[Slot];
Database->list[Slot] = record;
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
-
/* Return the record. */
*Record = record;
@@ -414,11 +377,6 @@ gckKERNEL_NewRecord(
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
if (record != gcvNULL)
{
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
@@ -464,19 +422,12 @@ gckKERNEL_DeleteRecord(
)
{
gceSTATUS status;
- gctBOOL acquired = gcvFALSE;
gcsDATABASE_RECORD_PTR record, previous;
gctUINT32 slot = _GetSlot(Database, Data);
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
Kernel, Database, Type, Data);
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
-
/* Scan the database for this record. */
for (record = Database->list[slot], previous = gcvNULL;
record != gcvNULL;
@@ -520,19 +471,11 @@ gckKERNEL_DeleteRecord(
record->next = Kernel->db->freeRecord;
Kernel->db->freeRecord = record;
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
-
/* Success. */
gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
/* Return the status. */
gcmkFOOTER();
@@ -574,18 +517,12 @@ gckKERNEL_FindRecord(
)
{
gceSTATUS status;
- gctBOOL acquired = gcvFALSE;
gcsDATABASE_RECORD_PTR record;
gctUINT32 slot = _GetSlot(Database, Data);
gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
Kernel, Database, Type, Data);
- /* Acquire the database mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Scan the database for this record. */
for (record = Database->list[slot];
record != gcvNULL;
@@ -614,19 +551,11 @@ gckKERNEL_FindRecord(
gckOS_MemCopy(Record, record, sizeof(gcsDATABASE_RECORD)));
}
- /* Release the database mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
-
/* Success. */
gcmkFOOTER_ARG("Record=0x%x", Record);
return gcvSTATUS_OK;
OnError:
- if (acquired)
- {
- /* Release the database mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
- }
/* Return the status. */
gcmkFOOTER();
@@ -807,6 +736,7 @@ gckKERNEL_AddProcessDB(
gcsDATABASE_PTR database;
gcsDATABASE_RECORD_PTR record = gcvNULL;
gcsDATABASE_COUNTERS * count;
+ gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x "
"Physical=0x%x Size=%lu",
@@ -815,6 +745,11 @@ gckKERNEL_AddProcessDB(
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Special case the idle record. */
if (Type == gcvDB_IDLE)
{
@@ -869,6 +804,8 @@ gckKERNEL_AddProcessDB(
}
}
#endif
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
/* Success. */
gcmkFOOTER_NO();
@@ -878,6 +815,7 @@ gckKERNEL_AddProcessDB(
/* Verify the arguments. */
gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+
/* Find the database. */
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
@@ -943,11 +881,20 @@ gckKERNEL_AddProcessDB(
}
}
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
/* Return the status. */
gcmkFOOTER();
return status;
@@ -987,6 +934,7 @@ gckKERNEL_RemoveProcessDB(
gceSTATUS status;
gcsDATABASE_PTR database;
gctSIZE_T bytes = 0;
+ gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
Kernel, ProcessID, Type, Pointer);
@@ -995,6 +943,11 @@ gckKERNEL_RemoveProcessDB(
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Find the database. */
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
@@ -1041,11 +994,20 @@ gckKERNEL_RemoveProcessDB(
break;
}
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
/* Return the status. */
gcmkFOOTER();
return status;
@@ -1087,6 +1049,7 @@ gckKERNEL_FindProcessDB(
{
gceSTATUS status;
gcsDATABASE_PTR database;
+ gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
Kernel, ProcessID, ThreadID, Type, Pointer);
@@ -1095,6 +1058,11 @@ gckKERNEL_FindProcessDB(
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Find the database. */
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
@@ -1102,11 +1070,20 @@ gckKERNEL_FindProcessDB(
gcmkONERROR(
gckKERNEL_FindRecord(Kernel, database, Type, Pointer, Record));
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
/* Return the status. */
gcmkFOOTER();
return status;
@@ -1145,12 +1122,18 @@ gckKERNEL_DestroyProcessDB(
gcuVIDMEM_NODE_PTR node;
gckKERNEL kernel = Kernel;
gctUINT32 i;
+ gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Find the database. */
gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
@@ -1194,12 +1177,15 @@ gckKERNEL_DestroyProcessDB(
/* Next next record. */
next = record->next;
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ acquired = gcvFALSE;
+
/* Dispatch on record type. */
switch (record->type)
{
case gcvDB_VIDEO_MEMORY:
/* Free the video memory. */
- status = gckVIDMEM_Free(gcmUINT64_TO_PTR(record->data));
+ status = gckVIDMEM_Free(Kernel, gcmUINT64_TO_PTR(record->data));
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: VIDEO_MEMORY 0x%x (status=%d)",
@@ -1364,6 +1350,10 @@ gckKERNEL_DestroyProcessDB(
break;
}
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Delete the record. */
gcmkONERROR(gckKERNEL_DeleteRecord(Kernel,
database,
@@ -1377,11 +1367,20 @@ gckKERNEL_DestroyProcessDB(
/* Delete the database. */
gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
/* Return the status. */
gcmkFOOTER();
return status;
@@ -1424,6 +1423,7 @@ gckKERNEL_QueryProcessDB(
{
gceSTATUS status;
gcsDATABASE_PTR database;
+ gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x",
Kernel, ProcessID, Type, Info);
@@ -1432,6 +1432,11 @@ gckKERNEL_QueryProcessDB(
gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
gcmkVERIFY_ARGUMENT(Info != gcvNULL);
+ /* Acquire the database mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Find the database. */
gcmkONERROR(
gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database));
@@ -1496,11 +1501,20 @@ gckKERNEL_QueryProcessDB(
break;
}
+ /* Release the database mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the database mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
+ }
+
/* Return the status. */
gcmkFOOTER();
return status;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
index 01f71d8e4176..aa066063e586 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
@@ -2280,7 +2280,7 @@ gckEVENT_Notify(
/* Free video memory. */
status =
- gckVIDMEM_Free(node);
+ gckVIDMEM_Free(Event->kernel, node);
break;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
index d7b8e0873252..c1f37172d069 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
@@ -308,7 +308,8 @@ gckKERNEL_AllocateLinearMemory(
if(*Pool == gcvPOOL_SYSTEM)
Type |= gcvSURF_VG;
/* Allocate memory. */
- status = gckVIDMEM_AllocateLinear(videoMemory,
+ status = gckVIDMEM_AllocateLinear(Kernel,
+ videoMemory,
Bytes,
Alignment,
Type,
@@ -599,7 +600,7 @@ gceSTATUS gckVGKERNEL_Dispatch(
#endif /* __QNXNTO__ */
/* Free video memory. */
- gcmkERR_BREAK(gckVIDMEM_Free(
+ gcmkERR_BREAK(gckVIDMEM_Free(Kernel,
node
));
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
index 5699996125cd..740006b4d5a1 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
@@ -250,8 +250,6 @@ gckVIDMEM_ConstructVirtual(
node->Virtual.lockKernels[i] = gcvNULL;
}
- node->Virtual.mutex = gcvNULL;
-
gcmkONERROR(gckOS_GetProcessID(&node->Virtual.processID));
#ifdef __QNXNTO__
@@ -267,10 +265,6 @@ gckVIDMEM_ConstructVirtual(
gcmkONERROR(gckOS_ZeroMemory(&node->Virtual.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
- /* Create the mutex. */
- gcmkONERROR(
- gckOS_CreateMutex(os, &node->Virtual.mutex));
-
/* Allocate the virtual memory. */
gcmkONERROR(
gckOS_AllocatePagedMemoryEx(os,
@@ -303,12 +297,6 @@ OnError:
/* Roll back. */
if (node != gcvNULL)
{
- if (node->Virtual.mutex != gcvNULL)
- {
- /* Destroy the mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->Virtual.mutex));
- }
-
/* Free the structure. */
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
}
@@ -361,9 +349,6 @@ gckVIDMEM_DestroyVirtual(
}
#endif
- /* Delete the mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(os, Node->Virtual.mutex));
-
for (i = 0; i < gcdMAX_GPU_COUNT; i++)
{
if (Node->Virtual.pageTables[i] != gcvNULL)
@@ -465,7 +450,6 @@ gckVIDMEM_Construct(
memory->bytes = Bytes;
memory->freeBytes = Bytes;
memory->threshold = Threshold;
- memory->mutex = gcvNULL;
#if gcdUSE_VIDMEM_PER_PID
gcmkONERROR(gckOS_GetProcessID(&memory->pid));
#endif
@@ -602,9 +586,6 @@ gckVIDMEM_Construct(
"[GALCORE] TILE_STATUS: bank %d",
memory->mapping[gcvSURF_TILE_STATUS]);
- /* Allocate the mutex. */
- gcmkONERROR(gckOS_CreateMutex(Os, &memory->mutex));
-
/* Return pointer to the gckVIDMEM object. */
*Memory = memory;
@@ -616,12 +597,6 @@ OnError:
/* Roll back. */
if (memory != gcvNULL)
{
- if (memory->mutex != gcvNULL)
- {
- /* Delete the mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(Os, memory->mutex));
- }
-
for (i = 0; i < banks; ++i)
{
/* Free the heap. */
@@ -688,9 +663,6 @@ gckVIDMEM_Destroy(
}
}
- /* Free the mutex. */
- gcmkVERIFY_OK(gckOS_DeleteMutex(Memory->os, Memory->mutex));
-
/* Mark the object as unknown. */
Memory->object.type = gcvOBJ_UNKNOWN;
@@ -742,6 +714,7 @@ gckVIDMEM_Destroy(
*/
gceSTATUS
gckVIDMEM_Allocate(
+ IN gckKERNEL Kernel,
IN gckVIDMEM Memory,
IN gctUINT Width,
IN gctUINT Height,
@@ -773,7 +746,7 @@ gckVIDMEM_Allocate(
/* Allocate through linear function. */
gcmkONERROR(
- gckVIDMEM_AllocateLinear(Memory, bytes, Alignment, Type, Node));
+ gckVIDMEM_AllocateLinear(Kernel, Memory, bytes, Alignment, Type, Node));
/* Success. */
gcmkFOOTER_ARG("*Node=0x%x", *Node);
@@ -989,6 +962,7 @@ OnError:
*/
gceSTATUS
gckVIDMEM_AllocateLinear(
+ IN gckKERNEL Kernel,
IN gckVIDMEM Memory,
IN gctSIZE_T Bytes,
IN gctUINT32 Alignment,
@@ -1016,7 +990,7 @@ gckVIDMEM_AllocateLinear(
gcmkVERIFY_ARGUMENT(Type < gcvSURF_NUM_TYPES);
/* Acquire the mutex. */
- gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
+ gcmkONERROR(gckOS_AcquireMutex(Memory->os, Kernel->vidmemMutex, gcvINFINITE));
acquired = gcvTRUE;
#if !gcdUSE_VIDMEM_PER_PID
@@ -1203,7 +1177,7 @@ gckVIDMEM_AllocateLinear(
#endif
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Kernel->vidmemMutex));
/* Return the pointer to the node. */
*Node = node;
@@ -1220,7 +1194,7 @@ OnError:
if (acquired)
{
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Kernel->vidmemMutex));
}
/* Return the status. */
@@ -1245,6 +1219,7 @@ OnError:
*/
gceSTATUS
gckVIDMEM_Free(
+ IN gckKERNEL Kernel,
IN gcuVIDMEM_NODE_PTR Node
)
{
@@ -1252,13 +1227,17 @@ gckVIDMEM_Free(
gckKERNEL kernel = gcvNULL;
gckVIDMEM memory = gcvNULL;
gcuVIDMEM_NODE_PTR node;
- gctBOOL mutexAcquired = gcvFALSE;
gckOS os = gcvNULL;
gctBOOL acquired = gcvFALSE;
gctINT32 i, totalLocked;
gcmkHEADER_ARG("Node=0x%x", Node);
+ /* Acquire the mutex. */
+ gcmkONERROR(
+ gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Verify the arguments. */
if ((Node == gcvNULL)
|| (Node->VidMem.memory == gcvNULL)
@@ -1277,6 +1256,9 @@ gckVIDMEM_Free(
/* Client still has a lock, defer free op 'till when lock reaches 0. */
Node->VidMem.freePending = gcvTRUE;
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ acquired = gcvFALSE;
+
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Node 0x%x is locked (%d)... deferring free.",
Node, Node->VidMem.locked);
@@ -1288,12 +1270,6 @@ gckVIDMEM_Free(
/* Extract pointer to gckVIDMEM object owning the node. */
memory = Node->VidMem.memory;
- /* Acquire the mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
-
- mutexAcquired = gcvTRUE;
-
#ifdef __QNXNTO__
#if !gcdUSE_VIDMEM_PER_PID
/* Reset. */
@@ -1370,7 +1346,7 @@ gckVIDMEM_Free(
}
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Node 0x%x is freed.",
@@ -1393,12 +1369,6 @@ gckVIDMEM_Free(
os = kernel->os;
gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
- /* Grab the mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
-
- acquired = gcvTRUE;
-
for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
{
totalLocked += Node->Virtual.lockeds[i];
@@ -1412,8 +1382,6 @@ gckVIDMEM_Free(
/* Set Flag */
Node->Virtual.freed = gcvTRUE;
-
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
}
else
{
@@ -1422,28 +1390,20 @@ gckVIDMEM_Free(
Node->Virtual.physical,
Node->Virtual.bytes));
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
-
/* Destroy the gcuVIDMEM_NODE union. */
gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
}
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
- if (mutexAcquired)
- {
- /* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(
- memory->os, memory->mutex
- ));
- }
-
if (acquired)
{
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
}
/* Return the status. */
@@ -1684,6 +1644,10 @@ gckVIDMEM_Lock(
/* Verify the arguments. */
gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
if ((Node == gcvNULL)
|| (Node->VidMem.memory == gcvNULL)
)
@@ -1745,10 +1709,6 @@ gckVIDMEM_Lock(
os = Node->Virtual.kernel->os;
gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
- /* Grab the mutex. */
- gcmkONERROR(gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
- acquired = gcvTRUE;
-
#if gcdPAGED_MEMORY_CACHEABLE
/* Force video memory cacheable. */
Cacheable = gcvTRUE;
@@ -1868,11 +1828,11 @@ gckVIDMEM_Lock(
/* Return hardware address. */
*Address = Node->Virtual.addresses[Kernel->core];
-
- /* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
}
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+
/* Success. */
gcmkFOOTER_ARG("*Address=%08x", *Address);
return gcvSTATUS_OK;
@@ -1918,7 +1878,7 @@ OnError:
if (acquired)
{
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
}
/* Return the status. */
@@ -1976,6 +1936,11 @@ gckVIDMEM_Unlock(
gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d",
Node, Type, gcmOPT_VALUE(Asynchroneous));
+ /* Grab the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vidmemMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+
/* Verify the arguments. */
if ((Node == gcvNULL)
|| (Node->VidMem.memory == gcvNULL)
@@ -2032,7 +1997,11 @@ gckVIDMEM_Unlock(
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
"Deferred-freeing Node 0x%x.",
Node);
- gcmkONERROR(gckVIDMEM_Free(Node));
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
+ acquired = gcvFALSE;
+
+ gcmkONERROR(gckVIDMEM_Free(Kernel, Node));
}
}
@@ -2052,12 +2021,6 @@ gckVIDMEM_Unlock(
os = Kernel->os;
gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
- /* Grab the mutex. */
- gcmkONERROR(
- gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
-
- acquired = gcvTRUE;
-
if (Asynchroneous == gcvNULL)
{
if (Node->Virtual.lockeds[Kernel->core] == 0)
@@ -2119,14 +2082,14 @@ gckVIDMEM_Unlock(
Node->Virtual.physical,
Node->Virtual.bytes));
+ /* Destroy the gcuVIDMEM_NODE union. */
+ gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
+
/* Release mutex before node is destroyed */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
acquired = gcvFALSE;
- /* Destroy the gcuVIDMEM_NODE union. */
- gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
-
/* Node has been destroyed, so we should not touch it any more */
gcmkFOOTER();
return gcvSTATUS_OK;
@@ -2234,10 +2197,12 @@ gckVIDMEM_Unlock(
/* Schedule the surface to be unlocked. */
*Asynchroneous = gcvTRUE;
}
+ }
+ if (acquired)
+ {
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
-
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
acquired = gcvFALSE;
}
@@ -2255,7 +2220,7 @@ OnError:
if (acquired)
{
/* Release the mutex. */
- gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex));
}
/* Return the status. */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
index 63d5dad3a75a..6445a41e7810 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
@@ -1497,6 +1497,13 @@ gckOS_StopTimer(
IN gctPOINTER Timer
);
+/* Get the global video memory mutex. */
+gceSTATUS
+gckOS_GetVideoMemoryMutex(
+ IN gckOS Os,
+ OUT gctPOINTER *Mutex
+ );
+
/******************************************************************************\
********************************* gckHEAP Object ********************************
\******************************************************************************/
@@ -1574,6 +1581,7 @@ gckVIDMEM_Destroy(
/* Allocate rectangular memory. */
gceSTATUS
gckVIDMEM_Allocate(
+ IN gckKERNEL Kernel,
IN gckVIDMEM Memory,
IN gctUINT Width,
IN gctUINT Height,
@@ -1587,6 +1595,7 @@ gckVIDMEM_Allocate(
/* Allocate linear memory. */
gceSTATUS
gckVIDMEM_AllocateLinear(
+ IN gckKERNEL Kernel,
IN gckVIDMEM Memory,
IN gctSIZE_T Bytes,
IN gctUINT32 Alignment,
@@ -1597,6 +1606,7 @@ gckVIDMEM_AllocateLinear(
/* Free memory. */
gceSTATUS
gckVIDMEM_Free(
+ IN gckKERNEL Kernel,
IN gcuVIDMEM_NODE_PTR Node
);
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
index f8413700031a..2c744012e02a 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
@@ -455,6 +455,7 @@ typedef struct _gcsKERNEL_FUNCTION * gcKERNEL_FUNCTION;
typedef struct _gcsHINT * gcsHINT_PTR;
typedef struct _gcSHADER_PROFILER * gcSHADER_PROFILER;
typedef struct _gcVARIABLE * gcVARIABLE;
+typedef struct _gcSHADER_LIST * gcSHADER_LIST;
struct _gcsHINT
{
@@ -523,6 +524,11 @@ struct _gcsHINT
#if TEMP_SHADER_PATCH
gctUINT32 pachedShaderIdentifier;
#endif
+
+#if gcdUSE_WCLIP_PATCH
+ /* Strict WClip match. */
+ gctBOOL strictWClipMatch;
+#endif
};
#if TEMP_SHADER_PATCH
@@ -3230,6 +3236,12 @@ gcATTRIBUTE_IsEnabled(
OUT gctBOOL * Enabled
);
+gceSTATUS
+gcATTRIBUTE_GetIndex(
+ IN gcATTRIBUTE Attribute,
+ OUT gctUINT16 * Index
+ );
+
/*******************************************************************************
** gcUNIFORM_GetType
********************************************************************************
@@ -3392,6 +3404,12 @@ gcUNIFORM_GetSampler(
OUT gctUINT32 * Sampler
);
+gceSTATUS
+gcUNIFORM_GetIndex(
+ IN gcUNIFORM Uniform,
+ OUT gctUINT16 * Index
+ );
+
/*******************************************************************************
** gcUNIFORM_GetFormat
**
@@ -4290,6 +4308,46 @@ gcSHADER_PatchZBiasForMachineCodeVS(
IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
);
+gceSTATUS
+gcSHADER_InsertList(
+ IN gcSHADER Shader,
+ IN gcSHADER_LIST * Root,
+ IN gctINT Index,
+ IN gctINT Data0,
+ IN gctINT Data1
+ );
+
+gceSTATUS
+gcSHADER_UpdateList(
+ IN gcSHADER Shader,
+ IN gcSHADER_LIST Root,
+ IN gctINT Index,
+ IN gctINT NewIndex
+ );
+
+gceSTATUS
+gcSHADER_DeleteList(
+ IN gcSHADER Shader,
+ IN gcSHADER_LIST * Root,
+ IN gctINT Index
+ );
+
+gceSTATUS
+gcSHADER_FindList(
+ IN gcSHADER Shader,
+ IN gcSHADER_LIST Root,
+ IN gctINT Index,
+ IN gcSHADER_LIST * List
+ );
+
+gceSTATUS
+gcSHADER_InsertWClipList(
+ IN gcSHADER Shader,
+ IN gctINT Index,
+ IN gctINT Data0,
+ IN gctINT Data1
+ );
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
index 420437f514bc..4c1dc3ef8119 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
@@ -694,7 +694,7 @@
This define enables the recovery code.
*/
#ifndef gcdENABLE_RECOVERY
-# define gcdENABLE_RECOVERY 1
+# define gcdENABLE_RECOVERY 0
#endif
/*
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
index b44652944c92..d33e8c280aa0 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
@@ -18,7 +18,6 @@
*
*****************************************************************************/
-
#ifndef __gc_hal_types_h_
#define __gc_hal_types_h_
@@ -1015,6 +1014,7 @@ typedef enum _gcePATCH_ID
gcePATCH_RTESTVA,
gcePATCH_BMX,
gcePATCH_BMGUI,
+ gcePATCH_ANDROID_CTS_MEDIA_PRESENTATIONTIME,
/* Game list */
gcePATCH_NBA2013,
@@ -1048,7 +1048,16 @@ typedef enum _gcePATCH_ID
gcePATCH_DUOKANTV,
gcePATCH_TESTAPP,
gcePATCH_GOOGLEEARTH,
-
+ gcePATCH_SF4,
+ gcePATCH_SPEEDRACE,
+ gcePATCH_AIRNAVY,
+ gcePATCH_F18NEW,
+ gcePATCH_F18,
+ gcePATCH_WISTONESG,
+ gcvPATCH_VECUNIT_RED,
+ gcvPATCH_NAMESGAS,
+ gcvPATCH_AFTERBURNER,
+ gcvPATCH_UIMARK,
/* Count enum*/
gcePATCH_COUNT,
}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
index ebd316e24c5b..63ed28c9c326 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -1,7 +1,7 @@
/****************************************************************************
*
* Copyright (C) 2005 - 2013 by Vivante Corp.
-* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+* Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +37,9 @@
#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
# include <linux/resmem_account.h>
+#endif
+
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
# include <linux/kernel.h>
# include <linux/mm.h>
# include <linux/oom.h>
@@ -893,9 +896,11 @@ static int drv_init(struct device *pdev)
/* Reset the base address */
device->baseAddress = 0;
}
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
+ task_free_register(&task_nb);
+#endif
#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
- task_free_register(&task_nb);
viv_gpu_resmem_handler.data = device->kernels[gcvCORE_MAJOR];
register_reserved_memory_account(&viv_gpu_resmem_handler);
#endif
@@ -980,8 +985,11 @@ static void drv_exit(void)
{
gcmkHEADER();
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
+#ifdef CONFIG_GPU_LOW_MEMORY_KILLER
task_free_unregister(&task_nb);
+#endif
+
+#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
unregister_reserved_memory_account(&viv_gpu_resmem_handler);
#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index 45c42a4908ea..b15399271f8d 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -211,6 +211,11 @@ struct _gckOS
/* workqueue for os timer. */
struct workqueue_struct * workqueue;
+
+ int gpu_clk_on[3];
+ struct mutex gpu_clk_mutex;
+
+ gctPOINTER vidmemMutex;
};
typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
@@ -1111,6 +1116,10 @@ gckOS_Construct(
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
+ mutex_init(&os->gpu_clk_mutex);
+
+ gcmkONERROR(gckOS_CreateMutex(os, &os->vidmemMutex));
+
/* Return pointer to the gckOS object. */
*Os = os;
@@ -1234,6 +1243,9 @@ gckOS_Destroy(
/* Destroy debug lock mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->debugLock));
+ /* Destroy video memory mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->vidmemMutex));
+
/* Wait for all works done. */
flush_workqueue(Os->workqueue);
@@ -2425,7 +2437,17 @@ gckOS_ReadRegisterEx(
gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
gcmkVERIFY_ARGUMENT(Data != gcvNULL);
+ if(Address != 0x10) mutex_lock(&Os->gpu_clk_mutex);
+ BUG_ON(!Os->gpu_clk_on[Core]);
+
+ if(Address)
+ {
+ gctUINT32 AQHiClockControl = readl((gctUINT8 *)Os->device->registerBases[Core]);
+ BUG_ON((AQHiClockControl & 0x3) == 0x3);
+ }
+
*Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
+ if(Address != 0x10) mutex_unlock(&Os->gpu_clk_mutex);
/* Success. */
gcmkFOOTER_ARG("*Data=0x%08x", *Data);
@@ -2475,7 +2497,17 @@ gckOS_WriteRegisterEx(
gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
+ mutex_lock(&Os->gpu_clk_mutex);
+ BUG_ON(!Os->gpu_clk_on[Core]);
+
+ if(Address)
+ {
+ gctUINT32 AQHiClockControl = readl((gctUINT8 *)Os->device->registerBases[Core]);
+ BUG_ON((AQHiClockControl & 0x3) == 0x3);
+ }
+
writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
+ mutex_unlock(&Os->gpu_clk_mutex);
/* Success. */
gcmkFOOTER_NO();
@@ -7020,6 +7052,7 @@ gckOS_SetGPUPower(
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
if (Clock == gcvTRUE) {
if (oldClockState == gcvFALSE) {
+ mutex_lock(&Os->gpu_clk_mutex);
switch (Core) {
case gcvCORE_MAJOR:
clk_enable(clk_3dcore);
@@ -7037,9 +7070,12 @@ gckOS_SetGPUPower(
default:
break;
}
+ Os->gpu_clk_on[Core] = 1;
+ mutex_unlock(&Os->gpu_clk_mutex);
}
} else {
if (oldClockState == gcvTRUE) {
+ mutex_lock(&Os->gpu_clk_mutex);
switch (Core) {
case gcvCORE_MAJOR:
if (cpu_is_mx6q())
@@ -7057,11 +7093,14 @@ gckOS_SetGPUPower(
default:
break;
}
+ Os->gpu_clk_on[Core] = 0;
+ mutex_unlock(&Os->gpu_clk_mutex);
}
}
#else
if (Clock == gcvTRUE) {
if (oldClockState == gcvFALSE) {
+ mutex_lock(&Os->gpu_clk_mutex);
switch (Core) {
case gcvCORE_MAJOR:
clk_prepare(clk_3dcore);
@@ -7086,9 +7125,12 @@ gckOS_SetGPUPower(
default:
break;
}
+ Os->gpu_clk_on[Core] = 1;
+ mutex_unlock(&Os->gpu_clk_mutex);
}
} else {
if (oldClockState == gcvTRUE) {
+ mutex_lock(&Os->gpu_clk_mutex);
switch (Core) {
case gcvCORE_MAJOR:
clk_disable(clk_3dshader);
@@ -7113,6 +7155,8 @@ gckOS_SetGPUPower(
default:
break;
}
+ Os->gpu_clk_on[Core] = 0;
+ mutex_unlock(&Os->gpu_clk_mutex);
}
}
#endif
@@ -8696,6 +8740,20 @@ gckOS_GetProcessNameByPid(
return gcvSTATUS_OK;
}
+gceSTATUS
+gckOS_GetVideoMemoryMutex(
+ IN gckOS Os,
+ OUT gctPOINTER *Mutex
+ )
+{
+ gcmkHEADER_ARG("Mutex=x%X", Mutex);
+
+ *Mutex = Os->vidmemMutex;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
#if gcdANDROID_NATIVE_FENCE_SYNC
gceSTATUS
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 133940473de4..5b64f2c67c04 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -305,12 +305,12 @@ config REGULATOR_PCF50633
on PCF50633
config REGULATOR_PFUZE100
- tristate "Support regulators on Freescale PFUZE100 PMIC"
+ tristate "Freescale PFUZE100/PFUZE200 regulator driver"
depends on I2C
select REGMAP_I2C
help
- Say y here to support the regulators found on the Freescale PFUZE100
- PMIC.
+ Say y here to support the regulators found on the Freescale
+ PFUZE100/PFUZE200 PMIC.
config REGULATOR_RC5T583
tristate "RICOH RC5T583 Power regulators"
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 36a73a5ad15d..4ec8d77b9eb1 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -56,6 +56,8 @@
#define PFUZE100_VGEN5VOL 0x70
#define PFUZE100_VGEN6VOL 0x71
+enum chips { PFUZE100, PFUZE200 };
+
struct pfuze_regulator {
struct regulator_desc desc;
unsigned char stby_reg;
@@ -63,6 +65,7 @@ struct pfuze_regulator {
};
struct pfuze_chip {
+ int chip_id;
struct regmap *regmap;
struct device *dev;
struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR];
@@ -78,14 +81,16 @@ static const int pfuze100_vsnvs[] = {
};
static const struct i2c_device_id pfuze_device_id[] = {
- {.name = "pfuze100"},
- {},
+ {.name = "pfuze100", .driver_data = PFUZE100},
+ {.name = "pfuze200", .driver_data = PFUZE200},
+ { }
};
MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
static const struct of_device_id pfuze_dt_ids[] = {
- { .compatible = "fsl,pfuze100" },
- {},
+ { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100},
+ { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200},
+ { }
};
MODULE_DEVICE_TABLE(of, pfuze_dt_ids);
@@ -139,14 +144,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
};
-#define PFUZE100_FIXED_REG(_name, base, voltage) \
- [PFUZE100_ ## _name] = { \
+#define PFUZE100_FIXED_REG(_chip, _name, base, voltage) \
+ [_chip ## _ ## _name] = { \
.desc = { \
.name = #_name, \
.n_voltages = 1, \
.ops = &pfuze100_fixed_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
- .id = PFUZE100_ ## _name, \
+ .id = _chip ## _ ## _name, \
.owner = THIS_MODULE, \
.min_uV = (voltage), \
.enable_reg = (base), \
@@ -154,14 +159,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
}, \
}
-#define PFUZE100_SW_REG(_name, base, min, max, step) \
- [PFUZE100_ ## _name] = { \
+#define PFUZE100_SW_REG(_chip, _name, base, min, max, step) \
+ [_chip ## _ ## _name] = { \
.desc = { \
.name = #_name,\
.n_voltages = ((max) - (min)) / (step) + 1, \
.ops = &pfuze100_sw_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
- .id = PFUZE100_ ## _name, \
+ .id = _chip ## _ ## _name, \
.owner = THIS_MODULE, \
.min_uV = (min), \
.uV_step = (step), \
@@ -172,14 +177,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
.stby_mask = 0x3f, \
}
-#define PFUZE100_SWB_REG(_name, base, mask, voltages) \
- [PFUZE100_ ## _name] = { \
+#define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \
+ [_chip ## _ ## _name] = { \
.desc = { \
.name = #_name, \
.n_voltages = ARRAY_SIZE(voltages), \
.ops = &pfuze100_swb_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
- .id = PFUZE100_ ## _name, \
+ .id = _chip ## _ ## _name, \
.owner = THIS_MODULE, \
.volt_table = voltages, \
.vsel_reg = (base), \
@@ -187,14 +192,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
}, \
}
-#define PFUZE100_VGEN_REG(_name, base, min, max, step) \
- [PFUZE100_ ## _name] = { \
+#define PFUZE100_VGEN_REG(_chip, _name, base, min, max, step) \
+ [_chip ## _ ## _name] = { \
.desc = { \
.name = #_name, \
.n_voltages = ((max) - (min)) / (step) + 1, \
.ops = &pfuze100_ldo_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
- .id = PFUZE100_ ## _name, \
+ .id = _chip ## _ ## _name, \
.owner = THIS_MODULE, \
.min_uV = (min), \
.uV_step = (step), \
@@ -207,25 +212,45 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
.stby_mask = 0x20, \
}
+/* PFUZE100 */
static struct pfuze_regulator pfuze100_regulators[] = {
- PFUZE100_SW_REG(SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
- PFUZE100_SW_REG(SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000),
- PFUZE100_SW_REG(SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
- PFUZE100_SW_REG(SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
- PFUZE100_SW_REG(SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
- PFUZE100_SW_REG(SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000),
- PFUZE100_SWB_REG(SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
- PFUZE100_SWB_REG(VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
- PFUZE100_FIXED_REG(VREFDDR, PFUZE100_VREFDDRCON, 750000),
- PFUZE100_VGEN_REG(VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
- PFUZE100_VGEN_REG(VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
- PFUZE100_VGEN_REG(VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
- PFUZE100_VGEN_REG(VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
- PFUZE100_VGEN_REG(VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
- PFUZE100_VGEN_REG(VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
+ PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
+ PFUZE100_SW_REG(PFUZE100, SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000),
+ PFUZE100_SW_REG(PFUZE100, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
+ PFUZE100_SW_REG(PFUZE100, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
+ PFUZE100_SW_REG(PFUZE100, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
+ PFUZE100_SW_REG(PFUZE100, SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000),
+ PFUZE100_SWB_REG(PFUZE100, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
+ PFUZE100_SWB_REG(PFUZE100, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
+ PFUZE100_FIXED_REG(PFUZE100, VREFDDR, PFUZE100_VREFDDRCON, 750000),
+ PFUZE100_VGEN_REG(PFUZE100, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
+ PFUZE100_VGEN_REG(PFUZE100, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
+ PFUZE100_VGEN_REG(PFUZE100, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
+ PFUZE100_VGEN_REG(PFUZE100, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
+ PFUZE100_VGEN_REG(PFUZE100, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
+ PFUZE100_VGEN_REG(PFUZE100, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
+};
+
+static struct pfuze_regulator pfuze200_regulators[] = {
+ PFUZE100_SW_REG(PFUZE200, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
+ PFUZE100_SW_REG(PFUZE200, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
+ PFUZE100_SW_REG(PFUZE200, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
+ PFUZE100_SW_REG(PFUZE200, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
+ PFUZE100_SWB_REG(PFUZE200, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
+ PFUZE100_SWB_REG(PFUZE200, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
+ PFUZE100_FIXED_REG(PFUZE200, VREFDDR, PFUZE100_VREFDDRCON, 750000),
+ PFUZE100_VGEN_REG(PFUZE200, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
+ PFUZE100_VGEN_REG(PFUZE200, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
+ PFUZE100_VGEN_REG(PFUZE200, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
+ PFUZE100_VGEN_REG(PFUZE200, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
+ PFUZE100_VGEN_REG(PFUZE200, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
+ PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
};
+static struct pfuze_regulator *pfuze_regulators;
+
#ifdef CONFIG_OF
+/* PFUZE100 */
static struct of_regulator_match pfuze100_matches[] = {
{ .name = "sw1ab", },
{ .name = "sw1c", },
@@ -244,24 +269,56 @@ static struct of_regulator_match pfuze100_matches[] = {
{ .name = "vgen6", },
};
+/* PFUZE200 */
+static struct of_regulator_match pfuze200_matches[] = {
+
+ { .name = "sw1ab", },
+ { .name = "sw2", },
+ { .name = "sw3a", },
+ { .name = "sw3b", },
+ { .name = "swbst", },
+ { .name = "vsnvs", },
+ { .name = "vrefddr", },
+ { .name = "vgen1", },
+ { .name = "vgen2", },
+ { .name = "vgen3", },
+ { .name = "vgen4", },
+ { .name = "vgen5", },
+ { .name = "vgen6", },
+};
+
+static struct of_regulator_match *pfuze_matches;
+
static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
{
struct device *dev = chip->dev;
struct device_node *np, *parent;
int ret;
- np = of_node_get(dev->parent->of_node);
+ np = of_node_get(dev->of_node);
if (!np)
return 0;
- parent = of_find_node_by_name(np, "regulators");
+ parent = of_get_child_by_name(np, "regulators");
if (!parent) {
dev_err(dev, "regulators node not found\n");
return -EINVAL;
}
- ret = of_regulator_match(dev, parent, pfuze100_matches,
- ARRAY_SIZE(pfuze100_matches));
+ switch (chip->chip_id) {
+ case PFUZE200:
+ pfuze_matches = pfuze200_matches;
+ ret = of_regulator_match(dev, parent, pfuze200_matches,
+ ARRAY_SIZE(pfuze200_matches));
+ break;
+
+ case PFUZE100:
+ default:
+ pfuze_matches = pfuze100_matches;
+ ret = of_regulator_match(dev, parent, pfuze100_matches,
+ ARRAY_SIZE(pfuze100_matches));
+ break;
+ }
of_node_put(parent);
if (ret < 0) {
@@ -275,12 +332,12 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
static inline struct regulator_init_data *match_init_data(int index)
{
- return pfuze100_matches[index].init_data;
+ return pfuze_matches[index].init_data;
}
static inline struct device_node *match_of_node(int index)
{
- return pfuze100_matches[index].of_node;
+ return pfuze_matches[index].of_node;
}
#else
static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
@@ -308,7 +365,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
if (ret)
return ret;
- if (value & 0x0f) {
+ if ((value & 0x0f) != pfuze_chip->chip_id) {
+ /* device id NOT match with your setting */
dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
return -ENODEV;
}
@@ -344,17 +402,31 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
dev_get_platdata(&client->dev);
struct regulator_config config = { .ena_gpio = -ENODEV };
int i, ret;
+ const struct of_device_id *match;
+ u32 regulator_num;
+ u32 sw_check_start, sw_check_end;
pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip),
GFP_KERNEL);
if (!pfuze_chip)
return -ENOMEM;
- i2c_set_clientdata(client, pfuze_chip);
-
- memcpy(pfuze_chip->regulator_descs, pfuze100_regulators,
- sizeof(pfuze_chip->regulator_descs));
+ if (client->dev.of_node) {
+ match = of_match_device(of_match_ptr(pfuze_dt_ids),
+ &client->dev);
+ if (!match) {
+ dev_err(&client->dev, "Error: No device match found\n");
+ return -ENODEV;
+ }
+ pfuze_chip->chip_id = (int)(long)match->data;
+ } else if (id) {
+ pfuze_chip->chip_id = id->driver_data;
+ } else {
+ dev_err(&client->dev, "No dts match or id table match found\n");
+ return -ENODEV;
+ }
+ i2c_set_clientdata(client, pfuze_chip);
pfuze_chip->dev = &client->dev;
pfuze_chip->regmap = devm_regmap_init_i2c(client, &pfuze_regmap_config);
@@ -371,11 +443,34 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
return ret;
}
+ /* use the right regulators after identify the right device */
+ switch (pfuze_chip->chip_id) {
+ case PFUZE200:
+ pfuze_regulators = pfuze200_regulators;
+ regulator_num = ARRAY_SIZE(pfuze200_regulators);
+ sw_check_start = PFUZE200_SW2;
+ sw_check_end = PFUZE200_SW3B;
+ break;
+
+ case PFUZE100:
+ default:
+ pfuze_regulators = pfuze100_regulators;
+ regulator_num = ARRAY_SIZE(pfuze100_regulators);
+ sw_check_start = PFUZE100_SW2;
+ sw_check_end = PFUZE100_SW4;
+ break;
+ }
+ dev_info(&client->dev, "pfuze%s found.\n",
+ (pfuze_chip->chip_id == PFUZE100) ? "100" : "200");
+
+ memcpy(pfuze_chip->regulator_descs, pfuze_regulators,
+ sizeof(pfuze_chip->regulator_descs));
+
ret = pfuze_parse_regulators_dt(pfuze_chip);
if (ret)
return ret;
- for (i = 0; i < PFUZE100_MAX_REGULATOR; i++) {
+ for (i = 0; i < regulator_num; i++) {
struct regulator_init_data *init_data;
struct regulator_desc *desc;
int val;
@@ -388,7 +483,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
init_data = match_init_data(i);
/* SW2~SW4 high bit check and modify the voltage value table */
- if (i > PFUZE100_SW1C && i < PFUZE100_SWBST) {
+ if (i >= sw_check_start && i <= sw_check_end) {
regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
if (val & 0x40) {
desc->min_uV = 800000;
@@ -440,6 +535,6 @@ static struct i2c_driver pfuze_driver = {
module_i2c_driver(pfuze_driver);
MODULE_AUTHOR("Robin Gong <b38343@freescale.com>");
-MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100 PMIC");
+MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/PFUZE200 PMIC");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("i2c:pfuze100-regulator");
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index 0040e2dd2be6..a30dab1bf11f 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -1360,6 +1360,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
return -EFAULT;
ipu_set_csc_coefficients(mxc_fbi->ipu, mxc_fbi->ipu_ch,
csc.param);
+ break;
}
default:
retval = -EINVAL;