aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/process.c2
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c2
-rw-r--r--arch/arm/mach-omap2/include/mach/omap_fiq_debugger.h1
-rw-r--r--arch/arm/mach-omap2/pm.h2
-rw-r--r--arch/arm/mach-omap2/pm34xx.c8
-rw-r--r--arch/arm/mach-omap2/pm44xx.c76
-rw-r--r--arch/arm/mach-omap2/smartreflex-class1p5.c2
-rw-r--r--drivers/gpio/gpio-omap.c14
-rw-r--r--drivers/gpu/pvr/Makefile2
-rw-r--r--drivers/gpu/pvr/bridged_pvr_bridge.c3
-rw-r--r--drivers/gpu/pvr/buffer_manager.c31
-rw-r--r--drivers/gpu/pvr/deviceclass.c60
-rw-r--r--drivers/gpu/pvr/devicemem.c29
-rw-r--r--drivers/gpu/pvr/mmap.c23
-rw-r--r--drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c4
-rw-r--r--drivers/gpu/pvr/osfunc.h1
-rw-r--r--drivers/gpu/pvr/pvr_bridge_k.c33
-rw-r--r--drivers/gpu/pvr/pvr_uaccess.h2
-rw-r--r--drivers/gpu/pvr/pvrversion.h6
-rw-r--r--drivers/gpu/pvr/queue.c16
-rw-r--r--drivers/gpu/pvr/refcount.c481
-rw-r--r--drivers/gpu/pvr/refcount.h152
-rw-r--r--drivers/gpu/pvr/services_headers.h1
-rw-r--r--drivers/gpu/pvr/sgx/mmu.c23
-rw-r--r--drivers/gpu/pvr/sgx/sgxkick.c31
-rw-r--r--drivers/gpu/pvr/sgx/sgxreset.c1
-rw-r--r--drivers/gpu/pvr/sgx/sgxtransfer.c32
-rw-r--r--drivers/gpu/pvr/sgx/sgxutils.c4
-rw-r--r--drivers/gpu/pvr/sgxfeaturedefs.h7
-rw-r--r--drivers/mmc/host/omap_hsmmc.c9
-rw-r--r--drivers/remoteproc/remoteproc.c2
-rw-r--r--drivers/rpmsg/rpmsg_resmgr.c4
-rw-r--r--drivers/video/omap2/dsscomp/device.c4
-rw-r--r--include/video/dsscomp.h40
-rw-r--r--sound/soc/omap/omap-mcpdm.c2
-rw-r--r--sound/soc/omap/omap-pcm.c5
-rw-r--r--sound/soc/soc-dsp.c79
37 files changed, 1042 insertions, 152 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 54c97ee..7d66a6e 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -223,8 +223,8 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
while (1) {
- tick_nohz_stop_sched_tick(1);
idle_notifier_call_chain(IDLE_START);
+ tick_nohz_stop_sched_tick(1);
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 1b83cea..da13f2d 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -120,7 +120,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
}
/* Execute ARM wfi */
- omap_sram_idle();
+ omap_sram_idle(false);
/* Re-allow idle for C1 */
if (state == &dev->states[0]) {
diff --git a/arch/arm/mach-omap2/include/mach/omap_fiq_debugger.h b/arch/arm/mach-omap2/include/mach/omap_fiq_debugger.h
index c49608e..4378a77 100644
--- a/arch/arm/mach-omap2/include/mach/omap_fiq_debugger.h
+++ b/arch/arm/mach-omap2/include/mach/omap_fiq_debugger.h
@@ -24,6 +24,7 @@ u32 omap_debug_uart_resume_idle(void);
static inline int __init omap_serial_debug_init(int id, bool is_fiq, bool is_high_prio_irq,
struct omap_device_pad *pads, int num_pads)
{
+ return 0;
}
static inline u32 omap_debug_uart_resume_idle(void)
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 3862ccd..c9da6b9 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -17,7 +17,7 @@
extern void *omap3_secure_ram_storage;
extern void omap3_pm_off_mode_enable(int);
-extern void omap_sram_idle(void);
+extern void omap_sram_idle(bool suspend);
extern int omap3_can_sleep(void);
extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
extern int omap3_idle_init(void);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 535480f..cb1e8d8 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -328,7 +328,7 @@ static void restore_table_entry(void)
set_cr(control_reg_value);
}
-void omap_sram_idle(void)
+void omap_sram_idle(bool suspend)
{
/* Variable to tell what needs to be saved and restored
* in omap_sram_idle*/
@@ -386,7 +386,7 @@ void omap_sram_idle(void)
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
- omap2_gpio_prepare_for_idle(per_going_off);
+ omap2_gpio_prepare_for_idle(per_going_off, suspend);
}
/* CORE */
@@ -485,7 +485,7 @@ static void omap3_pm_idle(void)
trace_power_start(POWER_CSTATE, 1, smp_processor_id());
trace_cpu_idle(1, smp_processor_id());
- omap_sram_idle();
+ omap_sram_idle(false);
trace_power_end(smp_processor_id());
trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
@@ -518,7 +518,7 @@ static int omap3_pm_suspend(void)
omap3_intc_suspend();
- omap_sram_idle();
+ omap_sram_idle(true);
restore:
/* Restore next_pwrsts */
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 78bbf4a..329f37a 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -76,6 +76,8 @@ static struct voltagedomain *mpu_voltdm, *iva_voltdm, *core_voltdm;
static struct clockdomain *tesla_clkdm;
static struct powerdomain *tesla_pwrdm;
+static struct clockdomain *emif_clkdm, *mpuss_clkdm;
+
/* Yet un-named erratum which requires AUTORET to be disabled for IVA PD */
#define OMAP4_PM_ERRATUM_IVA_AUTO_RET_iXXX BIT(1)
/*
@@ -85,6 +87,22 @@ static struct powerdomain *tesla_pwrdm;
*/
#define OMAP4_PM_ERRATUM_HSI_SWAKEUP_iXXX BIT(2)
+/* Dynamic dependendency Cannot be enabled due to i688 erratum ID for 443x */
+#define OMAP4_PM_ERRATUM_MPU_EMIF_NO_DYNDEP_i688 BIT(3)
+/*
+ * Dynamic dependendency Cannot be enabled due to i688 erratum ID for above 443x
+ * NOTE: this is NOT YET a confirmed erratum for 446x, but provided here in
+ * anticipation.
+ * If a fix is found at a later date, the code using this can be removed.
+ * WA involves:
+ * Enable MPU->EMIF SD before WFI and disable while coming out of WFI.
+ * This works around system hang/lockups seen when only MPU->EMIF
+ * dynamic dependency set. Allows dynamic dependency to be used
+ * in all active usecases and get all the power savings accordingly.
+ * TODO: Once this is available as final Errata, update with proper
+ * fix.
+ */
+#define OMAP4_PM_ERRATUM_MPU_EMIF_NO_DYNDEP_IDLE_iXXX BIT(4)
u8 pm44xx_errata;
#define is_pm44xx_erratum(erratum) (pm44xx_errata & OMAP4_PM_ERRATUM_##erratum)
@@ -129,6 +147,7 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
int core_next_state = PWRDM_POWER_ON;
int mpu_next_state = PWRDM_POWER_ON;
int ret;
+ int staticdep_wa_applied = 0;
pwrdm_clear_all_prev_pwrst(cpu0_pwrdm);
pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
@@ -152,9 +171,30 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend)
if (ret)
goto abort_gpio;
+ if (is_pm44xx_erratum(MPU_EMIF_NO_DYNDEP_IDLE_iXXX) &&
+ mpu_next_state <= PWRDM_POWER_INACTIVE) {
+ /* Configures MEMIF clockdomain in SW_WKUP */
+ if (clkdm_wakeup(emif_clkdm)) {
+ pr_err("%s: Failed to force wakeup of %s\n",
+ __func__, emif_clkdm->name);
+ } else {
+ /* Enable MPU-EMIF Static Dependency around WFI */
+ if (clkdm_add_wkdep(mpuss_clkdm, emif_clkdm))
+ pr_err("%s: Failed to Add wkdep %s->%s\n",
+ __func__, mpuss_clkdm->name,
+ emif_clkdm->name);
+ else
+ staticdep_wa_applied = 1;
+
+ /* Configures MEMIF clockdomain back to HW_AUTO */
+ clkdm_allow_idle(emif_clkdm);
+ }
+ }
if (mpu_next_state < PWRDM_POWER_INACTIVE) {
if (omap_sr_disable_reset_volt(mpu_voltdm))
goto abort_device_off;
+
+ omap_sr_disable_reset_volt(mpu_voltdm);
omap_vc_set_auto_trans(mpu_voltdm,
OMAP_VC_CHANNEL_AUTO_TRANSITION_RETENTION);
}
@@ -252,6 +292,24 @@ abort_device_off:
omap_voltage_get_curr_vdata(mpu_voltdm));
}
+ /*
+ * NOTE: is_pm44xx_erratum is not strictly required, but retained for
+ * code context redability.
+ */
+ if (is_pm44xx_erratum(MPU_EMIF_NO_DYNDEP_IDLE_iXXX) &&
+ staticdep_wa_applied) {
+ /* Configures MEMIF clockdomain in SW_WKUP */
+ if (clkdm_wakeup(emif_clkdm))
+ pr_err("%s: Failed to force wakeup of %s\n",
+ __func__, emif_clkdm->name);
+ /* Disable MPU-EMIF Static Dependency on WFI exit */
+ else if (clkdm_del_wkdep(mpuss_clkdm, emif_clkdm))
+ pr_err("%s: Failed to remove wkdep %s->%s\n",
+ __func__, mpuss_clkdm->name,
+ emif_clkdm->name);
+ /* Configures MEMIF clockdomain back to HW_AUTO */
+ clkdm_allow_idle(emif_clkdm);
+ }
abort_gpio:
return;
@@ -1137,6 +1195,11 @@ static void __init omap4_pm_setup_errata(void)
if (cpu_is_omap44xx())
pm44xx_errata |= OMAP4_PM_ERRATUM_IVA_AUTO_RET_iXXX |
OMAP4_PM_ERRATUM_HSI_SWAKEUP_iXXX;
+ /* Dynamic Dependency errata for all silicon !=443x */
+ if (cpu_is_omap443x())
+ pm44xx_errata |= OMAP4_PM_ERRATUM_MPU_EMIF_NO_DYNDEP_i688;
+ else
+ pm44xx_errata |= OMAP4_PM_ERRATUM_MPU_EMIF_NO_DYNDEP_IDLE_iXXX;
}
/**
@@ -1148,7 +1211,7 @@ static void __init omap4_pm_setup_errata(void)
static int __init omap4_pm_init(void)
{
int ret = 0;
- struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
+ struct clockdomain *l3_1_clkdm;
struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per, *l4_cfg;
if (!cpu_is_omap44xx())
@@ -1207,8 +1270,11 @@ static int __init omap4_pm_init(void)
(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per) || (!l4_cfg))
goto err2;
- if (cpu_is_omap443x()) {
+ /* if we cannot ever enable static dependency. */
+ if (is_pm44xx_erratum(MPU_EMIF_NO_DYNDEP_i688))
ret |= clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
+
+ if (cpu_is_omap443x()) {
ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm);
ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);
@@ -1228,12 +1294,6 @@ static int __init omap4_pm_init(void)
pr_info("OMAP4 PM: Static dependency added between"
" DUCATI <-> L4_PER/CFG and DUCATI <-> L3.\n");
} else if (cpu_is_omap446x()) {
- /*
- * Static dependency between mpuss and emif can only be
- * disabled if OSWR is disabled to avoid a HW bug that occurs
- * when mpuss enters OSWR
- */
- /*ret |= clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);*/
ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per);
ret |= clkdm_add_wkdep(mpuss_clkdm, l4_cfg);
diff --git a/arch/arm/mach-omap2/smartreflex-class1p5.c b/arch/arm/mach-omap2/smartreflex-class1p5.c
index c8d14af..f870220 100644
--- a/arch/arm/mach-omap2/smartreflex-class1p5.c
+++ b/arch/arm/mach-omap2/smartreflex-class1p5.c
@@ -69,6 +69,8 @@ struct sr_class1p5_work_data {
static struct delayed_work recal_work;
#endif
+static unsigned long class1p5_margin;
+
/**
* sr_class1p5_notify() - isr notifier for status events
* @voltdm: voltage domain for which we were triggered
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index b281955..abb2e7e 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1496,10 +1496,10 @@ static int omap2_gpio_set_edge_wakeup(struct gpio_bank *bank, bool suspend)
* even if they are set for level detection only.
*/
__raw_writel(bank->context.edge_falling |
- (bank->context.ew_leveldetect0 & wkup_status),
+ (bank->type_leveldetect0 & wkup_status),
(bank->base + bank->regs->fallingdetect));
__raw_writel(bank->context.edge_rising |
- (bank->context.ew_leveldetect1 & wkup_status),
+ (bank->type_leveldetect1 & wkup_status),
(bank->base + bank->regs->risingdetect));
__raw_writel(0, bank->base + bank->regs->leveldetect0);
__raw_writel(0, bank->base + bank->regs->leveldetect1);
@@ -1566,12 +1566,15 @@ int omap2_gpio_prepare_for_idle(int off_mode, bool suspend)
struct gpio_bank *bank;
list_for_each_entry(bank, &omap_gpio_list, node) {
+ if (!bank->mod_usage)
+ continue;
+
omap2_gpio_set_wakeupenables(bank);
if (omap2_gpio_set_edge_wakeup(bank, suspend))
ret = -EBUSY;
- if (bank->mod_usage && bank->loses_context && off_mode)
+ if (bank->loses_context)
if (pm_runtime_put_sync_suspend(bank->dev) < 0)
dev_err(bank->dev, "%s: GPIO bank %d "
"pm_runtime_put_sync failed\n",
@@ -1589,7 +1592,10 @@ void omap2_gpio_resume_after_idle(int off_mode)
struct gpio_bank *bank;
list_for_each_entry(bank, &omap_gpio_list, node) {
- if (bank->mod_usage && bank->loses_context && off_mode)
+ if (!bank->mod_usage)
+ continue;
+
+ if (bank->loses_context)
if (pm_runtime_get_sync(bank->dev) < 0)
dev_err(bank->dev, "%s: GPIO bank %d "
"pm_runtime_get_sync failed\n",
diff --git a/drivers/gpu/pvr/Makefile b/drivers/gpu/pvr/Makefile
index 1eb3417..a9c7e44 100644
--- a/drivers/gpu/pvr/Makefile
+++ b/drivers/gpu/pvr/Makefile
@@ -23,6 +23,7 @@ ccflags-y += \
-DSUPPORT_LARGE_GENERAL_HEAP \
-DPVR_NO_OMAP_TIMER \
-DSYS_SUPPORTS_SGX_IDLE_CALLBACK \
+ -DPVRSRV_REFCOUNT_DEBUG \
-Idrivers/gpu/pvr/sgx
ccflags-$(CONFIG_PVR_SGXCORE_540) += \
@@ -89,6 +90,7 @@ pvrsrvkm-y := \
bridged_pvr_bridge.o \
perproc.o \
lists.o \
+ refcount.o \
omap4/sysconfig.o \
omap4/sysutils.o \
sgx/bridged_sgx_bridge.o \
diff --git a/drivers/gpu/pvr/bridged_pvr_bridge.c b/drivers/gpu/pvr/bridged_pvr_bridge.c
index 44f8e05..7a84ee8 100644
--- a/drivers/gpu/pvr/bridged_pvr_bridge.c
+++ b/drivers/gpu/pvr/bridged_pvr_bridge.c
@@ -46,6 +46,7 @@
#include "perproc.h"
#include "device.h"
#include "buffer_manager.h"
+#include "refcount.h"
#include "pdump_km.h"
#include "syscommon.h"
@@ -899,7 +900,7 @@ PVRSRVMapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
if(psSrcKernelMemInfo->psKernelSyncInfo)
{
- psSrcKernelMemInfo->psKernelSyncInfo->ui32RefCount++;
+ PVRSRVKernelSyncInfoIncRef(psSrcKernelMemInfo->psKernelSyncInfo, psSrcKernelMemInfo);
}
psDstKernelMemInfo->psKernelSyncInfo = psSrcKernelMemInfo->psKernelSyncInfo;
diff --git a/drivers/gpu/pvr/buffer_manager.c b/drivers/gpu/pvr/buffer_manager.c
index 8907e22..27ed8a1 100644
--- a/drivers/gpu/pvr/buffer_manager.c
+++ b/drivers/gpu/pvr/buffer_manager.c
@@ -1408,7 +1408,7 @@ BM_Wrap ( IMG_HANDLE hDevMemHeap,
"BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
ui32Size, ui32Offset, sHashAddress.uiAddr));
- pBuf->ui32RefCount++;
+ PVRSRVBMBufIncRef(pBuf);
*phBuf = (BM_HANDLE)pBuf;
if(pui32Flags)
*pui32Flags = uFlags;
@@ -1477,7 +1477,7 @@ BM_Export (BM_HANDLE hBuf)
{
BM_BUF *pBuf = (BM_BUF *)hBuf;
- pBuf->ui32ExportCount++;
+ PVRSRVBMBufIncExport(pBuf);
}
IMG_VOID
@@ -1486,7 +1486,7 @@ BM_FreeExport(BM_HANDLE hBuf,
{
BM_BUF *pBuf = (BM_BUF *)hBuf;
- pBuf->ui32ExportCount--;
+ PVRSRVBMBufDecExport(pBuf);
FreeBuf (pBuf, ui32Flags, IMG_FALSE);
}
@@ -1509,8 +1509,7 @@ BM_Free (BM_HANDLE hBuf,
SysAcquireData(&psSysData);
- pBuf->ui32RefCount--;
-
+ PVRSRVBMBufDecRef(pBuf);
if(pBuf->ui32RefCount == 0)
{
if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
@@ -1757,7 +1756,12 @@ DevMemoryFree (BM_MAPPING *pMapping)
#define XPROC_WORKAROUND_BAD_SHAREINDEX 0773407734
+#define XPROC_WORKAROUND_UNKNOWN 0
+#define XPROC_WORKAROUND_ALLOC 1
+#define XPROC_WORKAROUND_MAP 2
+
static IMG_UINT32 gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
+static IMG_UINT32 gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
static struct {
@@ -1783,6 +1787,7 @@ PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index)
}
gXProcWorkaroundShareIndex = ui32Index;
+ gXProcWorkaroundState = XPROC_WORKAROUND_MAP;
return PVRSRV_OK;
}
@@ -1804,6 +1809,7 @@ PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index)
}
gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
+ gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
return PVRSRV_OK;
}
@@ -1823,6 +1829,7 @@ PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32In
if (gXProcWorkaroundShareData[*pui32Index].ui32RefCount == 0)
{
gXProcWorkaroundShareIndex = *pui32Index;
+ gXProcWorkaroundState = XPROC_WORKAROUND_ALLOC;
return PVRSRV_OK;
}
}
@@ -1881,12 +1888,20 @@ XProcWorkaroundAllocShareable(RA_ARENA *psArena,
*ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
*phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount ++;
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount++;
return PVRSRV_OK;
}
else
{
+ if (gXProcWorkaroundState != XPROC_WORKAROUND_ALLOC)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "XPROC workaround in bad state! About to allocate memory from non-alloc state! (%d)",
+ gXProcWorkaroundState));
+ }
+ PVR_ASSERT(gXProcWorkaroundState == XPROC_WORKAROUND_ALLOC);
+
if (psArena != IMG_NULL)
{
IMG_CPU_PHYADDR sCpuPAddr;
@@ -1954,7 +1969,7 @@ XProcWorkaroundAllocShareable(RA_ARENA *psArena,
*ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
*phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount ++;
+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount++;
return PVRSRV_OK;
}
@@ -2006,7 +2021,7 @@ static IMG_VOID XProcWorkaroundFreeShareable(IMG_HANDLE hOSMemHandle)
return;
}
- gXProcWorkaroundShareData[ui32SI].ui32RefCount --;
+ gXProcWorkaroundShareData[ui32SI].ui32RefCount--;
PVR_DPF((PVR_DBG_VERBOSE, "Reduced refcount of SI[%d] from %d to %d",
ui32SI, gXProcWorkaroundShareData[ui32SI].ui32RefCount+1, gXProcWorkaroundShareData[ui32SI].ui32RefCount));
diff --git a/drivers/gpu/pvr/deviceclass.c b/drivers/gpu/pvr/deviceclass.c
index 2ebd810..2834287 100644
--- a/drivers/gpu/pvr/deviceclass.c
+++ b/drivers/gpu/pvr/deviceclass.c
@@ -580,7 +580,8 @@ static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam,
psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice);
- if (--psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
{
PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
}
@@ -674,11 +675,24 @@ PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
return eError;
}
- psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
+ psDCPerContextInfo->psDCInfo = psDCInfo;
+ eError = PVRSRVGetDCSystemBufferKM(psDCPerContextInfo, IMG_NULL);
+ if(eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to get system buffer"));
+ psDCInfo->ui32RefCount--;
+ PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
+ return eError;
+ }
+
+ PVRSRVKernelSyncInfoIncRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount = 0;
}
+ else
+ {
+ psDCPerContextInfo->psDCInfo = psDCInfo;
+ }
- psDCPerContextInfo->psDCInfo = psDCInfo;
psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
RESMAN_TYPE_DISPLAYCLASS_DEVICE,
psDCPerContextInfo,
@@ -742,7 +756,7 @@ PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM,
PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
IMG_HANDLE hExtBuffer;
- if(!hDeviceKM || !phBuffer)
+ if(!hDeviceKM)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters"));
return PVRSRV_ERROR_INVALID_PARAMS;
@@ -767,7 +781,10 @@ PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM,
psDCInfo->sSystemBuffer.psDCInfo = psDCInfo;
- *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer);
+ if (phBuffer)
+ {
+ *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer);
+ }
return PVRSRV_OK;
}
@@ -872,7 +889,8 @@ static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain)
{
if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
{
- if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
{
PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
}
@@ -1079,7 +1097,7 @@ PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
goto ErrorExit;
}
- psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
+ PVRSRVKernelSyncInfoIncRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr;
@@ -1179,7 +1197,8 @@ ErrorExit:
{
if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
{
- if (--psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
{
PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
}
@@ -1482,6 +1501,22 @@ PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
psFlipCmd->ui32SwapInterval = ui32SwapInterval;
+ SysAcquireData(&psSysData);
+
+
+ {
+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH)
+ {
+ OSFlushCPUCacheKM();
+ }
+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN)
+ {
+ OSCleanCPUCacheKM();
+ }
+
+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE;
+ }
+
eError = PVRSRVSubmitCommandKM (psQueue, psCommand);
if (eError != PVRSRV_OK)
@@ -1492,7 +1527,6 @@ PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM,
- SysAcquireData(&psSysData);
eError = OSScheduleMISR(psSysData);
if (eError != PVRSRV_OK)
@@ -2102,7 +2136,8 @@ static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam,
{
if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
{
- if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
{
PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
}
@@ -2228,7 +2263,7 @@ PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc,
goto ErrorExit;
}
- psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount++;
+ PVRSRVKernelSyncInfoIncRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
@@ -2270,7 +2305,8 @@ ErrorExit:
{
if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
{
- if (--psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
+ PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL);
+ if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->ui32RefCount == 0)
{
PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
}
diff --git a/drivers/gpu/pvr/devicemem.c b/drivers/gpu/pvr/devicemem.c
index 03b28eb..cd22faa 100644
--- a/drivers/gpu/pvr/devicemem.c
+++ b/drivers/gpu/pvr/devicemem.c
@@ -597,6 +597,10 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernel
}
eError = FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
+
+
+ psKernelSyncInfo->psSyncDataMemInfoKM = IMG_NULL;
+ psKernelSyncInfo->psSyncData = IMG_NULL;
(IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
@@ -737,7 +741,7 @@ PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
PVR_UNREFERENCED_PARAMETER(ui32Param);
- psMemInfo->ui32RefCount--;
+ PVRSRVKernelMemInfoDecRef(psMemInfo);
if (psMemInfo->ui32RefCount == 0)
@@ -789,8 +793,7 @@ PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
case PVRSRV_MEMTYPE_DEVICE:
if (psMemInfo->psKernelSyncInfo)
{
- psMemInfo->psKernelSyncInfo->ui32RefCount--;
-
+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo);
if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
{
eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
@@ -918,7 +921,8 @@ PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
{
goto free_mainalloc;
}
- psMemInfo->psKernelSyncInfo->ui32RefCount++;
+
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
}
@@ -945,7 +949,7 @@ PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
}
- psMemInfo->ui32RefCount++;
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE;
@@ -958,7 +962,6 @@ free_mainalloc:
return eError;
}
-
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie,
PVRSRV_KERNEL_MEM_INFO *psMemInfo)
@@ -1201,10 +1204,10 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie,
goto ErrorExitPhase4;
}
- psMemInfo->psKernelSyncInfo->ui32RefCount++;
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
- psMemInfo->ui32RefCount++;
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED;
@@ -1286,7 +1289,7 @@ static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam,
if( psMapData->psMemInfo->psKernelSyncInfo )
{
- psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount--;
+ PVRSRVKernelSyncInfoDecRef(psMapData->psMemInfo->psKernelSyncInfo, psMapData->psMemInfo);
if (psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
{
eError = PVRSRVFreeSyncInfoKM(psMapData->psMemInfo->psKernelSyncInfo);
@@ -1446,7 +1449,7 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPer
if(psMemInfo->psKernelSyncInfo)
{
- psMemInfo->psKernelSyncInfo->ui32RefCount++;
+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo);
}
@@ -1454,10 +1457,10 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPer
psMemInfo->pvSysBackupBuffer = IMG_NULL;
- psMemInfo->ui32RefCount++;
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
- psSrcMemInfo->ui32RefCount++;
+ PVRSRVKernelMemInfoIncRef(psSrcMemInfo);
BM_Export(psSrcMemInfo->sMemBlk.hBuffer);
@@ -1754,7 +1757,7 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *
&UnmapDeviceClassMemoryCallBack);
(psDeviceClassBuffer->ui32MemMapRefCount)++;
- psMemInfo->ui32RefCount++;
+ PVRSRVKernelMemInfoIncRef(psMemInfo);
psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS;
diff --git a/drivers/gpu/pvr/mmap.c b/drivers/gpu/pvr/mmap.c
index d2a09a7..a63223c 100644
--- a/drivers/gpu/pvr/mmap.c
+++ b/drivers/gpu/pvr/mmap.c
@@ -54,15 +54,12 @@
#include <drm/drmP.h>
#endif
-#include "img_defs.h"
-#include "services.h"
-#include "servicesint.h"
+#include "services_headers.h"
+
#include "pvrmmap.h"
#include "mutils.h"
#include "mmap.h"
#include "mm.h"
-#include "pvr_debug.h"
-#include "osfunc.h"
#include "proc.h"
#include "mutex.h"
#include "handle.h"
@@ -327,7 +324,7 @@ PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
*pui32MMapOffset = psOffsetStruct->ui32MMapOffset;
*pui32UserVAddr = psOffsetStruct->ui32UserVAddr;
- psOffsetStruct->ui32RefCount++;
+ PVRSRVOffsetStructIncRef(psOffsetStruct);
eError = PVRSRV_OK;
goto exit_unlock;
@@ -364,7 +361,7 @@ PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
psOffsetStruct->bOnMMapList = IMG_TRUE;
- psOffsetStruct->ui32RefCount++;
+ PVRSRVOffsetStructIncRef(psOffsetStruct);
eError = PVRSRV_OK;
@@ -427,7 +424,7 @@ PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc,
goto exit_unlock;
}
- psOffsetStruct->ui32RefCount--;
+ PVRSRVOffsetStructDecRef(psOffsetStruct);
*pbMUnmap = (IMG_BOOL)((psOffsetStruct->ui32RefCount == 0) && (psOffsetStruct->ui32UserVAddr != 0));
@@ -600,10 +597,12 @@ static IMG_VOID
MMapVOpenNoLock(struct vm_area_struct* ps_vma)
{
PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data;
- PVR_ASSERT(psOffsetStruct != IMG_NULL)
- psOffsetStruct->ui32Mapped++;
+
+ PVR_ASSERT(psOffsetStruct != IMG_NULL);
PVR_ASSERT(!psOffsetStruct->bOnMMapList);
+ PVRSRVOffsetStructIncMapped(psOffsetStruct);
+
if (psOffsetStruct->ui32Mapped > 1)
{
PVR_DPF((PVR_DBG_WARNING, "%s: Offset structure 0x%p is being shared across processes (psOffsetStruct->ui32Mapped: %u)", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32Mapped));
@@ -651,7 +650,7 @@ MMapVCloseNoLock(struct vm_area_struct* ps_vma)
#endif
PVR_ASSERT(!psOffsetStruct->bOnMMapList);
- psOffsetStruct->ui32Mapped--;
+ PVRSRVOffsetStructDecMapped(psOffsetStruct);
if (psOffsetStruct->ui32Mapped == 0)
{
if (psOffsetStruct->ui32RefCount != 0)
@@ -1065,6 +1064,8 @@ PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea)
if (psOffsetStruct->ui32Mapped != 0)
{
PVR_DPF((PVR_DBG_ERROR, "%s: psOffsetStruct 0x%p for memory area 0x0x%p is still mapped; psOffsetStruct->ui32Mapped %u", __FUNCTION__, psOffsetStruct, psLinuxMemArea, psOffsetStruct->ui32Mapped));
+ dump_stack();
+ PVRSRVDumpRefCountCCB();
eError = PVRSRV_ERROR_STILL_MAPPED;
goto exit_unlock;
}
diff --git a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
index 5e0eca4..c888c31 100644
--- a/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
+++ b/drivers/gpu/pvr/omaplfb/omaplfb_displayclass.c
@@ -829,9 +829,6 @@ static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie,
{
psBuffer->hCmdComplete = (OMAPLFB_HANDLE)hCmdCookie;
psBuffer->ulSwapInterval = ulSwapInterval;
-#if defined(NO_HARDWARE)
- psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_FALSE);
-#else
if (is_tiler_addr(psBuffer->sSysAddr.uiAddr)) {
IMG_UINT32 w = psBuffer->psDevInfo->sDisplayDim.ui32Width;
IMG_UINT32 h = psBuffer->psDevInfo->sDisplayDim.ui32Height;
@@ -861,7 +858,6 @@ static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie,
} else {
OMAPLFBQueueBufferForSwap(psSwapChain, psBuffer);
}
-#endif
}
OMAPLFBCreateSwapChainUnLock(psDevInfo);
diff --git a/drivers/gpu/pvr/osfunc.h b/drivers/gpu/pvr/osfunc.h
index 3d76ba8..6e5cbd1 100644
--- a/drivers/gpu/pvr/osfunc.h
+++ b/drivers/gpu/pvr/osfunc.h
@@ -410,6 +410,7 @@ IMG_BOOL OSMemHandleIsPhysContig(IMG_VOID *hOSMemHandle);
#endif
static INLINE IMG_BOOL OSMemHandleIsPhysContig(IMG_HANDLE hOSMemHandle)
{
+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle);
return IMG_FALSE;
}
#endif
diff --git a/drivers/gpu/pvr/pvr_bridge_k.c b/drivers/gpu/pvr/pvr_bridge_k.c
index 91a75a9..6d51200 100644
--- a/drivers/gpu/pvr/pvr_bridge_k.c
+++ b/drivers/gpu/pvr/pvr_bridge_k.c
@@ -35,6 +35,8 @@
#include "private_data.h"
#include "linkage.h"
#include "pvr_bridge_km.h"
+#include "pvr_uaccess.h"
+#include "refcount.h"
#if defined(SUPPORT_DRI_DRM)
#include <drm/drmP.h>
@@ -296,7 +298,11 @@ PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsig
goto unlock_and_return;
}
- psMapDevMemIN->hKernelMemInfo = psPrivateData->hKernelMemInfo;
+ if (pvr_put_user(psPrivateData->hKernelMemInfo, &psMapDevMemIN->hKernelMemInfo) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
break;
}
@@ -390,13 +396,18 @@ PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsig
}
- psKernelMemInfo->ui32RefCount++;
+ PVRSRVKernelMemInfoIncRef(psKernelMemInfo);
psPrivateData->hKernelMemInfo = psExportDeviceMemOUT->hMemInfo;
#if defined(SUPPORT_MEMINFO_IDS)
- psKernelMemInfo->ui64Stamp =
- psExportDeviceMemOUT->ui64Stamp =
- psPrivateData->ui64Stamp = ++ui64Stamp;
+ psPrivateData->ui64Stamp = ++ui64Stamp;
+
+ psKernelMemInfo->ui64Stamp = psPrivateData->ui64Stamp;
+ if (pvr_put_user(psPrivateData->ui64Stamp, &psExportDeviceMemOUT->ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
#endif
break;
}
@@ -408,7 +419,11 @@ PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsig
PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT =
(PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut;
PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
- psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp = psPrivateData->ui64Stamp;
+ if (pvr_put_user(psPrivateData->ui64Stamp, &psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
break;
}
@@ -416,7 +431,11 @@ PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsig
{
PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT =
(PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut;
- psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp = ++ui64Stamp;
+ if (pvr_put_user(++ui64Stamp, &psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp) != 0)
+ {
+ err = -EFAULT;
+ goto unlock_and_return;
+ }
break;
}
#endif
diff --git a/drivers/gpu/pvr/pvr_uaccess.h b/drivers/gpu/pvr/pvr_uaccess.h
index bacafe9..4b7114e 100644
--- a/drivers/gpu/pvr/pvr_uaccess.h
+++ b/drivers/gpu/pvr/pvr_uaccess.h
@@ -64,5 +64,7 @@ static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pv
#endif
}
+#define pvr_put_user put_user
+
#endif
diff --git a/drivers/gpu/pvr/pvrversion.h b/drivers/gpu/pvr/pvrversion.h
index 5a762c1..1065b1c 100644
--- a/drivers/gpu/pvr/pvrversion.h
+++ b/drivers/gpu/pvr/pvrversion.h
@@ -36,7 +36,7 @@
#define PVRVERSION_FAMILY "sgxddk"
#define PVRVERSION_BRANCHNAME "1.8"
-#define PVRVERSION_BUILD 778707
+#define PVRVERSION_BUILD 785978
#define PVRVERSION_BSCONTROL "CustomerGoogle_Android_ogles1_ogles2_GPL"
#define PVRVERSION_STRING "CustomerGoogle_Android_ogles1_ogles2_GPL sgxddk 18 1.8@" PVR_STR2(PVRVERSION_BUILD)
@@ -44,8 +44,8 @@
#define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
-#define PVRVERSION_BUILD_HI 77
-#define PVRVERSION_BUILD_LO 8707
+#define PVRVERSION_BUILD_HI 78
+#define PVRVERSION_BUILD_LO 5978
#define PVRVERSION_STRING_NUMERIC PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO)
#endif /* _PVRVERSION_H_ */
diff --git a/drivers/gpu/pvr/queue.c b/drivers/gpu/pvr/queue.c
index 92a4713..4682094 100644
--- a/drivers/gpu/pvr/queue.c
+++ b/drivers/gpu/pvr/queue.c
@@ -25,7 +25,6 @@
******************************************************************************/
#include "services_headers.h"
-#include "pvr_bridge_km.h"
#include "lists.h"
#include "ttrace.h"
@@ -626,8 +625,6 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
psCommand->psDstSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
- apsDstSync[i]->ui32RefCount++;
-
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
@@ -645,8 +642,6 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
psCommand->psSrcSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
- apsSrcSync[i]->ui32RefCount++;
-
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x",
i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr,
psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
@@ -1008,11 +1003,6 @@ IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie,
{
psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
- if (--psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->ui32RefCount == 0)
- {
- PVRSRVFreeSyncInfoKM(psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM);
- }
-
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST,
psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM,
PVRSRV_SYNCOP_COMPLETE);
@@ -1029,11 +1019,6 @@ IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie,
{
psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete++;
- if (--psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->ui32RefCount == 0)
- {
- PVRSRVFreeSyncInfoKM(psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM);
- }
-
PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC,
psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM,
PVRSRV_SYNCOP_COMPLETE);
@@ -1200,7 +1185,6 @@ PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
if (psCmdCompleteData != IMG_NULL)
{
- PVR_ASSERT(psCmdCompleteData->bInUse == IMG_FALSE);
OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize,
psCmdCompleteData, IMG_NULL);
psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL;
diff --git a/drivers/gpu/pvr/refcount.c b/drivers/gpu/pvr/refcount.c
new file mode 100644
index 0000000..8b00972
--- /dev/null
+++ b/drivers/gpu/pvr/refcount.c
@@ -0,0 +1,481 @@
+/*************************************************************************/ /*!
+@Title Services reference count debugging
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Strictly Confidential.
+*/ /**************************************************************************/
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+
+#include "services_headers.h"
+
+#ifndef __linux__
+#warning Reference count debugging is not thread-safe on this platform
+#define PVRSRV_LOCK_CCB()
+#define PVRSRV_UNLOCK_CCB()
+#else /* __linux__ */
+#include <linux/mutex.h>
+static DEFINE_MUTEX(gsCCBLock);
+#define PVRSRV_LOCK_CCB() mutex_lock(&gsCCBLock)
+#define PVRSRV_UNLOCK_CCB() mutex_unlock(&gsCCBLock)
+#endif /* __linux__ */
+
+#define PVRSRV_REFCOUNT_CCB_MAX 512
+#define PVRSRV_REFCOUNT_CCB_MESG_MAX 80
+
+#define PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO (1U << 0)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO (1U << 1)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF (1U << 2)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2 (1U << 3)
+
+#if defined(__linux__)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP (1U << 4)
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 (1U << 5)
+#else
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP 0
+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 0
+#endif
+
+#define PVRSRV_REFCOUNT_CCB_DEBUG_ALL ~0U
+
+/*static const IMG_UINT guiDebugMask = PVRSRV_REFCOUNT_CCB_DEBUG_ALL;*/
+static const IMG_UINT guiDebugMask =
+ PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO |
+ PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2;
+
+typedef struct
+{
+ const IMG_CHAR *pszFile;
+ IMG_INT iLine;
+ IMG_UINT32 ui32PID;
+ IMG_CHAR pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX];
+}
+PVRSRV_REFCOUNT_CCB;
+
+static PVRSRV_REFCOUNT_CCB gsRefCountCCB[PVRSRV_REFCOUNT_CCB_MAX];
+static IMG_UINT giOffset;
+
+static const IMG_CHAR gszHeader[] =
+ /* 10 20 30 40 50 60 70
+ * 345678901234567890123456789012345678901234567890123456789012345678901
+ */
+ "TYPE SYNCINFO MEMINFO MEMHANDLE OTHER REF REF' SIZE PID";
+ /* NCINFO deadbeef deadbeef deadbeef deadbeef 1234 1234 deadbeef */
+
+#define PVRSRV_REFCOUNT_CCB_FMT_STRING "%8.8s %8p %8p %8p %8p %.4d %.4d %.8x"
+
+IMG_INTERNAL
+void PVRSRVDumpRefCountCCB(void)
+{
+ int i;
+
+ PVRSRV_LOCK_CCB();
+
+ PVR_LOG(("%s", gszHeader));
+
+ for(i = 0; i < PVRSRV_REFCOUNT_CCB_MAX; i++)
+ {
+ PVRSRV_REFCOUNT_CCB *psRefCountCCBEntry =
+ &gsRefCountCCB[(giOffset + i) % PVRSRV_REFCOUNT_CCB_MAX];
+
+ /* Early on, we won't have MAX_REFCOUNT_CCB_SIZE messages */
+ if(!psRefCountCCBEntry->pszFile)
+ break;
+
+ PVR_LOG(("%s %d %s:%d", psRefCountCCBEntry->pcMesg,
+ psRefCountCCBEntry->ui32PID,
+ psRefCountCCBEntry->pszFile,
+ psRefCountCCBEntry->iLine));
+ }
+
+ PVRSRV_UNLOCK_CCB();
+}
+
+IMG_INTERNAL
+void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "SYNCINFO",
+ psKernelSyncInfo,
+ psKernelMemInfo,
+ NULL,
+ (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
+ psKernelSyncInfo->ui32RefCount,
+ psKernelSyncInfo->ui32RefCount + 1,
+ (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelSyncInfo->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "SYNCINFO",
+ psKernelSyncInfo,
+ psKernelMemInfo,
+ (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
+ NULL,
+ psKernelSyncInfo->ui32RefCount,
+ psKernelSyncInfo->ui32RefCount - 1,
+ (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelSyncInfo->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MEMINFO",
+ psKernelMemInfo->psKernelSyncInfo,
+ psKernelMemInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ NULL,
+ psKernelMemInfo->ui32RefCount,
+ psKernelMemInfo->ui32RefCount + 1,
+ psKernelMemInfo->uAllocSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelMemInfo->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MEMINFO",
+ psKernelMemInfo->psKernelSyncInfo,
+ psKernelMemInfo,
+ psKernelMemInfo->sMemBlk.hOSMemHandle,
+ NULL,
+ psKernelMemInfo->ui32RefCount,
+ psKernelMemInfo->ui32RefCount - 1,
+ psKernelMemInfo->uAllocSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psKernelMemInfo->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32RefCount,
+ pBuf->ui32RefCount + 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32RefCount,
+ pBuf->ui32RefCount - 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF2",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32ExportCount,
+ pBuf->ui32ExportCount + 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32ExportCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "BM_BUF2",
+ NULL,
+ NULL,
+ BM_HandleToOSMemHandle(pBuf),
+ pBuf,
+ pBuf->ui32ExportCount,
+ pBuf->ui32ExportCount - 1,
+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ pBuf->ui32ExportCount--;
+}
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+
+IMG_INTERNAL
+void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32RefCount,
+ psOffsetStruct->ui32RefCount + 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32RefCount++;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32RefCount,
+ psOffsetStruct->ui32RefCount - 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32RefCount--;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP2",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32Mapped,
+ psOffsetStruct->ui32Mapped + 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32Mapped++;
+}
+
+IMG_INTERNAL
+void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
+ goto skip;
+
+ PVRSRV_LOCK_CCB();
+
+ gsRefCountCCB[giOffset].pszFile = pszFile;
+ gsRefCountCCB[giOffset].iLine = iLine;
+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
+ snprintf(gsRefCountCCB[giOffset].pcMesg,
+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
+ PVRSRV_REFCOUNT_CCB_FMT_STRING,
+ "MMAP2",
+ NULL,
+ NULL,
+ psOffsetStruct->psLinuxMemArea,
+ psOffsetStruct,
+ psOffsetStruct->ui32Mapped,
+ psOffsetStruct->ui32Mapped - 1,
+ psOffsetStruct->ui32RealByteSize);
+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;
+
+ PVRSRV_UNLOCK_CCB();
+
+skip:
+ psOffsetStruct->ui32Mapped--;
+}
+
+#endif /* defined(__linux__) */
+
+#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */
diff --git a/drivers/gpu/pvr/refcount.h b/drivers/gpu/pvr/refcount.h
new file mode 100644
index 0000000..d2fd9c7
--- /dev/null
+++ b/drivers/gpu/pvr/refcount.h
@@ -0,0 +1,152 @@
+/*************************************************************************/ /*!
+@Title Services reference count debugging
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Strictly Confidential.
+*/ /**************************************************************************/
+
+#ifndef __REFCOUNT_H__
+#define __REFCOUNT_H__
+
+#if defined(PVRSRV_REFCOUNT_DEBUG)
+
+void PVRSRVDumpRefCountCCB(void);
+
+#define PVRSRVKernelSyncInfoIncRef(x...) \
+ PVRSRVKernelSyncInfoIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelSyncInfoDecRef(x...) \
+ PVRSRVKernelSyncInfoDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelMemInfoIncRef(x...) \
+ PVRSRVKernelMemInfoIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVKernelMemInfoDecRef(x...) \
+ PVRSRVKernelMemInfoDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufIncRef(x...) \
+ PVRSRVBMBufIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufDecRef(x...) \
+ PVRSRVBMBufDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufIncExport(x...) \
+ PVRSRVBMBufIncExport2(__FILE__, __LINE__, x)
+#define PVRSRVBMBufDecExport(x...) \
+ PVRSRVBMBufDecExport2(__FILE__, __LINE__, x)
+
+void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo);
+void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile,
+ IMG_INT iLine, BM_BUF *pBuf);
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+#include "mmap.h"
+
+#define PVRSRVOffsetStructIncRef(x...) \
+ PVRSRVOffsetStructIncRef2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructDecRef(x...) \
+ PVRSRVOffsetStructDecRef2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructIncMapped(x...) \
+ PVRSRVOffsetStructIncMapped2(__FILE__, __LINE__, x)
+#define PVRSRVOffsetStructDecMapped(x...) \
+ PVRSRVOffsetStructDecMapped2(__FILE__, __LINE__, x)
+
+void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
+ PKV_OFFSET_STRUCT psOffsetStruct);
+
+#endif /* defined(__linux__) */
+
+#else /* defined(PVRSRV_REFCOUNT_DEBUG) */
+
+static INLINE void PVRSRVDumpRefCountCCB(void) { }
+
+static INLINE void PVRSRVKernelSyncInfoIncRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo);
+ psKernelSyncInfo->ui32RefCount++;
+}
+
+static INLINE void PVRSRVKernelSyncInfoDecRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo);
+ psKernelSyncInfo->ui32RefCount--;
+}
+
+static INLINE void PVRSRVKernelMemInfoIncRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ psKernelMemInfo->ui32RefCount++;
+}
+
+static INLINE void PVRSRVKernelMemInfoDecRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
+{
+ psKernelMemInfo->ui32RefCount--;
+}
+
+#if defined(__linux__)
+
+/* mmap refcounting is Linux specific */
+#include "mmap.h"
+
+static INLINE void PVRSRVOffsetStructIncRef(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32RefCount++;
+}
+
+static INLINE void PVRSRVOffsetStructDecRef(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32RefCount--;
+}
+
+static INLINE void PVRSRVOffsetStructIncMapped(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32Mapped++;
+}
+
+static INLINE void PVRSRVOffsetStructDecMapped(PKV_OFFSET_STRUCT psOffsetStruct)
+{
+ psOffsetStruct->ui32Mapped--;
+}
+
+static INLINE void PVRSRVBMBufIncRef(BM_BUF *pBuf)
+{
+ pBuf->ui32RefCount++;
+}
+
+static INLINE void PVRSRVBMBufDecRef(BM_BUF *pBuf)
+{
+ pBuf->ui32RefCount--;
+}
+
+static INLINE void PVRSRVBMBufIncExport(BM_BUF *pBuf)
+{
+ pBuf->ui32ExportCount++;
+}
+
+static INLINE void PVRSRVBMBufDecExport(BM_BUF *pBuf)
+{
+ pBuf->ui32ExportCount--;
+}
+
+#endif /* defined(__linux__) */
+
+#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */
+
+#endif /* __REFCOUNT_H__ */
diff --git a/drivers/gpu/pvr/services_headers.h b/drivers/gpu/pvr/services_headers.h
index 2b5f197..09ed87e 100644
--- a/drivers/gpu/pvr/services_headers.h
+++ b/drivers/gpu/pvr/services_headers.h
@@ -44,6 +44,7 @@
#include "pvr_debug.h"
#include "metrics.h"
#include "osfunc.h"
+#include "refcount.h"
#endif
diff --git a/drivers/gpu/pvr/sgx/mmu.c b/drivers/gpu/pvr/sgx/mmu.c
index fbda31c..774026d 100644
--- a/drivers/gpu/pvr/sgx/mmu.c
+++ b/drivers/gpu/pvr/sgx/mmu.c
@@ -197,8 +197,10 @@ MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr);
#endif
+#define PT_DUMP 1
+
#define PT_DEBUG 0
-#if PT_DEBUG
+#if (PT_DEBUG || PT_DUMP) && defined(PVRSRV_NEED_PVR_DPF)
static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
{
IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
@@ -207,13 +209,20 @@ static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
for(i = 0; i < 1024; i += 8)
{
- PVR_DPF((PVR_DBG_WARNING,
+ PVR_DPF((PVR_DBG_ERROR,
"%08X %08X %08X %08X %08X %08X %08X %08X\n",
p[i + 0], p[i + 1], p[i + 2], p[i + 3],
p[i + 4], p[i + 5], p[i + 6], p[i + 7]));
}
}
+#else
+static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
+{
+ PVR_UNREFERENCED_PARAMETER(psPTInfoList);
+}
+#endif
+#if PT_DEBUG
static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
{
IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr;
@@ -226,18 +235,13 @@ static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
if(psPTInfoList->ui32ValidPTECount != ui32Count)
{
- PVR_DPF((PVR_DBG_WARNING, "ui32ValidPTECount: %u ui32Count: %u\n",
+ PVR_DPF((PVR_DBG_ERROR, "ui32ValidPTECount: %u ui32Count: %u\n",
psPTInfoList->ui32ValidPTECount, ui32Count));
DumpPT(psPTInfoList);
BUG();
}
}
#else
-static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
-{
- PVR_UNREFERENCED_PARAMETER(psPTInfoList);
-}
-
static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
{
PVR_UNREFERENCED_PARAMETER(psPTInfoList);
@@ -2754,6 +2758,9 @@ MMU_MapPage (MMU_HEAP *pMMUHeap,
ui32Index ));
PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08X", uTmp));
PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08X", DevPAddr.uiAddr));
+#if PT_DUMP
+ DumpPT(ppsPTInfoList[0]);
+#endif
}
#if !defined(FIX_HW_BRN_31620)
PVR_ASSERT((uTmp & SGX_MMU_PTE_VALID) == 0);
diff --git a/drivers/gpu/pvr/sgx/sgxkick.c b/drivers/gpu/pvr/sgx/sgxkick.c
index cbac38e..019a75cb 100644
--- a/drivers/gpu/pvr/sgx/sgxkick.c
+++ b/drivers/gpu/pvr/sgx/sgxkick.c
@@ -573,6 +573,37 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick)
0,
MAKEUNIQUETAG(psCCBMemInfo));
}
+
+ if (psCCBKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo;
+
+ PDUMPCOMMENT("Modify TA/TQ ROpPendingVal\r\n");
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui32TATQSyncReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+
+ if (psCCBKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo;
+
+ PDUMPCOMMENT("Modify 3D/TQ ROpPendingVal\r\n");
+
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
+ psCCBMemInfo,
+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui323DTQSyncReadOpsPendingVal),
+ sizeof(IMG_UINT32),
+ 0,
+ MAKEUNIQUETAG(psCCBMemInfo));
+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++;
+ }
+
#endif
for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++)
diff --git a/drivers/gpu/pvr/sgx/sgxreset.c b/drivers/gpu/pvr/sgx/sgxreset.c
index 0baa11f..7050371 100644
--- a/drivers/gpu/pvr/sgx/sgxreset.c
+++ b/drivers/gpu/pvr/sgx/sgxreset.c
@@ -541,6 +541,7 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo,
ui32RegVal = EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK |
EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK |
EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK |
+ EUR_CR_MASTER_SOFT_RESET_MCI_RESET_MASK |
EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK;
#if defined(SGX_FEATURE_PTLA)
diff --git a/drivers/gpu/pvr/sgx/sgxtransfer.c b/drivers/gpu/pvr/sgx/sgxtransfer.c
index 92ee0bc..d40773e 100644
--- a/drivers/gpu/pvr/sgx/sgxtransfer.c
+++ b/drivers/gpu/pvr/sgx/sgxtransfer.c
@@ -352,7 +352,37 @@ IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSF
}
}
}
- }
+
+ if (psKick->hTASyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->hTASyncInfo;
+
+ PDUMPCOMMENT("Tweak TA/TQ surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncWriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+
+ if (psKick->h3DSyncInfo != IMG_NULL)
+ {
+ psSyncInfo = psKick->h3DSyncInfo;
+
+ PDUMPCOMMENT("Tweak 3D/TQ surface write op in transfer cmd\r\n");
+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal,
+ psCCBMemInfo,
+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncWriteOpsPendingVal)),
+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal),
+ psKick->ui32PDumpFlags,
+ MAKEUNIQUETAG(psCCBMemInfo));
+
+ psSyncInfo->psSyncData->ui32LastOpDumpVal++;
+ }
+ }
#endif
sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr;
diff --git a/drivers/gpu/pvr/sgx/sgxutils.c b/drivers/gpu/pvr/sgx/sgxutils.c
index f362e06..c9a733b 100644
--- a/drivers/gpu/pvr/sgx/sgxutils.c
+++ b/drivers/gpu/pvr/sgx/sgxutils.c
@@ -365,7 +365,9 @@ PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
goto Exit;
}
- if ((eCmdType == SGXMKIF_CMD_TA) && bLastInScene)
+ if (eCmdType == SGXMKIF_CMD_2D ||
+ eCmdType == SGXMKIF_CMD_TRANSFER ||
+ ((eCmdType == SGXMKIF_CMD_TA) && bLastInScene))
{
SYS_DATA *psSysData;
diff --git a/drivers/gpu/pvr/sgxfeaturedefs.h b/drivers/gpu/pvr/sgxfeaturedefs.h
index bdf36fe..2553022 100644
--- a/drivers/gpu/pvr/sgxfeaturedefs.h
+++ b/drivers/gpu/pvr/sgxfeaturedefs.h
@@ -124,8 +124,6 @@
#define SGX_FEATURE_PDS_DATA_INTERLEAVE_2DWORDS
#define SGX_FEATURE_MONOLITHIC_UKERNEL
#define SGX_FEATURE_ZLS_EXTERNALZ
- #define SGX_FEATURE_VDM_CONTEXT_SWITCH_REV_2
- #define SGX_FEATURE_ISP_CONTEXT_SWITCH_REV_2
#define SGX_FEATURE_NUM_PDS_PIPES (2)
#define SGX_FEATURE_NATIVE_BACKWARD_BLIT
#define SGX_FEATURE_MAX_TA_RENDER_TARGETS (512)
@@ -177,11 +175,6 @@
#define SGX_FEATURE_VDM_CONTEXT_SWITCH
#endif
-#if defined(SGX_FEATURE_ISP_CONTEXT_SWITCH_REV_2) \
- || defined(SGX_FEATURE_ISP_CONTEXT_SWITCH_REV_3)
-#define SGX_FEATURE_ISP_CONTEXT_SWITCH
-#endif
-
#if defined(FIX_HW_BRN_22693)
#undef SGX_FEATURE_AUTOCLOCKGATING
#endif
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 903b2c7..a2b0862 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2570,8 +2570,8 @@ static int omap_hsmmc_suspend(struct device *dev)
if (mmc_slot(host).mmc_data.built_in)
host->mmc->pm_flags |= MMC_PM_KEEP_POWER;
ret = mmc_suspend_host(host->mmc);
- mmc_host_enable(host->mmc);
if (ret == 0) {
+ mmc_host_enable(host->mmc);
omap_hsmmc_disable_irq(host);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
@@ -2588,13 +2588,6 @@ static int omap_hsmmc_suspend(struct device *dev)
dev_dbg(mmc_dev(host->mmc),
"Unmask interrupt failed\n");
}
-
- /*
- * Directly call platform_bus suspend. runtime PM
- * PM lock is held during system suspend, so will
- * not be auto-matically called
- */
- mmc_host_disable(host->mmc);
}
}
diff --git a/drivers/remoteproc/remoteproc.c b/drivers/remoteproc/remoteproc.c
index 9f46e8b..5d2fa6c 100644
--- a/drivers/remoteproc/remoteproc.c
+++ b/drivers/remoteproc/remoteproc.c
@@ -1418,7 +1418,7 @@ void rproc_last_busy(struct rproc *rproc)
mutex_lock(&rproc->pm_lock);
if (pm_runtime_suspended(dev) ||
- !pm_runtime_autosuspend_expiration(dev)) {
+ !pm_runtime_autosuspend_expiration(dev)) {
pm_runtime_mark_last_busy(dev);
mutex_unlock(&rproc->pm_lock);
/*
diff --git a/drivers/rpmsg/rpmsg_resmgr.c b/drivers/rpmsg/rpmsg_resmgr.c
index b3ddc34..a13094d 100644
--- a/drivers/rpmsg/rpmsg_resmgr.c
+++ b/drivers/rpmsg/rpmsg_resmgr.c
@@ -443,6 +443,10 @@ static int rprm_i2c_request(struct rprm_elem *e, struct rprm_i2c *obj)
i2c_put_adapter(adapter);
ret = pm_runtime_get_sync(i2c_dev);
+ /*
+ * pm_runtime_get_sync can return 1 in case it is already active,
+ * change it to 0 to indicate success.
+ */
ret -= ret == 1;
if (!ret)
e->handle = i2c_dev;
diff --git a/drivers/video/omap2/dsscomp/device.c b/drivers/video/omap2/dsscomp/device.c
index 57e4257..c92ed3f 100644
--- a/drivers/video/omap2/dsscomp/device.c
+++ b/drivers/video/omap2/dsscomp/device.c
@@ -235,8 +235,8 @@ static long setup_mgr(struct dsscomp_dev *cdev,
/* convert addresses to user space */
if (oi->cfg.color_mode == OMAP_DSS_COLOR_NV12) {
- if (oi->uv_addr)
- oi->uv = hwc_virt_to_phys((u32) oi->uv_addr);
+ if (oi->uv_address)
+ oi->uv = hwc_virt_to_phys((u32) oi->uv_address);
else
oi->uv = hwc_virt_to_phys(addr +
oi->cfg.height * oi->cfg.stride);
diff --git a/include/video/dsscomp.h b/include/video/dsscomp.h
index 05ec06a..e7216e9 100644
--- a/include/video/dsscomp.h
+++ b/include/video/dsscomp.h
@@ -334,7 +334,7 @@ struct dss2_ovl_cfg {
struct omap_dss_cconv_coefs cconv;
struct dss2_vc1_range_map_info vc1;
- __u8 ix; /* ovl index same as sysfs/overlay# */
+ __u8 ix; /* ovl index same as sysfs/overlay# */
__u8 zorder; /* 0..3 */
__u8 enabled; /* bool */
__u8 zonly; /* only set zorder and enabled bit */
@@ -349,26 +349,36 @@ enum omapdss_buffer_type {
OMAP_DSS_BUFTYPE_TILER_PAGE,
};
+enum omapdss_buffer_addressing_type {
+ OMAP_DSS_BUFADDR_DIRECT, /* using direct addresses */
+ OMAP_DSS_BUFADDR_BYTYPE, /* using buffer types */
+ OMAP_DSS_BUFADDR_ION, /* using ion handle(s) */
+ OMAP_DSS_BUFADDR_GRALLOC, /* using gralloc handle */
+};
+
struct dss2_ovl_info {
struct dss2_ovl_cfg cfg;
+ enum omapdss_buffer_addressing_type addressing;
+
union {
/* user-space interfaces */
struct {
- void *address; /* main buffer address */
- void *uv_addr; /* uv buffer address */
-
- /*
- * For DSSCIOC_CHECK_OVL we allow specifying just the
- * type of each buffer. This is used if we need to
- * check whether DSS will be able to display a buffer
- * if using a particular memory type before spending
- * time to map/copy the buffer into that type of
- * memory. Default value of 0 uses the address to
- * determine the type.
- */
- __u16 ba_type;
- __u16 uv_type;
+ void *address; /* main buffer address */
+ void *uv_address; /* uv buffer */
+ };
+
+ /*
+ * For DSSCIOC_CHECK_OVL we allow specifying just the
+ * type of each buffer. This is used if we need to
+ * check whether DSS will be able to display a buffer
+ * if using a particular memory type before spending
+ * time to map/copy the buffer into that type of
+ * memory.
+ */
+ struct {
+ enum omapdss_buffer_type ba_type;
+ enum omapdss_buffer_type uv_type;
};
/* kernel-space interfaces */
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 45328d4..62f23b2 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -399,7 +399,9 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
val = __raw_readl(OMAP4430_CM1_ABE_PDM_CLKCTRL);
if ((val & CLKCTRL_MODULEMODE_MASK) != CLKCTRL_MODULEMODE_ENABLED) {
WARN(1, "Clock not enabled: PDM_CLKCTRL=0x%x\n", val);
+ mcpdm->active--;
pm_runtime_put_sync(mcpdm->dev);
+ err = -ENODEV;
goto out;
}
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 6a36196..a2a464f 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -391,7 +391,6 @@ static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm)
static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;
@@ -400,14 +399,14 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(64);
- if (dai->driver->playback.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = omap_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
- if (dai->driver->capture.channels_min) {
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = omap_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
diff --git a/sound/soc/soc-dsp.c b/sound/soc/soc-dsp.c
index 446266c..40e459a 100644
--- a/sound/soc/soc-dsp.c
+++ b/sound/soc/soc-dsp.c
@@ -101,6 +101,12 @@ static inline void be_reparent(struct snd_soc_pcm_runtime *fe,
list_for_each_entry(dsp_params, &be->dsp[stream].fe_clients, list_fe) {
if (dsp_params->fe != fe) {
+
+ dev_dbg(&fe->dev, " reparent %s path %s %s %s\n",
+ stream ? "capture" : "playback",
+ dsp_params->fe->dai_link->name,
+ stream ? "<-" : "->", dsp_params->be->dai_link->name);
+
fe_substream = snd_soc_dsp_get_substream(dsp_params->fe,
stream);
be_substream->runtime = fe_substream->runtime;
@@ -116,6 +122,10 @@ static inline void be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
list_for_each_entry_safe(dsp_params, d, &fe->dsp[stream].be_clients, list_be) {
struct snd_soc_pcm_runtime *be = dsp_params->be;
+ dev_dbg(&fe->dev, "BE %s disconnect check for %s\n",
+ stream ? "capture" : "playback",
+ be->dai_link->name);
+
if (dsp_params->state == SND_SOC_DSP_LINK_STATE_FREE) {
dev_dbg(&fe->dev, " freed DSP %s path %s %s %s\n",
stream ? "capture" : "playback",
@@ -396,9 +406,12 @@ static int soc_dsp_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
be_substream->runtime = be->dsp[stream].runtime;
err = soc_pcm_open(be_substream);
- if (err < 0)
+ if (err < 0) {
+ dev_err(&be->dev, "BE open failed %d\n", err);
+ be->dsp[stream].users--;
+ be->dsp[stream].state = SND_SOC_DSP_STATE_CLOSE;
goto unwind;
-
+ }
be->dsp[stream].state = SND_SOC_DSP_STATE_OPEN;
count++;
}
@@ -1013,22 +1026,28 @@ static int dsp_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
{
struct snd_soc_dsp_link *dsp_link = fe->dai_link->dsp_link;
struct snd_pcm_substream *substream = snd_soc_dsp_get_substream(fe, stream);
+ struct snd_soc_dsp_params *dsp_params;
int ret;
dev_dbg(&fe->dev, "runtime %s open on FE %s\n",
stream ? "capture" : "playback", fe->dai_link->name);
ret = soc_dsp_be_dai_startup(fe, stream);
- if (ret < 0)
+ if (ret < 0) {
+ goto disconnect;
return ret;
+ }
ret = soc_dsp_be_dai_hw_params(fe, stream);
- if (ret < 0)
+ if (ret < 0) {
+ goto close;
return ret;
-
+ }
ret = soc_dsp_be_dai_prepare(fe, stream);
- if (ret < 0)
+ if (ret < 0) {
+ goto hw_free;
return ret;
+ }
/* run the stream event for each BE */
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1047,8 +1066,8 @@ static int dsp_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START);
if (ret < 0) {
- dev_err(&fe->dev,"dsp: trigger FE failed %d\n", ret);
- return ret;
+ dev_err(&fe->dev,"dsp: bespoke trigger FE failed %d\n", ret);
+ goto stream_stop;
}
} else {
dev_dbg(&fe->dev, "dsp: trigger FE %s cmd start\n",
@@ -1056,11 +1075,36 @@ static int dsp_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
ret = soc_dsp_be_dai_trigger(fe, stream,
SNDRV_PCM_TRIGGER_START);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ dev_err(&fe->dev,"dsp: trigger FE failed %d\n", ret);
+ goto stream_stop;
+ }
}
return 0;
+
+stream_stop:
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ soc_dsp_dapm_stream_event(fe, stream,
+ fe->cpu_dai->driver->playback.stream_name,
+ SNDRV_PCM_TRIGGER_STOP);
+ else
+ soc_dsp_dapm_stream_event(fe, stream,
+ fe->cpu_dai->driver->capture.stream_name,
+ SNDRV_PCM_TRIGGER_STOP);
+hw_free:
+ soc_dsp_be_dai_hw_free(fe, stream);
+close:
+ soc_dsp_be_dai_shutdown(fe, stream);
+disconnect:
+ /* disconnect any non started BEs */
+ list_for_each_entry(dsp_params, &fe->dsp[stream].be_clients, list_be) {
+ struct snd_soc_pcm_runtime *be = dsp_params->be;
+ if (be->dsp[stream].state != SND_SOC_DSP_STATE_START)
+ dsp_params->state = SND_SOC_DSP_LINK_STATE_FREE;
+ }
+ be_disconnect(fe, stream);
+ return ret;
}
static int dsp_run_update(struct snd_soc_pcm_runtime *fe, int stream,
@@ -1506,7 +1550,9 @@ int soc_dsp_fe_resume(struct snd_soc_pcm_runtime *fe)
int soc_dsp_fe_dai_open(struct snd_pcm_substream *fe_substream)
{
struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
- int err;
+ struct snd_soc_dsp_params *dsp_params;
+ int err, ret;
+ int stream = fe_substream->stream;
fe->dsp[fe_substream->stream].runtime = fe_substream->runtime;
@@ -1517,7 +1563,16 @@ int soc_dsp_fe_dai_open(struct snd_pcm_substream *fe_substream)
fe->dai_link->name, fe_substream->stream ? "capture" : "playback");
}
- return soc_dsp_fe_dai_startup(fe_substream);
+ ret = soc_dsp_fe_dai_startup(fe_substream);
+ if (ret < 0) {
+ /* clean up all links */
+ list_for_each_entry(dsp_params, &fe->dsp[stream].be_clients, list_be)
+ dsp_params->state = SND_SOC_DSP_LINK_STATE_FREE;
+
+ be_disconnect(fe, stream);
+ fe->dsp[stream].runtime = NULL;
+ }
+ return ret;
}
/* called when closing FE stream */