···7171#include "amdgpu_dm.h"7272#include "amdgpu_virt.h"7373#include "amdgpu_gart.h"7474-7474+#include "amdgpu_debugfs.h"75757676/*7777 * Modules parameters.···425425void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj);426426void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);427427int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);428428-int amdgpu_gem_debugfs_init(struct amdgpu_device *adev);429428430429/* sub-allocation manager, it has to be protected by another lock.431430 * By conception this is an helper for other part of the driver···12391240 */12401241void amdgpu_test_moves(struct amdgpu_device *adev);1241124212421242-/*12431243- * Debugfs12441244- */12451245-struct amdgpu_debugfs {12461246- const struct drm_info_list *files;12471247- unsigned num_files;12481248-};12491249-12501250-int amdgpu_debugfs_add_files(struct amdgpu_device *adev,12511251- const struct drm_info_list *files,12521252- unsigned nfiles);12531253-int amdgpu_debugfs_fence_init(struct amdgpu_device *adev);12541254-int amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);1255124312561244/*12571245 * amdgpu smumgr functions
+792
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
···11+/*22+ * Copyright 2008 Advanced Micro Devices, Inc.33+ * Copyright 2008 Red Hat Inc.44+ * Copyright 2009 Jerome Glisse.55+ *66+ * Permission is hereby granted, free of charge, to any person obtaining a77+ * copy of this software and associated documentation files (the "Software"),88+ * to deal in the Software without restriction, including without limitation99+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,1010+ * and/or sell copies of the Software, and to permit persons to whom the1111+ * Software is furnished to do so, subject to the following conditions:1212+ *1313+ * The above copyright notice and this permission notice shall be included in1414+ * all copies or substantial portions of the Software.1515+ *1616+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR1717+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1818+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL1919+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR2020+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,2121+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR2222+ * OTHER DEALINGS IN THE SOFTWARE.2323+ *2424+ */2525+2626+#include <linux/kthread.h>2727+#include <drm/drmP.h>2828+#include <linux/debugfs.h>2929+#include "amdgpu.h"3030+3131+/*3232+ * Debugfs3333+ */3434+int amdgpu_debugfs_add_files(struct amdgpu_device *adev,3535+ const struct drm_info_list *files,3636+ unsigned nfiles)3737+{3838+ unsigned i;3939+4040+ for (i = 0; i < adev->debugfs_count; i++) {4141+ if (adev->debugfs[i].files == files) {4242+ /* Already registered */4343+ return 0;4444+ }4545+ }4646+4747+ i = adev->debugfs_count + 1;4848+ if (i > AMDGPU_DEBUGFS_MAX_COMPONENTS) {4949+ DRM_ERROR("Reached maximum number of debugfs components.\n");5050+ DRM_ERROR("Report so we increase "5151+ "AMDGPU_DEBUGFS_MAX_COMPONENTS.\n");5252+ return -EINVAL;5353+ }5454+ adev->debugfs[adev->debugfs_count].files = files;5555+ adev->debugfs[adev->debugfs_count].num_files = nfiles;5656+ adev->debugfs_count = i;5757+#if defined(CONFIG_DEBUG_FS)5858+ drm_debugfs_create_files(files, nfiles,5959+ adev->ddev->primary->debugfs_root,6060+ adev->ddev->primary);6161+#endif6262+ return 0;6363+}6464+6565+#if defined(CONFIG_DEBUG_FS)6666+6767+static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,6868+ size_t size, loff_t *pos)6969+{7070+ struct amdgpu_device *adev = file_inode(f)->i_private;7171+ ssize_t result = 0;7272+ int r;7373+ bool pm_pg_lock, use_bank;7474+ unsigned instance_bank, sh_bank, se_bank;7575+7676+ if (size & 0x3 || *pos & 0x3)7777+ return -EINVAL;7878+7979+ /* are we reading registers for which a PG lock is necessary? */8080+ pm_pg_lock = (*pos >> 23) & 1;8181+8282+ if (*pos & (1ULL << 62)) {8383+ se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;8484+ sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;8585+ instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;8686+8787+ if (se_bank == 0x3FF)8888+ se_bank = 0xFFFFFFFF;8989+ if (sh_bank == 0x3FF)9090+ sh_bank = 0xFFFFFFFF;9191+ if (instance_bank == 0x3FF)9292+ instance_bank = 0xFFFFFFFF;9393+ use_bank = 1;9494+ } else {9595+ use_bank = 0;9696+ }9797+9898+ *pos &= (1UL << 22) - 1;9999+100100+ if (use_bank) {101101+ if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||102102+ (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))103103+ return -EINVAL;104104+ mutex_lock(&adev->grbm_idx_mutex);105105+ amdgpu_gfx_select_se_sh(adev, se_bank,106106+ sh_bank, instance_bank);107107+ }108108+109109+ if (pm_pg_lock)110110+ mutex_lock(&adev->pm.mutex);111111+112112+ while (size) {113113+ uint32_t value;114114+115115+ if (*pos > adev->rmmio_size)116116+ goto end;117117+118118+ value = RREG32(*pos >> 2);119119+ r = put_user(value, (uint32_t *)buf);120120+ if (r) {121121+ result = r;122122+ goto end;123123+ }124124+125125+ result += 4;126126+ buf += 4;127127+ *pos += 4;128128+ size -= 4;129129+ }130130+131131+end:132132+ if (use_bank) {133133+ amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);134134+ mutex_unlock(&adev->grbm_idx_mutex);135135+ }136136+137137+ if (pm_pg_lock)138138+ mutex_unlock(&adev->pm.mutex);139139+140140+ return result;141141+}142142+143143+static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,144144+ size_t size, loff_t *pos)145145+{146146+ struct amdgpu_device *adev = file_inode(f)->i_private;147147+ ssize_t result = 0;148148+ int r;149149+ bool pm_pg_lock, use_bank;150150+ unsigned instance_bank, sh_bank, se_bank;151151+152152+ if (size & 0x3 || *pos & 0x3)153153+ return -EINVAL;154154+155155+ /* are we reading registers for which a PG lock is necessary? */156156+ pm_pg_lock = (*pos >> 23) & 1;157157+158158+ if (*pos & (1ULL << 62)) {159159+ se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;160160+ sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;161161+ instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;162162+163163+ if (se_bank == 0x3FF)164164+ se_bank = 0xFFFFFFFF;165165+ if (sh_bank == 0x3FF)166166+ sh_bank = 0xFFFFFFFF;167167+ if (instance_bank == 0x3FF)168168+ instance_bank = 0xFFFFFFFF;169169+ use_bank = 1;170170+ } else {171171+ use_bank = 0;172172+ }173173+174174+ *pos &= (1UL << 22) - 1;175175+176176+ if (use_bank) {177177+ if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||178178+ (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))179179+ return -EINVAL;180180+ mutex_lock(&adev->grbm_idx_mutex);181181+ amdgpu_gfx_select_se_sh(adev, se_bank,182182+ sh_bank, instance_bank);183183+ }184184+185185+ if (pm_pg_lock)186186+ mutex_lock(&adev->pm.mutex);187187+188188+ while (size) {189189+ uint32_t value;190190+191191+ if (*pos > adev->rmmio_size)192192+ return result;193193+194194+ r = get_user(value, (uint32_t *)buf);195195+ if (r)196196+ return r;197197+198198+ WREG32(*pos >> 2, value);199199+200200+ result += 4;201201+ buf += 4;202202+ *pos += 4;203203+ size -= 4;204204+ }205205+206206+ if (use_bank) {207207+ amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);208208+ mutex_unlock(&adev->grbm_idx_mutex);209209+ }210210+211211+ if (pm_pg_lock)212212+ mutex_unlock(&adev->pm.mutex);213213+214214+ return result;215215+}216216+217217+static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,218218+ size_t size, loff_t *pos)219219+{220220+ struct amdgpu_device *adev = file_inode(f)->i_private;221221+ ssize_t result = 0;222222+ int r;223223+224224+ if (size & 0x3 || *pos & 0x3)225225+ return -EINVAL;226226+227227+ while (size) {228228+ uint32_t value;229229+230230+ value = RREG32_PCIE(*pos >> 2);231231+ r = put_user(value, (uint32_t *)buf);232232+ if (r)233233+ return r;234234+235235+ result += 4;236236+ buf += 4;237237+ *pos += 4;238238+ size -= 4;239239+ }240240+241241+ return result;242242+}243243+244244+static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf,245245+ size_t size, loff_t *pos)246246+{247247+ struct amdgpu_device *adev = file_inode(f)->i_private;248248+ ssize_t result = 0;249249+ int r;250250+251251+ if (size & 0x3 || *pos & 0x3)252252+ return -EINVAL;253253+254254+ while (size) {255255+ uint32_t value;256256+257257+ r = get_user(value, (uint32_t *)buf);258258+ if (r)259259+ return r;260260+261261+ WREG32_PCIE(*pos >> 2, value);262262+263263+ result += 4;264264+ buf += 4;265265+ *pos += 4;266266+ size -= 4;267267+ }268268+269269+ return result;270270+}271271+272272+static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,273273+ size_t size, loff_t *pos)274274+{275275+ struct amdgpu_device *adev = file_inode(f)->i_private;276276+ ssize_t result = 0;277277+ int r;278278+279279+ if (size & 0x3 || *pos & 0x3)280280+ return -EINVAL;281281+282282+ while (size) {283283+ uint32_t value;284284+285285+ value = RREG32_DIDT(*pos >> 2);286286+ r = put_user(value, (uint32_t *)buf);287287+ if (r)288288+ return r;289289+290290+ result += 4;291291+ buf += 4;292292+ *pos += 4;293293+ size -= 4;294294+ }295295+296296+ return result;297297+}298298+299299+static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf,300300+ size_t size, loff_t *pos)301301+{302302+ struct amdgpu_device *adev = file_inode(f)->i_private;303303+ ssize_t result = 0;304304+ int r;305305+306306+ if (size & 0x3 || *pos & 0x3)307307+ return -EINVAL;308308+309309+ while (size) {310310+ uint32_t value;311311+312312+ r = get_user(value, (uint32_t *)buf);313313+ if (r)314314+ return r;315315+316316+ WREG32_DIDT(*pos >> 2, value);317317+318318+ result += 4;319319+ buf += 4;320320+ *pos += 4;321321+ size -= 4;322322+ }323323+324324+ return result;325325+}326326+327327+static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,328328+ size_t size, loff_t *pos)329329+{330330+ struct amdgpu_device *adev = file_inode(f)->i_private;331331+ ssize_t result = 0;332332+ int r;333333+334334+ if (size & 0x3 || *pos & 0x3)335335+ return -EINVAL;336336+337337+ while (size) {338338+ uint32_t value;339339+340340+ value = RREG32_SMC(*pos);341341+ r = put_user(value, (uint32_t *)buf);342342+ if (r)343343+ return r;344344+345345+ result += 4;346346+ buf += 4;347347+ *pos += 4;348348+ size -= 4;349349+ }350350+351351+ return result;352352+}353353+354354+static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf,355355+ size_t size, loff_t *pos)356356+{357357+ struct amdgpu_device *adev = file_inode(f)->i_private;358358+ ssize_t result = 0;359359+ int r;360360+361361+ if (size & 0x3 || *pos & 0x3)362362+ return -EINVAL;363363+364364+ while (size) {365365+ uint32_t value;366366+367367+ r = get_user(value, (uint32_t *)buf);368368+ if (r)369369+ return r;370370+371371+ WREG32_SMC(*pos, value);372372+373373+ result += 4;374374+ buf += 4;375375+ *pos += 4;376376+ size -= 4;377377+ }378378+379379+ return result;380380+}381381+382382+static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,383383+ size_t size, loff_t *pos)384384+{385385+ struct amdgpu_device *adev = file_inode(f)->i_private;386386+ ssize_t result = 0;387387+ int r;388388+ uint32_t *config, no_regs = 0;389389+390390+ if (size & 0x3 || *pos & 0x3)391391+ return -EINVAL;392392+393393+ config = kmalloc_array(256, sizeof(*config), GFP_KERNEL);394394+ if (!config)395395+ return -ENOMEM;396396+397397+ /* version, increment each time something is added */398398+ config[no_regs++] = 3;399399+ config[no_regs++] = adev->gfx.config.max_shader_engines;400400+ config[no_regs++] = adev->gfx.config.max_tile_pipes;401401+ config[no_regs++] = adev->gfx.config.max_cu_per_sh;402402+ config[no_regs++] = adev->gfx.config.max_sh_per_se;403403+ config[no_regs++] = adev->gfx.config.max_backends_per_se;404404+ config[no_regs++] = adev->gfx.config.max_texture_channel_caches;405405+ config[no_regs++] = adev->gfx.config.max_gprs;406406+ config[no_regs++] = adev->gfx.config.max_gs_threads;407407+ config[no_regs++] = adev->gfx.config.max_hw_contexts;408408+ config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend;409409+ config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend;410410+ config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size;411411+ config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size;412412+ config[no_regs++] = adev->gfx.config.num_tile_pipes;413413+ config[no_regs++] = adev->gfx.config.backend_enable_mask;414414+ config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes;415415+ config[no_regs++] = adev->gfx.config.mem_row_size_in_kb;416416+ config[no_regs++] = adev->gfx.config.shader_engine_tile_size;417417+ config[no_regs++] = adev->gfx.config.num_gpus;418418+ config[no_regs++] = adev->gfx.config.multi_gpu_tile_size;419419+ config[no_regs++] = adev->gfx.config.mc_arb_ramcfg;420420+ config[no_regs++] = adev->gfx.config.gb_addr_config;421421+ config[no_regs++] = adev->gfx.config.num_rbs;422422+423423+ /* rev==1 */424424+ config[no_regs++] = adev->rev_id;425425+ config[no_regs++] = adev->pg_flags;426426+ config[no_regs++] = adev->cg_flags;427427+428428+ /* rev==2 */429429+ config[no_regs++] = adev->family;430430+ config[no_regs++] = adev->external_rev_id;431431+432432+ /* rev==3 */433433+ config[no_regs++] = adev->pdev->device;434434+ config[no_regs++] = adev->pdev->revision;435435+ config[no_regs++] = adev->pdev->subsystem_device;436436+ config[no_regs++] = adev->pdev->subsystem_vendor;437437+438438+ while (size && (*pos < no_regs * 4)) {439439+ uint32_t value;440440+441441+ value = config[*pos >> 2];442442+ r = put_user(value, (uint32_t *)buf);443443+ if (r) {444444+ kfree(config);445445+ return r;446446+ }447447+448448+ result += 4;449449+ buf += 4;450450+ *pos += 4;451451+ size -= 4;452452+ }453453+454454+ kfree(config);455455+ return result;456456+}457457+458458+static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,459459+ size_t size, loff_t *pos)460460+{461461+ struct amdgpu_device *adev = file_inode(f)->i_private;462462+ int idx, x, outsize, r, valuesize;463463+ uint32_t values[16];464464+465465+ if (size & 3 || *pos & 0x3)466466+ return -EINVAL;467467+468468+ if (amdgpu_dpm == 0)469469+ return -EINVAL;470470+471471+ /* convert offset to sensor number */472472+ idx = *pos >> 2;473473+474474+ valuesize = sizeof(values);475475+ if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor)476476+ r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);477477+ else478478+ return -EINVAL;479479+480480+ if (size > valuesize)481481+ return -EINVAL;482482+483483+ outsize = 0;484484+ x = 0;485485+ if (!r) {486486+ while (size) {487487+ r = put_user(values[x++], (int32_t *)buf);488488+ buf += 4;489489+ size -= 4;490490+ outsize += 4;491491+ }492492+ }493493+494494+ return !r ? outsize : r;495495+}496496+497497+static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,498498+ size_t size, loff_t *pos)499499+{500500+ struct amdgpu_device *adev = f->f_inode->i_private;501501+ int r, x;502502+ ssize_t result=0;503503+ uint32_t offset, se, sh, cu, wave, simd, data[32];504504+505505+ if (size & 3 || *pos & 3)506506+ return -EINVAL;507507+508508+ /* decode offset */509509+ offset = (*pos & GENMASK_ULL(6, 0));510510+ se = (*pos & GENMASK_ULL(14, 7)) >> 7;511511+ sh = (*pos & GENMASK_ULL(22, 15)) >> 15;512512+ cu = (*pos & GENMASK_ULL(30, 23)) >> 23;513513+ wave = (*pos & GENMASK_ULL(36, 31)) >> 31;514514+ simd = (*pos & GENMASK_ULL(44, 37)) >> 37;515515+516516+ /* switch to the specific se/sh/cu */517517+ mutex_lock(&adev->grbm_idx_mutex);518518+ amdgpu_gfx_select_se_sh(adev, se, sh, cu);519519+520520+ x = 0;521521+ if (adev->gfx.funcs->read_wave_data)522522+ adev->gfx.funcs->read_wave_data(adev, simd, wave, data, &x);523523+524524+ amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);525525+ mutex_unlock(&adev->grbm_idx_mutex);526526+527527+ if (!x)528528+ return -EINVAL;529529+530530+ while (size && (offset < x * 4)) {531531+ uint32_t value;532532+533533+ value = data[offset >> 2];534534+ r = put_user(value, (uint32_t *)buf);535535+ if (r)536536+ return r;537537+538538+ result += 4;539539+ buf += 4;540540+ offset += 4;541541+ size -= 4;542542+ }543543+544544+ return result;545545+}546546+547547+static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,548548+ size_t size, loff_t *pos)549549+{550550+ struct amdgpu_device *adev = f->f_inode->i_private;551551+ int r;552552+ ssize_t result = 0;553553+ uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data;554554+555555+ if (size & 3 || *pos & 3)556556+ return -EINVAL;557557+558558+ /* decode offset */559559+ offset = *pos & GENMASK_ULL(11, 0);560560+ se = (*pos & GENMASK_ULL(19, 12)) >> 12;561561+ sh = (*pos & GENMASK_ULL(27, 20)) >> 20;562562+ cu = (*pos & GENMASK_ULL(35, 28)) >> 28;563563+ wave = (*pos & GENMASK_ULL(43, 36)) >> 36;564564+ simd = (*pos & GENMASK_ULL(51, 44)) >> 44;565565+ thread = (*pos & GENMASK_ULL(59, 52)) >> 52;566566+ bank = (*pos & GENMASK_ULL(61, 60)) >> 60;567567+568568+ data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL);569569+ if (!data)570570+ return -ENOMEM;571571+572572+ /* switch to the specific se/sh/cu */573573+ mutex_lock(&adev->grbm_idx_mutex);574574+ amdgpu_gfx_select_se_sh(adev, se, sh, cu);575575+576576+ if (bank == 0) {577577+ if (adev->gfx.funcs->read_wave_vgprs)578578+ adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data);579579+ } else {580580+ if (adev->gfx.funcs->read_wave_sgprs)581581+ adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data);582582+ }583583+584584+ amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);585585+ mutex_unlock(&adev->grbm_idx_mutex);586586+587587+ while (size) {588588+ uint32_t value;589589+590590+ value = data[offset++];591591+ r = put_user(value, (uint32_t *)buf);592592+ if (r) {593593+ result = r;594594+ goto err;595595+ }596596+597597+ result += 4;598598+ buf += 4;599599+ size -= 4;600600+ }601601+602602+err:603603+ kfree(data);604604+ return result;605605+}606606+607607+static const struct file_operations amdgpu_debugfs_regs_fops = {608608+ .owner = THIS_MODULE,609609+ .read = amdgpu_debugfs_regs_read,610610+ .write = amdgpu_debugfs_regs_write,611611+ .llseek = default_llseek612612+};613613+static const struct file_operations amdgpu_debugfs_regs_didt_fops = {614614+ .owner = THIS_MODULE,615615+ .read = amdgpu_debugfs_regs_didt_read,616616+ .write = amdgpu_debugfs_regs_didt_write,617617+ .llseek = default_llseek618618+};619619+static const struct file_operations amdgpu_debugfs_regs_pcie_fops = {620620+ .owner = THIS_MODULE,621621+ .read = amdgpu_debugfs_regs_pcie_read,622622+ .write = amdgpu_debugfs_regs_pcie_write,623623+ .llseek = default_llseek624624+};625625+static const struct file_operations amdgpu_debugfs_regs_smc_fops = {626626+ .owner = THIS_MODULE,627627+ .read = amdgpu_debugfs_regs_smc_read,628628+ .write = amdgpu_debugfs_regs_smc_write,629629+ .llseek = default_llseek630630+};631631+632632+static const struct file_operations amdgpu_debugfs_gca_config_fops = {633633+ .owner = THIS_MODULE,634634+ .read = amdgpu_debugfs_gca_config_read,635635+ .llseek = default_llseek636636+};637637+638638+static const struct file_operations amdgpu_debugfs_sensors_fops = {639639+ .owner = THIS_MODULE,640640+ .read = amdgpu_debugfs_sensor_read,641641+ .llseek = default_llseek642642+};643643+644644+static const struct file_operations amdgpu_debugfs_wave_fops = {645645+ .owner = THIS_MODULE,646646+ .read = amdgpu_debugfs_wave_read,647647+ .llseek = default_llseek648648+};649649+static const struct file_operations amdgpu_debugfs_gpr_fops = {650650+ .owner = THIS_MODULE,651651+ .read = amdgpu_debugfs_gpr_read,652652+ .llseek = default_llseek653653+};654654+655655+static const struct file_operations *debugfs_regs[] = {656656+ &amdgpu_debugfs_regs_fops,657657+ &amdgpu_debugfs_regs_didt_fops,658658+ &amdgpu_debugfs_regs_pcie_fops,659659+ &amdgpu_debugfs_regs_smc_fops,660660+ &amdgpu_debugfs_gca_config_fops,661661+ &amdgpu_debugfs_sensors_fops,662662+ &amdgpu_debugfs_wave_fops,663663+ &amdgpu_debugfs_gpr_fops,664664+};665665+666666+static const char *debugfs_regs_names[] = {667667+ "amdgpu_regs",668668+ "amdgpu_regs_didt",669669+ "amdgpu_regs_pcie",670670+ "amdgpu_regs_smc",671671+ "amdgpu_gca_config",672672+ "amdgpu_sensors",673673+ "amdgpu_wave",674674+ "amdgpu_gpr",675675+};676676+677677+int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)678678+{679679+ struct drm_minor *minor = adev->ddev->primary;680680+ struct dentry *ent, *root = minor->debugfs_root;681681+ unsigned i, j;682682+683683+ for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {684684+ ent = debugfs_create_file(debugfs_regs_names[i],685685+ S_IFREG | S_IRUGO, root,686686+ adev, debugfs_regs[i]);687687+ if (IS_ERR(ent)) {688688+ for (j = 0; j < i; j++) {689689+ debugfs_remove(adev->debugfs_regs[i]);690690+ adev->debugfs_regs[i] = NULL;691691+ }692692+ return PTR_ERR(ent);693693+ }694694+695695+ if (!i)696696+ i_size_write(ent->d_inode, adev->rmmio_size);697697+ adev->debugfs_regs[i] = ent;698698+ }699699+700700+ return 0;701701+}702702+703703+void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev)704704+{705705+ unsigned i;706706+707707+ for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {708708+ if (adev->debugfs_regs[i]) {709709+ debugfs_remove(adev->debugfs_regs[i]);710710+ adev->debugfs_regs[i] = NULL;711711+ }712712+ }713713+}714714+715715+static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data)716716+{717717+ struct drm_info_node *node = (struct drm_info_node *) m->private;718718+ struct drm_device *dev = node->minor->dev;719719+ struct amdgpu_device *adev = dev->dev_private;720720+ int r = 0, i;721721+722722+ /* hold on the scheduler */723723+ for (i = 0; i < AMDGPU_MAX_RINGS; i++) {724724+ struct amdgpu_ring *ring = adev->rings[i];725725+726726+ if (!ring || !ring->sched.thread)727727+ continue;728728+ kthread_park(ring->sched.thread);729729+ }730730+731731+ seq_printf(m, "run ib test:\n");732732+ r = amdgpu_ib_ring_tests(adev);733733+ if (r)734734+ seq_printf(m, "ib ring tests failed (%d).\n", r);735735+ else736736+ seq_printf(m, "ib ring tests passed.\n");737737+738738+ /* go on the scheduler */739739+ for (i = 0; i < AMDGPU_MAX_RINGS; i++) {740740+ struct amdgpu_ring *ring = adev->rings[i];741741+742742+ if (!ring || !ring->sched.thread)743743+ continue;744744+ kthread_unpark(ring->sched.thread);745745+ }746746+747747+ return 0;748748+}749749+750750+static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data)751751+{752752+ struct drm_info_node *node = (struct drm_info_node *) m->private;753753+ struct drm_device *dev = node->minor->dev;754754+ struct amdgpu_device *adev = dev->dev_private;755755+756756+ seq_write(m, adev->bios, adev->bios_size);757757+ return 0;758758+}759759+760760+static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data)761761+{762762+ struct drm_info_node *node = (struct drm_info_node *)m->private;763763+ struct drm_device *dev = node->minor->dev;764764+ struct amdgpu_device *adev = dev->dev_private;765765+766766+ seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev));767767+ return 0;768768+}769769+770770+static const struct drm_info_list amdgpu_debugfs_list[] = {771771+ {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump},772772+ {"amdgpu_test_ib", &amdgpu_debugfs_test_ib},773773+ {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram}774774+};775775+776776+int amdgpu_debugfs_init(struct amdgpu_device *adev)777777+{778778+ return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list,779779+ ARRAY_SIZE(amdgpu_debugfs_list));780780+}781781+782782+#else783783+int amdgpu_debugfs_init(struct amdgpu_device *adev)784784+{785785+ return 0;786786+}787787+int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)788788+{789789+ return 0;790790+}791791+void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { }792792+#endif
+42
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h
···11+/*22+ * Copyright 2008 Advanced Micro Devices, Inc.33+ * Copyright 2008 Red Hat Inc.44+ * Copyright 2009 Jerome Glisse.55+ *66+ * Permission is hereby granted, free of charge, to any person obtaining a77+ * copy of this software and associated documentation files (the "Software"),88+ * to deal in the Software without restriction, including without limitation99+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,1010+ * and/or sell copies of the Software, and to permit persons to whom the1111+ * Software is furnished to do so, subject to the following conditions:1212+ *1313+ * The above copyright notice and this permission notice shall be included in1414+ * all copies or substantial portions of the Software.1515+ *1616+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR1717+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1818+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL1919+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR2020+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,2121+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR2222+ * OTHER DEALINGS IN THE SOFTWARE.2323+ *2424+ */2525+2626+/*2727+ * Debugfs2828+ */2929+struct amdgpu_debugfs {3030+ const struct drm_info_list *files;3131+ unsigned num_files;3232+};3333+3434+int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);3535+void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev);3636+int amdgpu_debugfs_init(struct amdgpu_device *adev);3737+int amdgpu_debugfs_add_files(struct amdgpu_device *adev,3838+ const struct drm_info_list *files,3939+ unsigned nfiles);4040+int amdgpu_debugfs_fence_init(struct amdgpu_device *adev);4141+int amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);4242+int amdgpu_debugfs_gem_init(struct amdgpu_device *adev);
+1-768
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
···2828#include <linux/kthread.h>2929#include <linux/console.h>3030#include <linux/slab.h>3131-#include <linux/debugfs.h>3231#include <drm/drmP.h>3332#include <drm/drm_crtc_helper.h>3433#include <drm/drm_atomic_helper.h>···6263MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");63646465#define AMDGPU_RESUME_MS 20006565-6666-static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);6767-static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev);6868-static int amdgpu_debugfs_init(struct amdgpu_device *adev);69667067static const char *amdgpu_asic_name[] = {7168 "TAHITI",···21662171 if (r)21672172 DRM_ERROR("registering pm debugfs failed (%d).\n", r);2168217321692169- r = amdgpu_gem_debugfs_init(adev);21742174+ r = amdgpu_debugfs_gem_init(adev);21702175 if (r)21712176 DRM_ERROR("registering gem debugfs failed (%d).\n", r);21722177···30153020 }30163021}3017302230183018-/*30193019- * Debugfs30203020- */30213021-int amdgpu_debugfs_add_files(struct amdgpu_device *adev,30223022- const struct drm_info_list *files,30233023- unsigned nfiles)30243024-{30253025- unsigned i;30263026-30273027- for (i = 0; i < adev->debugfs_count; i++) {30283028- if (adev->debugfs[i].files == files) {30293029- /* Already registered */30303030- return 0;30313031- }30323032- }30333033-30343034- i = adev->debugfs_count + 1;30353035- if (i > AMDGPU_DEBUGFS_MAX_COMPONENTS) {30363036- DRM_ERROR("Reached maximum number of debugfs components.\n");30373037- DRM_ERROR("Report so we increase "30383038- "AMDGPU_DEBUGFS_MAX_COMPONENTS.\n");30393039- return -EINVAL;30403040- }30413041- adev->debugfs[adev->debugfs_count].files = files;30423042- adev->debugfs[adev->debugfs_count].num_files = nfiles;30433043- adev->debugfs_count = i;30443044-#if defined(CONFIG_DEBUG_FS)30453045- drm_debugfs_create_files(files, nfiles,30463046- adev->ddev->primary->debugfs_root,30473047- adev->ddev->primary);30483048-#endif30493049- return 0;30503050-}30513051-30523052-#if defined(CONFIG_DEBUG_FS)30533053-30543054-static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,30553055- size_t size, loff_t *pos)30563056-{30573057- struct amdgpu_device *adev = file_inode(f)->i_private;30583058- ssize_t result = 0;30593059- int r;30603060- bool pm_pg_lock, use_bank;30613061- unsigned instance_bank, sh_bank, se_bank;30623062-30633063- if (size & 0x3 || *pos & 0x3)30643064- return -EINVAL;30653065-30663066- /* are we reading registers for which a PG lock is necessary? */30673067- pm_pg_lock = (*pos >> 23) & 1;30683068-30693069- if (*pos & (1ULL << 62)) {30703070- se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;30713071- sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;30723072- instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;30733073-30743074- if (se_bank == 0x3FF)30753075- se_bank = 0xFFFFFFFF;30763076- if (sh_bank == 0x3FF)30773077- sh_bank = 0xFFFFFFFF;30783078- if (instance_bank == 0x3FF)30793079- instance_bank = 0xFFFFFFFF;30803080- use_bank = 1;30813081- } else {30823082- use_bank = 0;30833083- }30843084-30853085- *pos &= (1UL << 22) - 1;30863086-30873087- if (use_bank) {30883088- if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||30893089- (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))30903090- return -EINVAL;30913091- mutex_lock(&adev->grbm_idx_mutex);30923092- amdgpu_gfx_select_se_sh(adev, se_bank,30933093- sh_bank, instance_bank);30943094- }30953095-30963096- if (pm_pg_lock)30973097- mutex_lock(&adev->pm.mutex);30983098-30993099- while (size) {31003100- uint32_t value;31013101-31023102- if (*pos > adev->rmmio_size)31033103- goto end;31043104-31053105- value = RREG32(*pos >> 2);31063106- r = put_user(value, (uint32_t *)buf);31073107- if (r) {31083108- result = r;31093109- goto end;31103110- }31113111-31123112- result += 4;31133113- buf += 4;31143114- *pos += 4;31153115- size -= 4;31163116- }31173117-31183118-end:31193119- if (use_bank) {31203120- amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);31213121- mutex_unlock(&adev->grbm_idx_mutex);31223122- }31233123-31243124- if (pm_pg_lock)31253125- mutex_unlock(&adev->pm.mutex);31263126-31273127- return result;31283128-}31293129-31303130-static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,31313131- size_t size, loff_t *pos)31323132-{31333133- struct amdgpu_device *adev = file_inode(f)->i_private;31343134- ssize_t result = 0;31353135- int r;31363136- bool pm_pg_lock, use_bank;31373137- unsigned instance_bank, sh_bank, se_bank;31383138-31393139- if (size & 0x3 || *pos & 0x3)31403140- return -EINVAL;31413141-31423142- /* are we reading registers for which a PG lock is necessary? */31433143- pm_pg_lock = (*pos >> 23) & 1;31443144-31453145- if (*pos & (1ULL << 62)) {31463146- se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;31473147- sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;31483148- instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;31493149-31503150- if (se_bank == 0x3FF)31513151- se_bank = 0xFFFFFFFF;31523152- if (sh_bank == 0x3FF)31533153- sh_bank = 0xFFFFFFFF;31543154- if (instance_bank == 0x3FF)31553155- instance_bank = 0xFFFFFFFF;31563156- use_bank = 1;31573157- } else {31583158- use_bank = 0;31593159- }31603160-31613161- *pos &= (1UL << 22) - 1;31623162-31633163- if (use_bank) {31643164- if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||31653165- (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))31663166- return -EINVAL;31673167- mutex_lock(&adev->grbm_idx_mutex);31683168- amdgpu_gfx_select_se_sh(adev, se_bank,31693169- sh_bank, instance_bank);31703170- }31713171-31723172- if (pm_pg_lock)31733173- mutex_lock(&adev->pm.mutex);31743174-31753175- while (size) {31763176- uint32_t value;31773177-31783178- if (*pos > adev->rmmio_size)31793179- return result;31803180-31813181- r = get_user(value, (uint32_t *)buf);31823182- if (r)31833183- return r;31843184-31853185- WREG32(*pos >> 2, value);31863186-31873187- result += 4;31883188- buf += 4;31893189- *pos += 4;31903190- size -= 4;31913191- }31923192-31933193- if (use_bank) {31943194- amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);31953195- mutex_unlock(&adev->grbm_idx_mutex);31963196- }31973197-31983198- if (pm_pg_lock)31993199- mutex_unlock(&adev->pm.mutex);32003200-32013201- return result;32023202-}32033203-32043204-static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,32053205- size_t size, loff_t *pos)32063206-{32073207- struct amdgpu_device *adev = file_inode(f)->i_private;32083208- ssize_t result = 0;32093209- int r;32103210-32113211- if (size & 0x3 || *pos & 0x3)32123212- return -EINVAL;32133213-32143214- while (size) {32153215- uint32_t value;32163216-32173217- value = RREG32_PCIE(*pos >> 2);32183218- r = put_user(value, (uint32_t *)buf);32193219- if (r)32203220- return r;32213221-32223222- result += 4;32233223- buf += 4;32243224- *pos += 4;32253225- size -= 4;32263226- }32273227-32283228- return result;32293229-}32303230-32313231-static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf,32323232- size_t size, loff_t *pos)32333233-{32343234- struct amdgpu_device *adev = file_inode(f)->i_private;32353235- ssize_t result = 0;32363236- int r;32373237-32383238- if (size & 0x3 || *pos & 0x3)32393239- return -EINVAL;32403240-32413241- while (size) {32423242- uint32_t value;32433243-32443244- r = get_user(value, (uint32_t *)buf);32453245- if (r)32463246- return r;32473247-32483248- WREG32_PCIE(*pos >> 2, value);32493249-32503250- result += 4;32513251- buf += 4;32523252- *pos += 4;32533253- size -= 4;32543254- }32553255-32563256- return result;32573257-}32583258-32593259-static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,32603260- size_t size, loff_t *pos)32613261-{32623262- struct amdgpu_device *adev = file_inode(f)->i_private;32633263- ssize_t result = 0;32643264- int r;32653265-32663266- if (size & 0x3 || *pos & 0x3)32673267- return -EINVAL;32683268-32693269- while (size) {32703270- uint32_t value;32713271-32723272- value = RREG32_DIDT(*pos >> 2);32733273- r = put_user(value, (uint32_t *)buf);32743274- if (r)32753275- return r;32763276-32773277- result += 4;32783278- buf += 4;32793279- *pos += 4;32803280- size -= 4;32813281- }32823282-32833283- return result;32843284-}32853285-32863286-static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf,32873287- size_t size, loff_t *pos)32883288-{32893289- struct amdgpu_device *adev = file_inode(f)->i_private;32903290- ssize_t result = 0;32913291- int r;32923292-32933293- if (size & 0x3 || *pos & 0x3)32943294- return -EINVAL;32953295-32963296- while (size) {32973297- uint32_t value;32983298-32993299- r = get_user(value, (uint32_t *)buf);33003300- if (r)33013301- return r;33023302-33033303- WREG32_DIDT(*pos >> 2, value);33043304-33053305- result += 4;33063306- buf += 4;33073307- *pos += 4;33083308- size -= 4;33093309- }33103310-33113311- return result;33123312-}33133313-33143314-static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,33153315- size_t size, loff_t *pos)33163316-{33173317- struct amdgpu_device *adev = file_inode(f)->i_private;33183318- ssize_t result = 0;33193319- int r;33203320-33213321- if (size & 0x3 || *pos & 0x3)33223322- return -EINVAL;33233323-33243324- while (size) {33253325- uint32_t value;33263326-33273327- value = RREG32_SMC(*pos);33283328- r = put_user(value, (uint32_t *)buf);33293329- if (r)33303330- return r;33313331-33323332- result += 4;33333333- buf += 4;33343334- *pos += 4;33353335- size -= 4;33363336- }33373337-33383338- return result;33393339-}33403340-33413341-static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf,33423342- size_t size, loff_t *pos)33433343-{33443344- struct amdgpu_device *adev = file_inode(f)->i_private;33453345- ssize_t result = 0;33463346- int r;33473347-33483348- if (size & 0x3 || *pos & 0x3)33493349- return -EINVAL;33503350-33513351- while (size) {33523352- uint32_t value;33533353-33543354- r = get_user(value, (uint32_t *)buf);33553355- if (r)33563356- return r;33573357-33583358- WREG32_SMC(*pos, value);33593359-33603360- result += 4;33613361- buf += 4;33623362- *pos += 4;33633363- size -= 4;33643364- }33653365-33663366- return result;33673367-}33683368-33693369-static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,33703370- size_t size, loff_t *pos)33713371-{33723372- struct amdgpu_device *adev = file_inode(f)->i_private;33733373- ssize_t result = 0;33743374- int r;33753375- uint32_t *config, no_regs = 0;33763376-33773377- if (size & 0x3 || *pos & 0x3)33783378- return -EINVAL;33793379-33803380- config = kmalloc_array(256, sizeof(*config), GFP_KERNEL);33813381- if (!config)33823382- return -ENOMEM;33833383-33843384- /* version, increment each time something is added */33853385- config[no_regs++] = 3;33863386- config[no_regs++] = adev->gfx.config.max_shader_engines;33873387- config[no_regs++] = adev->gfx.config.max_tile_pipes;33883388- config[no_regs++] = adev->gfx.config.max_cu_per_sh;33893389- config[no_regs++] = adev->gfx.config.max_sh_per_se;33903390- config[no_regs++] = adev->gfx.config.max_backends_per_se;33913391- config[no_regs++] = adev->gfx.config.max_texture_channel_caches;33923392- config[no_regs++] = adev->gfx.config.max_gprs;33933393- config[no_regs++] = adev->gfx.config.max_gs_threads;33943394- config[no_regs++] = adev->gfx.config.max_hw_contexts;33953395- config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend;33963396- config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend;33973397- config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size;33983398- config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size;33993399- config[no_regs++] = adev->gfx.config.num_tile_pipes;34003400- config[no_regs++] = adev->gfx.config.backend_enable_mask;34013401- config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes;34023402- config[no_regs++] = adev->gfx.config.mem_row_size_in_kb;34033403- config[no_regs++] = adev->gfx.config.shader_engine_tile_size;34043404- config[no_regs++] = adev->gfx.config.num_gpus;34053405- config[no_regs++] = adev->gfx.config.multi_gpu_tile_size;34063406- config[no_regs++] = adev->gfx.config.mc_arb_ramcfg;34073407- config[no_regs++] = adev->gfx.config.gb_addr_config;34083408- config[no_regs++] = adev->gfx.config.num_rbs;34093409-34103410- /* rev==1 */34113411- config[no_regs++] = adev->rev_id;34123412- config[no_regs++] = adev->pg_flags;34133413- config[no_regs++] = adev->cg_flags;34143414-34153415- /* rev==2 */34163416- config[no_regs++] = adev->family;34173417- config[no_regs++] = adev->external_rev_id;34183418-34193419- /* rev==3 */34203420- config[no_regs++] = adev->pdev->device;34213421- config[no_regs++] = adev->pdev->revision;34223422- config[no_regs++] = adev->pdev->subsystem_device;34233423- config[no_regs++] = adev->pdev->subsystem_vendor;34243424-34253425- while (size && (*pos < no_regs * 4)) {34263426- uint32_t value;34273427-34283428- value = config[*pos >> 2];34293429- r = put_user(value, (uint32_t *)buf);34303430- if (r) {34313431- kfree(config);34323432- return r;34333433- }34343434-34353435- result += 4;34363436- buf += 4;34373437- *pos += 4;34383438- size -= 4;34393439- }34403440-34413441- kfree(config);34423442- return result;34433443-}34443444-34453445-static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,34463446- size_t size, loff_t *pos)34473447-{34483448- struct amdgpu_device *adev = file_inode(f)->i_private;34493449- int idx, x, outsize, r, valuesize;34503450- uint32_t values[16];34513451-34523452- if (size & 3 || *pos & 0x3)34533453- return -EINVAL;34543454-34553455- if (amdgpu_dpm == 0)34563456- return -EINVAL;34573457-34583458- /* convert offset to sensor number */34593459- idx = *pos >> 2;34603460-34613461- valuesize = sizeof(values);34623462- if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor)34633463- r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);34643464- else34653465- return -EINVAL;34663466-34673467- if (size > valuesize)34683468- return -EINVAL;34693469-34703470- outsize = 0;34713471- x = 0;34723472- if (!r) {34733473- while (size) {34743474- r = put_user(values[x++], (int32_t *)buf);34753475- buf += 4;34763476- size -= 4;34773477- outsize += 4;34783478- }34793479- }34803480-34813481- return !r ? outsize : r;34823482-}34833483-34843484-static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,34853485- size_t size, loff_t *pos)34863486-{34873487- struct amdgpu_device *adev = f->f_inode->i_private;34883488- int r, x;34893489- ssize_t result=0;34903490- uint32_t offset, se, sh, cu, wave, simd, data[32];34913491-34923492- if (size & 3 || *pos & 3)34933493- return -EINVAL;34943494-34953495- /* decode offset */34963496- offset = (*pos & GENMASK_ULL(6, 0));34973497- se = (*pos & GENMASK_ULL(14, 7)) >> 7;34983498- sh = (*pos & GENMASK_ULL(22, 15)) >> 15;34993499- cu = (*pos & GENMASK_ULL(30, 23)) >> 23;35003500- wave = (*pos & GENMASK_ULL(36, 31)) >> 31;35013501- simd = (*pos & GENMASK_ULL(44, 37)) >> 37;35023502-35033503- /* switch to the specific se/sh/cu */35043504- mutex_lock(&adev->grbm_idx_mutex);35053505- amdgpu_gfx_select_se_sh(adev, se, sh, cu);35063506-35073507- x = 0;35083508- if (adev->gfx.funcs->read_wave_data)35093509- adev->gfx.funcs->read_wave_data(adev, simd, wave, data, &x);35103510-35113511- amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);35123512- mutex_unlock(&adev->grbm_idx_mutex);35133513-35143514- if (!x)35153515- return -EINVAL;35163516-35173517- while (size && (offset < x * 4)) {35183518- uint32_t value;35193519-35203520- value = data[offset >> 2];35213521- r = put_user(value, (uint32_t *)buf);35223522- if (r)35233523- return r;35243524-35253525- result += 4;35263526- buf += 4;35273527- offset += 4;35283528- size -= 4;35293529- }35303530-35313531- return result;35323532-}35333533-35343534-static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,35353535- size_t size, loff_t *pos)35363536-{35373537- struct amdgpu_device *adev = f->f_inode->i_private;35383538- int r;35393539- ssize_t result = 0;35403540- uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data;35413541-35423542- if (size & 3 || *pos & 3)35433543- return -EINVAL;35443544-35453545- /* decode offset */35463546- offset = *pos & GENMASK_ULL(11, 0);35473547- se = (*pos & GENMASK_ULL(19, 12)) >> 12;35483548- sh = (*pos & GENMASK_ULL(27, 20)) >> 20;35493549- cu = (*pos & GENMASK_ULL(35, 28)) >> 28;35503550- wave = (*pos & GENMASK_ULL(43, 36)) >> 36;35513551- simd = (*pos & GENMASK_ULL(51, 44)) >> 44;35523552- thread = (*pos & GENMASK_ULL(59, 52)) >> 52;35533553- bank = (*pos & GENMASK_ULL(61, 60)) >> 60;35543554-35553555- data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL);35563556- if (!data)35573557- return -ENOMEM;35583558-35593559- /* switch to the specific se/sh/cu */35603560- mutex_lock(&adev->grbm_idx_mutex);35613561- amdgpu_gfx_select_se_sh(adev, se, sh, cu);35623562-35633563- if (bank == 0) {35643564- if (adev->gfx.funcs->read_wave_vgprs)35653565- adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data);35663566- } else {35673567- if (adev->gfx.funcs->read_wave_sgprs)35683568- adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data);35693569- }35703570-35713571- amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);35723572- mutex_unlock(&adev->grbm_idx_mutex);35733573-35743574- while (size) {35753575- uint32_t value;35763576-35773577- value = data[offset++];35783578- r = put_user(value, (uint32_t *)buf);35793579- if (r) {35803580- result = r;35813581- goto err;35823582- }35833583-35843584- result += 4;35853585- buf += 4;35863586- size -= 4;35873587- }35883588-35893589-err:35903590- kfree(data);35913591- return result;35923592-}35933593-35943594-static const struct file_operations amdgpu_debugfs_regs_fops = {35953595- .owner = THIS_MODULE,35963596- .read = amdgpu_debugfs_regs_read,35973597- .write = amdgpu_debugfs_regs_write,35983598- .llseek = default_llseek35993599-};36003600-static const struct file_operations amdgpu_debugfs_regs_didt_fops = {36013601- .owner = THIS_MODULE,36023602- .read = amdgpu_debugfs_regs_didt_read,36033603- .write = amdgpu_debugfs_regs_didt_write,36043604- .llseek = default_llseek36053605-};36063606-static const struct file_operations amdgpu_debugfs_regs_pcie_fops = {36073607- .owner = THIS_MODULE,36083608- .read = amdgpu_debugfs_regs_pcie_read,36093609- .write = amdgpu_debugfs_regs_pcie_write,36103610- .llseek = default_llseek36113611-};36123612-static const struct file_operations amdgpu_debugfs_regs_smc_fops = {36133613- .owner = THIS_MODULE,36143614- .read = amdgpu_debugfs_regs_smc_read,36153615- .write = amdgpu_debugfs_regs_smc_write,36163616- .llseek = default_llseek36173617-};36183618-36193619-static const struct file_operations amdgpu_debugfs_gca_config_fops = {36203620- .owner = THIS_MODULE,36213621- .read = amdgpu_debugfs_gca_config_read,36223622- .llseek = default_llseek36233623-};36243624-36253625-static const struct file_operations amdgpu_debugfs_sensors_fops = {36263626- .owner = THIS_MODULE,36273627- .read = amdgpu_debugfs_sensor_read,36283628- .llseek = default_llseek36293629-};36303630-36313631-static const struct file_operations amdgpu_debugfs_wave_fops = {36323632- .owner = THIS_MODULE,36333633- .read = amdgpu_debugfs_wave_read,36343634- .llseek = default_llseek36353635-};36363636-static const struct file_operations amdgpu_debugfs_gpr_fops = {36373637- .owner = THIS_MODULE,36383638- .read = amdgpu_debugfs_gpr_read,36393639- .llseek = default_llseek36403640-};36413641-36423642-static const struct file_operations *debugfs_regs[] = {36433643- &amdgpu_debugfs_regs_fops,36443644- &amdgpu_debugfs_regs_didt_fops,36453645- &amdgpu_debugfs_regs_pcie_fops,36463646- &amdgpu_debugfs_regs_smc_fops,36473647- &amdgpu_debugfs_gca_config_fops,36483648- &amdgpu_debugfs_sensors_fops,36493649- &amdgpu_debugfs_wave_fops,36503650- &amdgpu_debugfs_gpr_fops,36513651-};36523652-36533653-static const char *debugfs_regs_names[] = {36543654- "amdgpu_regs",36553655- "amdgpu_regs_didt",36563656- "amdgpu_regs_pcie",36573657- "amdgpu_regs_smc",36583658- "amdgpu_gca_config",36593659- "amdgpu_sensors",36603660- "amdgpu_wave",36613661- "amdgpu_gpr",36623662-};36633663-36643664-static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)36653665-{36663666- struct drm_minor *minor = adev->ddev->primary;36673667- struct dentry *ent, *root = minor->debugfs_root;36683668- unsigned i, j;36693669-36703670- for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {36713671- ent = debugfs_create_file(debugfs_regs_names[i],36723672- S_IFREG | S_IRUGO, root,36733673- adev, debugfs_regs[i]);36743674- if (IS_ERR(ent)) {36753675- for (j = 0; j < i; j++) {36763676- debugfs_remove(adev->debugfs_regs[i]);36773677- adev->debugfs_regs[i] = NULL;36783678- }36793679- return PTR_ERR(ent);36803680- }36813681-36823682- if (!i)36833683- i_size_write(ent->d_inode, adev->rmmio_size);36843684- adev->debugfs_regs[i] = ent;36853685- }36863686-36873687- return 0;36883688-}36893689-36903690-static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev)36913691-{36923692- unsigned i;36933693-36943694- for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {36953695- if (adev->debugfs_regs[i]) {36963696- debugfs_remove(adev->debugfs_regs[i]);36973697- adev->debugfs_regs[i] = NULL;36983698- }36993699- }37003700-}37013701-37023702-static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data)37033703-{37043704- struct drm_info_node *node = (struct drm_info_node *) m->private;37053705- struct drm_device *dev = node->minor->dev;37063706- struct amdgpu_device *adev = dev->dev_private;37073707- int r = 0, i;37083708-37093709- /* hold on the scheduler */37103710- for (i = 0; i < AMDGPU_MAX_RINGS; i++) {37113711- struct amdgpu_ring *ring = adev->rings[i];37123712-37133713- if (!ring || !ring->sched.thread)37143714- continue;37153715- kthread_park(ring->sched.thread);37163716- }37173717-37183718- seq_printf(m, "run ib test:\n");37193719- r = amdgpu_ib_ring_tests(adev);37203720- if (r)37213721- seq_printf(m, "ib ring tests failed (%d).\n", r);37223722- else37233723- seq_printf(m, "ib ring tests passed.\n");37243724-37253725- /* go on the scheduler */37263726- for (i = 0; i < AMDGPU_MAX_RINGS; i++) {37273727- struct amdgpu_ring *ring = adev->rings[i];37283728-37293729- if (!ring || !ring->sched.thread)37303730- continue;37313731- kthread_unpark(ring->sched.thread);37323732- }37333733-37343734- return 0;37353735-}37363736-37373737-static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data)37383738-{37393739- struct drm_info_node *node = (struct drm_info_node *) m->private;37403740- struct drm_device *dev = node->minor->dev;37413741- struct amdgpu_device *adev = dev->dev_private;37423742-37433743- seq_write(m, adev->bios, adev->bios_size);37443744- return 0;37453745-}37463746-37473747-static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data)37483748-{37493749- struct drm_info_node *node = (struct drm_info_node *)m->private;37503750- struct drm_device *dev = node->minor->dev;37513751- struct amdgpu_device *adev = dev->dev_private;37523752-37533753- seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev));37543754- return 0;37553755-}37563756-37573757-static const struct drm_info_list amdgpu_debugfs_list[] = {37583758- {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump},37593759- {"amdgpu_test_ib", &amdgpu_debugfs_test_ib},37603760- {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram}37613761-};37623762-37633763-static int amdgpu_debugfs_init(struct amdgpu_device *adev)37643764-{37653765- return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list,37663766- ARRAY_SIZE(amdgpu_debugfs_list));37673767-}37683768-37693769-#else37703770-static int amdgpu_debugfs_init(struct amdgpu_device *adev)37713771-{37723772- return 0;37733773-}37743774-static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)37753775-{37763776- return 0;37773777-}37783778-static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { }37793779-#endif