mirror of
https://github.com/revyos/thead-kernel.git
synced 2026-06-21 09:12:26 +02:00
34
drivers/gpu/drm/img-rogue/gpu_trace_point.h
Normal file
34
drivers/gpu/drm/img-rogue/gpu_trace_point.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM gpu_trace_point
|
||||
|
||||
#if !defined(_TRACE_GPU_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_GPU_H
|
||||
|
||||
#include <linux/sched/numa_balancing.h>
|
||||
#include <linux/tracepoint.h>
|
||||
#include <linux/binfmts.h>
|
||||
|
||||
TRACE_EVENT(gpu_interrupt,
|
||||
|
||||
TP_PROTO(unsigned int IRQStatusReg, unsigned int IRQStatus),
|
||||
|
||||
TP_ARGS(IRQStatusReg, IRQStatus),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( unsigned int, IRQStatusReg)
|
||||
__field( unsigned int, IRQStatus)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->IRQStatusReg = IRQStatusReg;
|
||||
__entry->IRQStatus = IRQStatus;
|
||||
),
|
||||
|
||||
TP_printk("IRQStatusReg=%d IRQStatus=%d", __entry->IRQStatusReg, __entry->IRQStatus)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_GPU_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
||||
@@ -550,6 +550,14 @@ out:
|
||||
return iErr;
|
||||
}
|
||||
|
||||
static void wrap_pvr_sync_close(void *connection_data)
|
||||
{
|
||||
CONNECTION_DATA *psConnection = (CONNECTION_DATA *)connection_data;
|
||||
pvr_sync_close(connection_data);
|
||||
OSConnectionPrivateDataDeInit(psConnection->hOsPrivateData);
|
||||
kfree(psConnection);
|
||||
}
|
||||
|
||||
/**************************************************************************/ /*!
|
||||
@Function PVRSRVDeviceSyncOpen
|
||||
@Description Sync device open.
|
||||
@@ -633,7 +641,7 @@ static int PVRSRVDeviceSyncOpen(PVRSRV_DEVICE_NODE *psDeviceNode,
|
||||
|
||||
#if defined(SUPPORT_NATIVE_FENCE_SYNC) && !defined(USE_PVRSYNC_DEVNODE)
|
||||
#if (PVRSRV_DEVICE_INIT_MODE == PVRSRV_LINUX_DEV_INIT_ON_CONNECT)
|
||||
psConnectionPriv->pfDeviceRelease = pvr_sync_close;
|
||||
psConnectionPriv->pfDeviceRelease = wrap_pvr_sync_close;
|
||||
#endif
|
||||
#endif
|
||||
psDRMFile->driver_priv = psConnectionPriv;
|
||||
|
||||
@@ -1843,6 +1843,34 @@ void OSDumpVersionInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
|
||||
utsname()->version,
|
||||
utsname()->machine);
|
||||
}
|
||||
|
||||
void OSWriteHWRegl(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
|
||||
{
|
||||
writel((IMG_UINT32)(ui32Value), (IMG_BYTE __iomem *)(pvLinRegBaseAddr) + (ui32Offset));
|
||||
}
|
||||
|
||||
void OSWriteHWRegll(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT64 ui64Value)
|
||||
{
|
||||
volatile void *_addr = pvLinRegBaseAddr;
|
||||
IMG_UINT32 _off = ui32Offset;
|
||||
IMG_UINT64 _val = ui64Value;
|
||||
writel((IMG_UINT32)((_val) & 0xffffffff), (IMG_BYTE __iomem *)(_addr) + (_off));
|
||||
writel((IMG_UINT32)(((IMG_UINT64)(_val) >> 32) & 0xffffffff), (IMG_BYTE __iomem *)(_addr) + (_off) + 4);
|
||||
}
|
||||
|
||||
IMG_UINT32 OSReadHWRegl(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
|
||||
{
|
||||
return ((IMG_UINT32)readl((IMG_BYTE __iomem *)(pvLinRegBaseAddr) + (ui32Offset)));
|
||||
}
|
||||
|
||||
IMG_UINT64 OSReadHWRegll(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
|
||||
{
|
||||
volatile void *_addr = pvLinRegBaseAddr;
|
||||
IMG_UINT32 _off = ui32Offset;
|
||||
return (IMG_UINT64)(( (IMG_UINT64)(readl((IMG_BYTE __iomem *)(_addr) + (_off) + 4)) << 32) \
|
||||
| readl((IMG_BYTE __iomem *)(_addr) + (_off)));
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_DMA_TRANSFER)
|
||||
|
||||
typedef struct _OS_CLEANUP_DATA_
|
||||
|
||||
@@ -1022,34 +1022,24 @@ void OSWriteMemoryBarrier(volatile void *hReadback);
|
||||
} while (0)
|
||||
|
||||
#if defined(__linux__) && defined(__KERNEL__) && !defined(NO_HARDWARE)
|
||||
|
||||
void OSWriteHWRegl(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
|
||||
void OSWriteHWRegll(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT64 ui64Value);
|
||||
IMG_UINT32 OSReadHWRegl(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
|
||||
IMG_UINT64 OSReadHWRegll(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
|
||||
|
||||
#define OSReadHWReg8(addr, off) ((IMG_UINT8)readb((IMG_BYTE __iomem *)(addr) + (off)))
|
||||
#define OSReadHWReg16(addr, off) ((IMG_UINT16)readw((IMG_BYTE __iomem *)(addr) + (off)))
|
||||
#define OSReadHWReg32(addr, off) ((IMG_UINT32)readl((IMG_BYTE __iomem *)(addr) + (off)))
|
||||
#define OSReadHWReg32(addr, off) OSReadHWRegl(addr, off)
|
||||
|
||||
/* Little endian support only */
|
||||
#define OSReadHWReg64(addr, off) \
|
||||
({ \
|
||||
__typeof__(addr) _addr = addr; \
|
||||
__typeof__(off) _off = off; \
|
||||
(IMG_UINT64) \
|
||||
( \
|
||||
( (IMG_UINT64)(readl((IMG_BYTE __iomem *)(_addr) + (_off) + 4)) << 32) \
|
||||
| readl((IMG_BYTE __iomem *)(_addr) + (_off)) \
|
||||
); \
|
||||
})
|
||||
#define OSReadHWReg64(addr, off) OSReadHWRegll(addr, off)
|
||||
|
||||
#define OSWriteHWReg8(addr, off, val) writeb((IMG_UINT8)(val), (IMG_BYTE __iomem *)(addr) + (off))
|
||||
#define OSWriteHWReg16(addr, off, val) writew((IMG_UINT16)(val), (IMG_BYTE __iomem *)(addr) + (off))
|
||||
#define OSWriteHWReg32(addr, off, val) writel((IMG_UINT32)(val), (IMG_BYTE __iomem *)(addr) + (off))
|
||||
#define OSWriteHWReg32(addr, off, val) OSWriteHWRegl(addr, off, val)
|
||||
/* Little endian support only */
|
||||
#define OSWriteHWReg64(addr, off, val) do \
|
||||
{ \
|
||||
__typeof__(addr) _addr = addr; \
|
||||
__typeof__(off) _off = off; \
|
||||
__typeof__(val) _val = val; \
|
||||
writel((IMG_UINT32)((_val) & 0xffffffff), (IMG_BYTE __iomem *)(_addr) + (_off)); \
|
||||
writel((IMG_UINT32)(((IMG_UINT64)(_val) >> 32) & 0xffffffff), (IMG_BYTE __iomem *)(_addr) + (_off) + 4); \
|
||||
} while (0)
|
||||
#define OSWriteHWReg64(addr, off, val) OSWriteHWRegll(addr, off, val)
|
||||
|
||||
|
||||
#elif defined(NO_HARDWARE)
|
||||
|
||||
@@ -127,6 +127,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include "pdump_physmem.h"
|
||||
#endif
|
||||
|
||||
#undef linux
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "gpu_trace_point.h"
|
||||
|
||||
static PVRSRV_ERROR RGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
|
||||
static PVRSRV_ERROR RGXDevVersionString(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_CHAR **ppszVersionString);
|
||||
static PVRSRV_ERROR RGXDevClockSpeed(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_PUINT32 pui32RGXClockSpeed);
|
||||
@@ -402,6 +406,7 @@ static inline IMG_BOOL RGXAckHwIrq(PVRSRV_RGXDEV_INFO *psDevInfo,
|
||||
{
|
||||
IMG_UINT32 ui32IRQStatus = OSReadHWReg32(psDevInfo->pvRegsBaseKM, ui32IRQStatusReg);
|
||||
|
||||
trace_gpu_interrupt(ui32IRQStatusReg, ui32IRQStatus);
|
||||
if (ui32IRQStatus & ui32IRQStatusEventMsk)
|
||||
{
|
||||
/* acknowledge and clear the interrupt */
|
||||
@@ -511,6 +516,9 @@ static IMG_BOOL RGX_LISRHandler(void *pvData)
|
||||
{
|
||||
UPDATE_LISR_DBG_STATUS(RGX_LISR_DEVICE_NOT_POWERED);
|
||||
}
|
||||
/* When handling interrupts, there may be a situation where the GPU is powered off,
|
||||
* return IMG_TRUE to avoid the OS considering that this interrupt is nobody cared */
|
||||
bIrqAcknowledged = IMG_TRUE;
|
||||
}
|
||||
|
||||
return bIrqAcknowledged;
|
||||
|
||||
@@ -373,7 +373,7 @@ PVRSRVBridgeEventObjectClose(IMG_UINT32 ui32DispatchTableEntry,
|
||||
(psEventObjectCloseOUT->eError != PVRSRV_ERROR_KERNEL_CCB_FULL) &&
|
||||
(psEventObjectCloseOUT->eError != PVRSRV_ERROR_RETRY)))
|
||||
{
|
||||
PVR_DPF((PVR_DBG_ERROR,
|
||||
PVR_DPF((PVR_DBG_WARNING,
|
||||
"%s: %s", __func__, PVRSRVGetErrorString(psEventObjectCloseOUT->eError)));
|
||||
UnlockHandle(psConnection->psHandleBase);
|
||||
goto EventObjectClose_exit;
|
||||
|
||||
@@ -307,6 +307,8 @@ PVRSRV_ERROR SysDevInit(void *pvOSDevice, PVRSRV_DEVICE_CONFIG **ppsDevConfig)
|
||||
dma_set_mask(pvOSDevice, DMA_BIT_MASK(40));
|
||||
#endif
|
||||
|
||||
thead_sysfs_init(pvOSDevice);
|
||||
|
||||
mfg = dt_hw_init(pvOSDevice);
|
||||
if (IS_ERR(mfg)) {
|
||||
if (PTR_ERR(mfg) == -EPROBE_DEFER)
|
||||
@@ -419,6 +421,7 @@ void SysDevDeInit(PVRSRV_DEVICE_CONFIG *psDevConfig)
|
||||
#endif
|
||||
|
||||
PhysHeapsDestroy(psDevConfig->pasPhysHeaps);
|
||||
thead_sysfs_uninit(psDevConfig->pvOSDevice);
|
||||
OSFreeMem(psDevConfig);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,9 +54,340 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <drm/drm_device.h>
|
||||
|
||||
#include "pvrsrv.h"
|
||||
#include "pvr_drv.h"
|
||||
#include "proc_stats.h"
|
||||
#include "pvrversion.h"
|
||||
#include "rgxhwperf.h"
|
||||
#include "rgxinit.h"
|
||||
#include "process_stats.h"
|
||||
#include "thead_sys.h"
|
||||
|
||||
#ifdef SUPPORT_RGX
|
||||
static IMG_HANDLE ghGpuUtilSysFS;
|
||||
#endif
|
||||
static int thead_gpu_period_ms = -1;
|
||||
static int thead_gpu_loading_max_percent = -1;
|
||||
static int thead_gpu_last_server_error = 0;
|
||||
static int thead_gpu_last_rgx_error = 0;
|
||||
|
||||
struct gpu_sysfs_private_data {
|
||||
struct device *dev;
|
||||
struct timer_list timer;
|
||||
struct workqueue_struct *workqueue;
|
||||
struct work_struct work;
|
||||
};
|
||||
static struct gpu_sysfs_private_data thead_gpu_sysfs_private_data;
|
||||
|
||||
/******************定义log的读写属性*************************************/
|
||||
static ssize_t thead_gpu_log_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t len = 0;
|
||||
PDLLIST_NODE pNext, pNode;
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct pvr_drm_private *priv = drm_dev->dev_private;
|
||||
PVRSRV_DEVICE_NODE *psDevNode = priv->dev_node;
|
||||
PVRSRV_DEVICE_HEALTH_STATUS eHealthStatus = OSAtomicRead(&psDevNode->eHealthStatus);
|
||||
PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
|
||||
|
||||
// 驱动信息
|
||||
int dev_id = (int)psDevNode->sDevId.ui32InternalID;
|
||||
int dev_connection_num = 0;
|
||||
int dev_loading_percent = -1;
|
||||
|
||||
// 内存信息
|
||||
IMG_UINT32 dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_COUNT];
|
||||
|
||||
// 实例/会话/通道信息
|
||||
int instance_id = 0;
|
||||
|
||||
// 异常信息
|
||||
char* server_state[3] = {"UNDEFINED", "OK", "BAD"};
|
||||
char* rgx_state[5] = {"UNDEFINED", "OK", "NOT RESPONDING", "DEAD", "FAULT"};
|
||||
int rgx_err = 0;
|
||||
|
||||
if (psDevNode->pvDevice != NULL)
|
||||
{
|
||||
PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice;
|
||||
#ifdef SUPPORT_RGX
|
||||
if (!PVRSRV_VZ_MODE_IS(GUEST) &&
|
||||
psDevInfo->pfnGetGpuUtilStats &&
|
||||
eHealthStatus == PVRSRV_DEVICE_HEALTH_STATUS_OK)
|
||||
{
|
||||
RGXFWIF_GPU_UTIL_STATS sGpuUtilStats;
|
||||
PVRSRV_ERROR eError = PVRSRV_OK;
|
||||
|
||||
eError = psDevInfo->pfnGetGpuUtilStats(psDevNode,
|
||||
ghGpuUtilSysFS,
|
||||
&sGpuUtilStats);
|
||||
|
||||
if ((eError == PVRSRV_OK) &&
|
||||
((IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative))
|
||||
{
|
||||
IMG_UINT64 util;
|
||||
IMG_UINT32 rem;
|
||||
|
||||
util = 100 * sGpuUtilStats.ui64GpuStatActive;
|
||||
util = OSDivide64(util, (IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative, &rem);
|
||||
|
||||
dev_loading_percent = (int)util;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
rgx_err = psDevInfo->sErrorCounts.ui32WGPErrorCount + psDevInfo->sErrorCounts.ui32TRPErrorCount;
|
||||
}
|
||||
|
||||
if (dev_loading_percent > thead_gpu_loading_max_percent)
|
||||
thead_gpu_loading_max_percent = dev_loading_percent;
|
||||
|
||||
PVRSRVFindProcessMemStats(0, PVRSRV_DRIVER_STAT_TYPE_COUNT, IMG_TRUE, dev_mem_state);
|
||||
|
||||
if (!psDevNode->hConnectionsLock)
|
||||
{
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"[GPU] Version: %s\n"
|
||||
"Build Info: %s %s %s %s\n"
|
||||
"----------------------------------------MODULE PARAM-----------------------------------------\n"
|
||||
"updatePeriod_ms\n"
|
||||
"%d\n"
|
||||
"----------------------------------------MODULE STATUS----------------------------------------\n"
|
||||
"DevId DevInstanceNum DevLoading_%% DevLoadingMax_%%\n"
|
||||
"%-10d%-20d%-15d%-15d\n"
|
||||
"----------------------------------------MEM INFO(KB)-----------------------------------------\n"
|
||||
"KMalloc VMalloc PTMemoryUMA VMapPTUMA\n"
|
||||
"%-18d%-18d%-18d%-18d\n"
|
||||
"PTMemoryLMA IORemapPTLMA GPUMemLMA GPUMemUMA\n"
|
||||
"%-18d%-18d%-18d%-18d\n"
|
||||
"GPUMemUMAPool MappedGPUMemUMA/LMA DmaBufImport\n"
|
||||
"%-18d%-36d%-18d\n"
|
||||
"----------------------------------------INSTANCE INFO----------------------------------------\n"
|
||||
"Id ProName ProId ThdId\n"
|
||||
"---------------------------------------EXCEPTION INFO----------------------------------------\n"
|
||||
"Server_State Server_Error RGX_State RGX_Error\n"
|
||||
"%-18s%-18d%-18s%-18d\n",
|
||||
PVRVERSION_STRING, utsname()->sysname, utsname()->release, utsname()->version, utsname()->machine, thead_gpu_period_ms,
|
||||
dev_id, 0, dev_loading_percent, thead_gpu_loading_max_percent,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_KMALLOC] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_VMALLOC],
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_UMA] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_VMAP_PT_UMA] >> 10,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_LMA] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_IOREMAP_PT_LMA] >> 10,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_LMA] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA] >> 10,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA_POOL] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_MAPPED_GPUMEM_UMA_LMA] >> 10,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_DMA_BUF_IMPORT] >> 10,
|
||||
server_state[psPVRSRVData->eServicesState], PVRSRV_KM_ERRORS - thead_gpu_last_server_error,
|
||||
rgx_state[eHealthStatus], rgx_err - thead_gpu_last_rgx_error);
|
||||
return len;
|
||||
}
|
||||
|
||||
OSLockAcquire(psDevNode->hConnectionsLock);
|
||||
dllist_foreach_node(&psDevNode->sConnections, pNode, pNext)
|
||||
{
|
||||
dev_connection_num++;
|
||||
}
|
||||
|
||||
// 格式化输出
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"[GPU] Version: %s\n"
|
||||
"Build Info: %s %s %s %s\n"
|
||||
"----------------------------------------MODULE PARAM-----------------------------------------\n"
|
||||
"updatePeriod_ms\n"
|
||||
"%d\n"
|
||||
"----------------------------------------MODULE STATUS----------------------------------------\n"
|
||||
"DevId DevInstanceNum DevLoading_%% DevLoadingMax_%%\n"
|
||||
"%-10d%-20d%-15d%-15d\n"
|
||||
"----------------------------------------MEM INFO(KB)-----------------------------------------\n"
|
||||
"KMalloc VMalloc PTMemoryUMA VMapPTUMA\n"
|
||||
"%-18d%-18d%-18d%-18d\n"
|
||||
"PTMemoryLMA IORemapPTLMA GPUMemLMA GPUMemUMA\n"
|
||||
"%-18d%-18d%-18d%-18d\n"
|
||||
"GPUMemUMAPool MappedGPUMemUMA/LMA DmaBufImport\n"
|
||||
"%-18d%-36d%-18d\n"
|
||||
"----------------------------------------INSTANCE INFO----------------------------------------\n"
|
||||
"Id ProName ProId ThdId\n",
|
||||
PVRVERSION_STRING, utsname()->sysname, utsname()->release, utsname()->version, utsname()->machine, thead_gpu_period_ms,
|
||||
dev_id, dev_connection_num, dev_loading_percent, thead_gpu_loading_max_percent,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_KMALLOC] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_VMALLOC],
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_UMA] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_VMAP_PT_UMA] >> 10,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_PT_MEMORY_LMA] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_IOREMAP_PT_LMA] >> 10,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_LMA] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA] >> 10,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_ALLOC_GPUMEM_UMA_POOL] >> 10, dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_MAPPED_GPUMEM_UMA_LMA] >> 10,
|
||||
dev_mem_state[PVRSRV_DRIVER_STAT_TYPE_DMA_BUF_IMPORT] >> 10);
|
||||
|
||||
dllist_foreach_node(&psDevNode->sConnections, pNode, pNext)
|
||||
{
|
||||
CONNECTION_DATA *sData = IMG_CONTAINER_OF(pNode, CONNECTION_DATA, sConnectionListNode);
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"%-5d%-20s%-10d%-10d\n",
|
||||
instance_id, sData->pszProcName, sData->pid, sData->tid);
|
||||
instance_id++;
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"---------------------------------------EXCEPTION INFO----------------------------------------\n"
|
||||
"Server_State Server_Error RGX_State RGX_Error\n"
|
||||
"%-18s%-18d%-18s%-18d\n",
|
||||
server_state[psPVRSRVData->eServicesState], PVRSRV_KM_ERRORS - thead_gpu_last_server_error,
|
||||
rgx_state[eHealthStatus], rgx_err - thead_gpu_last_rgx_error);
|
||||
|
||||
OSLockRelease(psDevNode->hConnectionsLock);
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t thead_gpu_log_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct pvr_drm_private *priv = drm_dev->dev_private;
|
||||
PVRSRV_DEVICE_NODE *psDevNode = priv->dev_node;
|
||||
|
||||
thead_gpu_loading_max_percent = -1;
|
||||
thead_gpu_last_server_error = PVRSRV_KM_ERRORS;
|
||||
if (psDevNode->pvDevice != NULL)
|
||||
{
|
||||
PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice;
|
||||
thead_gpu_last_rgx_error = psDevInfo->sErrorCounts.ui32WGPErrorCount + psDevInfo->sErrorCounts.ui32TRPErrorCount;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute sthead_gpu_log_attr = __ATTR(log, 0664, thead_gpu_log_show, thead_gpu_log_store);
|
||||
|
||||
/******************定义updatePeriod的读写属性*************************************/
|
||||
static ssize_t thead_gpu_updatePeriod_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n(set 50~10000 to enable update period, set other value to disable)\n",
|
||||
thead_gpu_period_ms);
|
||||
}
|
||||
|
||||
static ssize_t thead_gpu_updatePeriod_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
char *start = (char *)buf;
|
||||
int temp_period_ms = simple_strtoul(start, &start, 0);
|
||||
if (temp_period_ms >= 50 && temp_period_ms <= 10000) {
|
||||
thead_gpu_period_ms = temp_period_ms;
|
||||
mod_timer(&thead_gpu_sysfs_private_data.timer, jiffies + msecs_to_jiffies(thead_gpu_period_ms));
|
||||
} else {
|
||||
thead_gpu_period_ms = -1;
|
||||
del_timer(&thead_gpu_sysfs_private_data.timer);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute sthead_gpu_updateperiod_attr = __ATTR(updatePeriod_ms, 0664, thead_gpu_updatePeriod_show, thead_gpu_updatePeriod_store);
|
||||
|
||||
/******************定义sysfs属性info group*************************************/
|
||||
static struct attribute *pthead_gpu_attrs[] = {
|
||||
&sthead_gpu_log_attr.attr,
|
||||
&sthead_gpu_updateperiod_attr.attr,
|
||||
NULL, // must be NULL
|
||||
};
|
||||
|
||||
static struct attribute_group sthead_gpu_attr_group = {
|
||||
.name = "info", // device下目录指定
|
||||
.attrs = pthead_gpu_attrs,
|
||||
};
|
||||
|
||||
static void thead_gpu_work_func(struct work_struct *w)
|
||||
{
|
||||
struct gpu_sysfs_private_data *data = container_of(w, struct gpu_sysfs_private_data, work);
|
||||
struct device *dev = data->dev;
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct pvr_drm_private *priv = drm_dev->dev_private;
|
||||
PVRSRV_DEVICE_NODE *psDevNode = priv->dev_node;
|
||||
PVRSRV_DEVICE_HEALTH_STATUS eHealthStatus = OSAtomicRead(&psDevNode->eHealthStatus);
|
||||
int current_loading_percent = -1;
|
||||
if (psDevNode->pvDevice != NULL)
|
||||
{
|
||||
PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice;
|
||||
#ifdef SUPPORT_RGX
|
||||
if (!PVRSRV_VZ_MODE_IS(GUEST) &&
|
||||
psDevInfo->pfnGetGpuUtilStats &&
|
||||
eHealthStatus == PVRSRV_DEVICE_HEALTH_STATUS_OK)
|
||||
{
|
||||
RGXFWIF_GPU_UTIL_STATS sGpuUtilStats;
|
||||
PVRSRV_ERROR eError = PVRSRV_OK;
|
||||
|
||||
eError = psDevInfo->pfnGetGpuUtilStats(psDevNode,
|
||||
ghGpuUtilSysFS,
|
||||
&sGpuUtilStats);
|
||||
|
||||
if ((eError == PVRSRV_OK) &&
|
||||
((IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative))
|
||||
{
|
||||
IMG_UINT64 util;
|
||||
IMG_UINT32 rem;
|
||||
|
||||
util = 100 * sGpuUtilStats.ui64GpuStatActive;
|
||||
util = OSDivide64(util, (IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative, &rem);
|
||||
|
||||
current_loading_percent = (int)util;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (current_loading_percent > thead_gpu_loading_max_percent)
|
||||
thead_gpu_loading_max_percent = current_loading_percent;
|
||||
mod_timer(&data->timer, jiffies + msecs_to_jiffies(thead_gpu_period_ms));
|
||||
}
|
||||
|
||||
void thead_gpu_timer_callback(struct timer_list *t)
|
||||
{
|
||||
struct gpu_sysfs_private_data *data = container_of(t, struct gpu_sysfs_private_data, timer);
|
||||
queue_work(data->workqueue, &data->work);
|
||||
}
|
||||
|
||||
int thead_sysfs_init(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
ret = sysfs_create_group(&dev->kobj, &sthead_gpu_attr_group);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to create gpu dev sysfs.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_RGX) && !defined(NO_HARDWARE)
|
||||
if (SORgxGpuUtilStatsRegister(&ghGpuUtilSysFS) != PVRSRV_OK)
|
||||
{
|
||||
dev_err(dev, "Failed to register GpuUtil for sysfs.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
thead_gpu_sysfs_private_data.workqueue = create_workqueue("gpu_sysfs_workqueue");
|
||||
if (!thead_gpu_sysfs_private_data.workqueue)
|
||||
return -ENOMEM;
|
||||
INIT_WORK(&thead_gpu_sysfs_private_data.work, thead_gpu_work_func);
|
||||
|
||||
thead_gpu_sysfs_private_data.dev = dev;
|
||||
timer_setup(&thead_gpu_sysfs_private_data.timer, thead_gpu_timer_callback, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void thead_sysfs_uninit(struct device *dev)
|
||||
{
|
||||
if (thead_gpu_sysfs_private_data.dev == dev)
|
||||
del_timer(&thead_gpu_sysfs_private_data.timer);
|
||||
|
||||
if (thead_gpu_sysfs_private_data.workqueue)
|
||||
destroy_workqueue(thead_gpu_sysfs_private_data.workqueue);
|
||||
|
||||
#if defined(SUPPORT_RGX) && !defined(NO_HARDWARE)
|
||||
if (SORgxGpuUtilStatsUnregister(ghGpuUtilSysFS) != PVRSRV_OK)
|
||||
{
|
||||
dev_err(dev, "Failed to unregister GpuUtil for sysfs.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
sysfs_remove_group(&dev->kobj, &sthead_gpu_attr_group);
|
||||
}
|
||||
|
||||
int thead_mfg_enable(struct gpu_plat_if *mfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -63,6 +63,9 @@ struct gpu_plat_if {
|
||||
struct regmap *vosys_regmap;
|
||||
};
|
||||
|
||||
int thead_sysfs_init(struct device *dev);
|
||||
void thead_sysfs_uninit(struct device *dev);
|
||||
|
||||
struct gpu_plat_if *dt_hw_init(struct device *dev);
|
||||
void dt_hw_uninit(struct gpu_plat_if *mfg);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user