// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. * */ #include #include #include "hgsl.h" #include "hgsl_debugfs.h" static int hgsl_client_mem_show(struct seq_file *s, void *unused) { struct hgsl_priv *priv = s->private; struct hgsl_mem_node *tmp = NULL; seq_printf(s, "%16s %16s %10s %10s\n", "gpuaddr", "size", "flags", "type"); mutex_lock(&priv->lock); list_for_each_entry(tmp, &priv->mem_allocated, node) { seq_printf(s, "%p %16llx %10x %10d\n", tmp->memdesc.gpuaddr, tmp->memdesc.size, tmp->flags, tmp->memtype ); } mutex_unlock(&priv->lock); return 0; } DEFINE_SHOW_ATTRIBUTE(hgsl_client_mem); static int hgsl_client_memtype_show(struct seq_file *s, void *unused) { struct hgsl_priv *priv = s->private; struct hgsl_mem_node *tmp = NULL; int i; int memtype; static struct { char *name; size_t size; } gpu_mem_types[] = { {"any", 0}, {"framebuffer", 0}, {"renderbbuffer", 0}, {"arraybuffer", 0}, {"elementarraybuffer", 0}, {"vertexarraybuffer", 0}, {"texture", 0}, {"surface", 0}, {"eglsurface", 0}, {"gl", 0}, {"cl", 0}, {"cl_buffer_map", 0}, {"cl_buffer_unmap", 0}, {"cl_image_map", 0}, {"cl_image_unmap", 0}, {"cl_kernel_stack", 0}, {"cmds", 0}, {"2d", 0}, {"egl_image", 0}, {"egl_shadow", 0}, {"multisample", 0}, }; for (i = 0; i < ARRAY_SIZE(gpu_mem_types); i++) gpu_mem_types[i].size = 0; mutex_lock(&priv->lock); list_for_each_entry(tmp, &priv->mem_allocated, node) { memtype = GET_MEMTYPE(tmp->flags); if (memtype < ARRAY_SIZE(gpu_mem_types)) gpu_mem_types[memtype].size += tmp->memdesc.size; } mutex_unlock(&priv->lock); seq_printf(s, "%16s %16s\n", "type", "size"); for (i = 0; i < ARRAY_SIZE(gpu_mem_types); i++) { if (gpu_mem_types[i].size != 0) seq_printf(s, "%16s %16d\n", gpu_mem_types[i].name, gpu_mem_types[i].size); } return 0; } DEFINE_SHOW_ATTRIBUTE(hgsl_client_memtype); int hgsl_debugfs_client_init(struct hgsl_priv *priv) { struct qcom_hgsl *hgsl = priv->dev; unsigned char name[16]; struct dentry *ret; snprintf(name, sizeof(name), "%d", priv->pid); ret = debugfs_create_dir(name, hgsl->clients_debugfs); if (IS_ERR(ret)) { pr_warn("Create debugfs proc node failed.\n"); return PTR_ERR(ret); } priv->debugfs_client = ret; priv->debugfs_mem = debugfs_create_file("mem", 0444, priv->debugfs_client, priv, &hgsl_client_mem_fops); priv->debugfs_memtype = debugfs_create_file("obj_types", 0444, priv->debugfs_client, priv, &hgsl_client_memtype_fops); return 0; } void hgsl_debugfs_client_release(struct hgsl_priv *priv) { debugfs_remove_recursive(priv->debugfs_client); } void hgsl_debugfs_init(struct platform_device *pdev) { struct qcom_hgsl *hgsl_dev = platform_get_drvdata(pdev); struct dentry *root; root = debugfs_create_dir("hgsl", NULL); hgsl_dev->debugfs = root; hgsl_dev->clients_debugfs = debugfs_create_dir("clients", root); } void hgsl_debugfs_release(struct platform_device *pdev) { struct qcom_hgsl *hgsl = platform_get_drvdata(pdev); debugfs_remove_recursive(hgsl->debugfs); }