brintos

brintos / linux-shallow public Read only

0
0
Text · 3.6 KiB · 169b8fe Raw
160 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.3 */4 5#include <linux/types.h>6#include <linux/debugfs.h>7 8#include <drm/drm_debugfs.h>9#include <drm/drm_file.h>10#include <drm/drm_print.h>11 12#include "a5xx_gpu.h"13 14static void pfp_print(struct msm_gpu *gpu, struct drm_printer *p)15{16	int i;17 18	drm_printf(p, "PFP state:\n");19 20	for (i = 0; i < 36; i++) {21		gpu_write(gpu, REG_A5XX_CP_PFP_STAT_ADDR, i);22		drm_printf(p, "  %02x: %08x\n", i,23			gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA));24	}25}26 27static void me_print(struct msm_gpu *gpu, struct drm_printer *p)28{29	int i;30 31	drm_printf(p, "ME state:\n");32 33	for (i = 0; i < 29; i++) {34		gpu_write(gpu, REG_A5XX_CP_ME_STAT_ADDR, i);35		drm_printf(p, "  %02x: %08x\n", i,36			gpu_read(gpu, REG_A5XX_CP_ME_STAT_DATA));37	}38}39 40static void meq_print(struct msm_gpu *gpu, struct drm_printer *p)41{42	int i;43 44	drm_printf(p, "MEQ state:\n");45	gpu_write(gpu, REG_A5XX_CP_MEQ_DBG_ADDR, 0);46 47	for (i = 0; i < 64; i++) {48		drm_printf(p, "  %02x: %08x\n", i,49			gpu_read(gpu, REG_A5XX_CP_MEQ_DBG_DATA));50	}51}52 53static void roq_print(struct msm_gpu *gpu, struct drm_printer *p)54{55	int i;56 57	drm_printf(p, "ROQ state:\n");58	gpu_write(gpu, REG_A5XX_CP_ROQ_DBG_ADDR, 0);59 60	for (i = 0; i < 512 / 4; i++) {61		uint32_t val[4];62		int j;63		for (j = 0; j < 4; j++)64			val[j] = gpu_read(gpu, REG_A5XX_CP_ROQ_DBG_DATA);65		drm_printf(p, "  %02x: %08x %08x %08x %08x\n", i,66			val[0], val[1], val[2], val[3]);67	}68}69 70static int show(struct seq_file *m, void *arg)71{72	struct drm_info_node *node = m->private;73	struct drm_device *dev = node->minor->dev;74	struct msm_drm_private *priv = dev->dev_private;75	struct drm_printer p = drm_seq_file_printer(m);76	void (*show)(struct msm_gpu *gpu, struct drm_printer *p) =77		node->info_ent->data;78 79	show(priv->gpu, &p);80	return 0;81}82 83#define ENT(n) { .name = #n, .show = show, .data = n ##_print }84static struct drm_info_list a5xx_debugfs_list[] = {85	ENT(pfp),86	ENT(me),87	ENT(meq),88	ENT(roq),89};90 91/* for debugfs files that can be written to, we can't use drm helper: */92static int93reset_set(void *data, u64 val)94{95	struct drm_device *dev = data;96	struct msm_drm_private *priv = dev->dev_private;97	struct msm_gpu *gpu = priv->gpu;98	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);99	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);100 101	if (!capable(CAP_SYS_ADMIN))102		return -EINVAL;103 104	/* TODO do we care about trying to make sure the GPU is idle?105	 * Since this is just a debug feature limited to CAP_SYS_ADMIN,106	 * maybe it is fine to let the user keep both pieces if they107	 * try to reset an active GPU.108	 */109 110	mutex_lock(&gpu->lock);111 112	release_firmware(adreno_gpu->fw[ADRENO_FW_PM4]);113	adreno_gpu->fw[ADRENO_FW_PM4] = NULL;114 115	release_firmware(adreno_gpu->fw[ADRENO_FW_PFP]);116	adreno_gpu->fw[ADRENO_FW_PFP] = NULL;117 118	if (a5xx_gpu->pm4_bo) {119		msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace);120		drm_gem_object_put(a5xx_gpu->pm4_bo);121		a5xx_gpu->pm4_bo = NULL;122	}123 124	if (a5xx_gpu->pfp_bo) {125		msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace);126		drm_gem_object_put(a5xx_gpu->pfp_bo);127		a5xx_gpu->pfp_bo = NULL;128	}129 130	gpu->needs_hw_init = true;131 132	pm_runtime_get_sync(&gpu->pdev->dev);133	gpu->funcs->recover(gpu);134 135	pm_runtime_put_sync(&gpu->pdev->dev);136	mutex_unlock(&gpu->lock);137 138	return 0;139}140 141DEFINE_DEBUGFS_ATTRIBUTE(reset_fops, NULL, reset_set, "%llx\n");142 143 144void a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor)145{146	struct drm_device *dev;147 148	if (!minor)149		return;150 151	dev = minor->dev;152 153	drm_debugfs_create_files(a5xx_debugfs_list,154				 ARRAY_SIZE(a5xx_debugfs_list),155				 minor->debugfs_root, minor);156 157	debugfs_create_file_unsafe("reset", S_IWUGO, minor->debugfs_root, dev,158				&reset_fops);159}160