[Openpvrsgx-devgroup] [PATCH 1/2] drm: pvrsgx: pvr-drv: Fix OCP handling with ioremap and reg access
Tony Lindgren
tony at atomide.com
Sat Oct 23 12:12:05 CEST 2021
The OCP registers need to be configured for SGX on some omap variants
to route the SGX interrupt. However, this must not be done on omap34xx
as the OCP registers are not readable and reads will hang the system.
We currently have pvr-drv hang on omap3430 devices like n900 because of
trying read the OCP registers.
We need to a combination of suitable ifdefs for each SoC for the OCP
regs, but that's not a nice solution. Let's just start getting rid of
the OCP related ifdefs and configure the OCP directly in the pvr-drv as
needed. We just need to reconfigure the OCP registers in the runtime PM
functions for now.
Note that this still leaves SysClearInterrupts() doing a write to ack the
OCP interrupt. However looks like the write won't do anything on omap34xx
so we can leave it for now and remove it later when adding support for
interrupt handling to pvr-drv.
Also sgx_jz4780 also configures OCP regs, but I suspect that code never
was enabled and was copied from earlier TI specific code. If sgx_jz4780
really uses the OCP regs, it needs at least the ocp_base configured.
Let's also add pvr_sgx_readl() and pvr_sgx_writel() while at it to make
it easy to rewrite further features and make it clear that the OCP
register area is SoC specific and separate from the SGX registers.
Reported-by: Ivaylo Dimitrov <ivo.g.dimitrov.75 at gmail.com>
Signed-off-by: Tony Lindgren <tony at atomide.com>
---
.../services4/system/omap/sysconfig.c | 66 ------------------
.../services4/system/omap/syslocal.h | 8 ---
.../services4/system/omap/sysutils_linux.c | 4 --
.../services4/system/sgx_jz4780/sysconfig.c | 42 ------------
.../services4/system/sgx_jz4780/syslocal.h | 8 ---
.../services4/system/sgx_jz4780/sysutils.c | 4 --
drivers/gpu/drm/pvrsgx/pvr-drv.c | 68 +++++++++++++++++--
drivers/gpu/drm/pvrsgx/pvr-drv.h | 29 ++++++++
8 files changed, 91 insertions(+), 138 deletions(-)
diff --git a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/sysconfig.c b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/sysconfig.c
--- a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/sysconfig.c
+++ b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/sysconfig.c
@@ -79,31 +79,14 @@ IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl,
IMG_UINT32 *pdwBytesTransferred);
#if defined(SGX_OCP_REGS_ENABLED)
-
static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr;
-
-static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
-{
- PVRSRV_ERROR eError = EnableSGXClocks(psSysData);
-
-#if !defined(SGX_OCP_NO_INT_BYPASS)
- if(eError == PVRSRV_OK)
- {
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK);
- }
#endif
- return eError;
-}
-
-#else /* defined(SGX_OCP_REGS_ENABLED) */
static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
{
return EnableSGXClocks(psSysData);
}
-#endif /* defined(SGX_OCP_REGS_ENABLED) */
-
static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData)
{
PVRSRV_ERROR eError = EnableSystemClocks(psSysData);
@@ -568,9 +551,6 @@ PVRSRV_ERROR SysFinalise(IMG_VOID)
return eError;
}
SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
-#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
- SysEnableSGXInterrupts(gpsSysData);
-#endif
#endif /* defined(SYS_USING_INTERRUPTS) */
#if defined(__linux__) || defined(__QNXNTO__)
/* Create a human readable version string for this system */
@@ -979,52 +959,6 @@ IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
#endif /* defined(NO_HARDWARE) */
}
-#if defined(SGX_OCP_NO_INT_BYPASS)
-/*!
-******************************************************************************
- @Function SysEnableSGXInterrupts
-
- @Description Enables SGX interrupts
-
- @Input psSysData
-
- @Return IMG_VOID
-
-******************************************************************************/
-IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData)
-{
- SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData;
- if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED))
- {
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1);
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1);
- SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED);
- }
-}
-
-/*!
-******************************************************************************
- @Function SysDisableSGXInterrupts
-
- @Description Disables SGX interrupts
-
- @Input psSysData
-
- @Return IMG_VOID
-
-******************************************************************************/
-IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData)
-{
- SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData;
-
- if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED))
- {
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1);
- SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED);
- }
-}
-#endif /* defined(SGX_OCP_NO_INT_BYPASS) */
-
/*!
******************************************************************************
diff --git a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/syslocal.h b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/syslocal.h
--- a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/syslocal.h
+++ b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/syslocal.h
@@ -199,14 +199,6 @@ typedef struct _SYS_SPECIFIC_DATA_TAG_
extern SYS_SPECIFIC_DATA *gpsSysSpecificData;
-#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS)
-IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData);
-IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData);
-#else
-#define SysEnableSGXInterrupts(psSysData)
-#define SysDisableSGXInterrupts(psSysData)
-#endif
-
#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
diff --git a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/sysutils_linux.c b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/sysutils_linux.c
--- a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/sysutils_linux.c
+++ b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/omap/sysutils_linux.c
@@ -223,8 +223,6 @@ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)
#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */
#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */
- SysEnableSGXInterrupts(psSysData);
-
/* Indicate that the SGX clocks are enabled */
atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);
@@ -258,8 +256,6 @@ IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)
PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));
- SysDisableSGXInterrupts(psSysData);
-
#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
pm_runtime_mark_last_busy(&gpsPVRLDMDev->dev);
pm_runtime_put_autosuspend(&gpsPVRLDMDev->dev);
diff --git a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/sysconfig.c b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/sysconfig.c
--- a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/sysconfig.c
+++ b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/sysconfig.c
@@ -88,32 +88,14 @@ IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl,
IMG_UINT32 *pdwBytesTransferred);
#if defined(SGX_OCP_REGS_ENABLED)
-
static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr;
-
-static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
-{
- PVRSRV_ERROR eError = EnableSGXClocks(psSysData);
-
-#if !defined(SGX_OCP_NO_INT_BYPASS)
- if(eError == PVRSRV_OK)
- {
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14);
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK);
- }
#endif
- return eError;
-}
-
-#else
static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
{
return EnableSGXClocks(psSysData);
}
-#endif
-
static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData)
{
PVRSRV_ERROR eError = EnableSystemClocks(psSysData);
@@ -753,30 +735,6 @@ IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
#endif
}
-#if defined(SGX_OCP_NO_INT_BYPASS)
-IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData)
-{
- SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData;
- if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED))
- {
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1);
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1);
- SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED);
- }
-}
-
-IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData)
-{
- SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData;
-
- if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED))
- {
- OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1);
- SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED);
- }
-}
-#endif
-
PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
{
PVRSRV_ERROR eError = PVRSRV_OK;
diff --git a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/syslocal.h b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/syslocal.h
--- a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/syslocal.h
+++ b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/syslocal.h
@@ -128,14 +128,6 @@ typedef struct _SYS_SPECIFIC_DATA_TAG_
extern SYS_SPECIFIC_DATA *gpsSysSpecificData;
-#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS)
-IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData);
-IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData);
-#else
-#define SysEnableSGXInterrupts(psSysData)
-#define SysDisableSGXInterrupts(psSysData)
-#endif
-
#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
diff --git a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/sysutils.c b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/sysutils.c
--- a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/sysutils.c
+++ b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/system/sgx_jz4780/sysutils.c
@@ -212,8 +212,6 @@ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)
}
#endif
- SysEnableSGXInterrupts(psSysData);
-
atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);
return PVRSRV_OK;
@@ -228,8 +226,6 @@ IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)
PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));
- SysDisableSGXInterrupts(psSysData);
-
#if defined(SYS_XB47_HAS_DVFS_FRAMEWORK)
{
struct gpu_platform_data *pdata;
diff --git a/drivers/gpu/drm/pvrsgx/pvr-drv.c b/drivers/gpu/drm/pvrsgx/pvr-drv.c
--- a/drivers/gpu/drm/pvrsgx/pvr-drv.c
+++ b/drivers/gpu/drm/pvrsgx/pvr-drv.c
@@ -39,10 +39,13 @@
struct pvr_capabilities {
u32 quirks;
unsigned long smp:1;
+ u16 ocp_offset;
};
struct pvr {
struct device *dev;
+ void __iomem *sgx_base;
+ void __iomem *ocp_base;
struct drm_device *ddev;
const struct pvr_capabilities *cap;
u32 quirks;
@@ -51,6 +54,26 @@ struct pvr {
struct platform_device *gpsPVRLDMDev;
static struct drm_device *gpsPVRDRMDev;
+u32 pvr_sgx_readl(struct pvr *ddata, unsigned short offset)
+{
+ return readl_relaxed(ddata->sgx_base + offset);
+}
+
+void pvr_sgx_writel(struct pvr *ddata, u32 val, unsigned short offset)
+{
+ writel_relaxed(val, ddata->sgx_base + offset);
+}
+
+u32 pvr_ocp_readl(struct pvr *ddata, unsigned short offset)
+{
+ return readl_relaxed(ddata->ocp_base + offset);
+}
+
+void pvr_ocp_writel(struct pvr *ddata, u32 val, unsigned short offset)
+{
+ writel_relaxed(val, ddata->ocp_base + offset);
+}
+
static int pvr_drm_load(struct drm_device *dev, unsigned long flags)
{
dev_dbg(dev->dev, "%s\n", __func__);
@@ -163,15 +186,33 @@ static struct drm_driver pvr_drm_driver = {
static int __maybe_unused pvr_runtime_suspend(struct device *dev)
{
+ struct pvr *ddata = dev_get_drvdata(dev);
+
dev_dbg(dev, "%s\n", __func__);
+ /* Nothing to do if no OCP */
+ if (!ddata->ocp_base)
+ return 0;
+
+ pvr_ocp_writel(ddata, BIT(0), SGX_OCP_IRQENABLE_CLR_2);
+
return 0;
}
static int __maybe_unused pvr_runtime_resume(struct device *dev)
{
+ struct pvr *ddata = dev_get_drvdata(dev);
+
dev_dbg(dev, "%s\n", __func__);
+ /* Nothing to do if no OCP */
+ if (!ddata->ocp_base)
+ return 0;
+
+ pvr_ocp_writel(ddata, BIT(31), SGX_OCP_DEBUG_CONFIG);
+ pvr_ocp_writel(ddata, BIT(0), SGX_OCP_IRQSTATUS_2);
+ pvr_ocp_writel(ddata, BIT(0), SGX_OCP_IRQENABLE_SET_2);
+
return 0;
}
@@ -200,18 +241,26 @@ static const struct dev_pm_ops pvr_pm_ops = {
/* revisit: should we name for different capabilities? pvr_default, pvr_omap4, pvr_smp? */
-static const struct pvr_capabilities __maybe_unused pvr_omap3 = {
+static const struct pvr_capabilities __maybe_unused pvr_omap34xx = {
+ /* Has OCP registers but not accessible */
+};
+
+static const struct pvr_capabilities __maybe_unused pvr_omap36xx = {
+ .ocp_offset = 0xfe00,
};
static const struct pvr_capabilities __maybe_unused pvr_omap4 = {
+ .ocp_offset = 0xfe00,
.quirks = PVR_QUIRK_OMAP4,
};
static const struct pvr_capabilities __maybe_unused pvr_omap4470 = {
+ .ocp_offset = 0xfe00,
.smp = true,
};
static const struct pvr_capabilities __maybe_unused pvr_omap5 = {
+ .ocp_offset = 0xfe00,
.smp = true,
};
@@ -234,23 +283,23 @@ static const struct pvr_capabilities __maybe_unused pvr_sun8i_a83t = {
static const struct of_device_id pvr_ids[] = {
#ifdef ti_omap3_sgx530_121
- { .compatible = "ti,omap3-sgx530-121", .data = &pvr_omap3, },
+ { .compatible = "ti,omap3-sgx530-121", .data = &pvr_omap34xx, },
#endif
#ifdef ti_omap3630_sgx530_125
- { .compatible = "ti,omap3-sgx530-125", .data = &pvr_omap3, },
+ { .compatible = "ti,omap3-sgx530-125", .data = &pvr_omap36xx, },
#endif
#ifdef ti_am3517_sgx530_125
- { .compatible = "ti,am3517-sgx530-125", .data = &pvr_omap3, },
+ { .compatible = "ti,am3517-sgx530-125", .data = &pvr_omap36xx, },
#endif
#ifdef ti_am3352_sgx530_125
- { .compatible = "ti,am3352-sgx530-125", .data = &pvr_omap3, },
+ { .compatible = "ti,am3352-sgx530-125", .data = &pvr_omap36xx, },
#endif
#ifdef ti_am4_sgx530_125
- { .compatible = "ti,am4-sgx530-125", .data = &pvr_omap3, },
+ { .compatible = "ti,am4-sgx530-125", .data = &pvr_omap36xx, },
#endif
#ifdef ti_omap4_sgx540_120
@@ -318,6 +367,13 @@ static int pvr_probe(struct platform_device *pdev)
if (error)
return error;
+ ddata->sgx_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ddata->sgx_base))
+ return PTR_ERR(ddata->sgx_base);
+
+ if (ddata->cap->ocp_offset)
+ ddata->ocp_base = ddata->sgx_base + ddata->cap->ocp_offset;
+
pm_runtime_enable(ddata->dev);
error = pm_runtime_get_sync(ddata->dev);
if (error < 0) {
diff --git a/drivers/gpu/drm/pvrsgx/pvr-drv.h b/drivers/gpu/drm/pvrsgx/pvr-drv.h
--- a/drivers/gpu/drm/pvrsgx/pvr-drv.h
+++ b/drivers/gpu/drm/pvrsgx/pvr-drv.h
@@ -31,6 +31,35 @@ struct pvr_unpriv {
#define DRM_IOCTL_PVR_DBGDRV DRM_IOWR(DRM_COMMAND_BASE + DRM_PVR_DBGDRV, struct pvr_ioctl)
#define DRM_IOCTL_PVR_DISP DRM_IOWR(DRM_COMMAND_BASE + DRM_PVR_DISP, drm_pvr_display_cmd)
+/* OCP registers from OCP base, at least omaps have these */
+#define SGX_OCP_REVISION 0x000
+#define SGX_OCP_HWINFO 0x004
+#define SGX_OCP_SYSCONFIG 0x010
+#define SGX_OCP_IRQSTATUS_RAW_0 0x024
+#define SGX_OCP_IRQSTATUS_RAW_1 0x028
+#define SGX_OCP_IRQSTATUS_RAW_2 0x02c
+#define SGX_OCP_IRQSTATUS_0 0x030
+#define SGX_OCP_IRQSTATUS_1 0x034
+#define SGX_OCP_IRQSTATUS_2 0x038
+#define SGX_OCP_IRQENABLE_SET_0 0x03c
+#define SGX_OCP_IRQENABLE_SET_1 0x040
+#define SGX_OCP_IRQENABLE_SET_2 0x044
+#define SGX_OCP_IRQENABLE_CLR_0 0x048
+#define SGX_OCP_IRQENABLE_CLR_1 0x04c
+#define SGX_OCP_IRQENABLE_CLR_2 0x050
+#define SGX_OCP_PAGE_CONFIG 0x100
+#define SGX_OCP_INTERRUPT_EVENT 0x104
+#define SGX_OCP_DEBUG_CONFIG 0x108
+#define SGX_OCP_DEBUG_STATUS_0 0x10c
+#define SGX_OCP_DEBUG_STATUS_1 0x110 /* Only on omap4470 and later */
+
+struct pvr;
+
+u32 pvr_sgx_readl(struct pvr *ddata, unsigned short offset);
+void pvr_sgx_writel(struct pvr *ddata, u32 val, unsigned short offset);
+u32 pvr_ocp_readl(struct pvr *ddata, unsigned short offset);
+void pvr_ocp_writel(struct pvr *ddata, u32 val, unsigned short offset);
+
/* We are currently calling these from the Imagination SDK */
int PVRCore_Init(void);
void PVRCore_Cleanup(void);
--
2.33.0
More information about the openpvrsgx-devgroup
mailing list