diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2017-12-14 15:23:14 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-12-18 10:59:01 -0500 |
commit | 75758255dc0fae76a845fd5185cfcdf60990cc99 (patch) | |
tree | f1dedc5ebce0d3043666a0f70bb08b90c35f5052 /drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |
parent | cdd61df614851d18b8ee72f0615202bef67f5b91 (diff) |
drm/amdgpu: move debugfs functions to their own file
amdgpu_device.c was getting pretty cluttered.
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 769 |
1 files changed, 1 insertions, 768 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 3beea322bc12..ec078a9a5de8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/kthread.h> | 28 | #include <linux/kthread.h> |
29 | #include <linux/console.h> | 29 | #include <linux/console.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/debugfs.h> | ||
32 | #include <drm/drmP.h> | 31 | #include <drm/drmP.h> |
33 | #include <drm/drm_crtc_helper.h> | 32 | #include <drm/drm_crtc_helper.h> |
34 | #include <drm/drm_atomic_helper.h> | 33 | #include <drm/drm_atomic_helper.h> |
@@ -64,10 +63,6 @@ MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); | |||
64 | 63 | ||
65 | #define AMDGPU_RESUME_MS 2000 | 64 | #define AMDGPU_RESUME_MS 2000 |
66 | 65 | ||
67 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); | ||
68 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); | ||
69 | static int amdgpu_debugfs_init(struct amdgpu_device *adev); | ||
70 | |||
71 | static const char *amdgpu_asic_name[] = { | 66 | static const char *amdgpu_asic_name[] = { |
72 | "TAHITI", | 67 | "TAHITI", |
73 | "PITCAIRN", | 68 | "PITCAIRN", |
@@ -2171,7 +2166,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
2171 | if (r) | 2166 | if (r) |
2172 | DRM_ERROR("registering pm debugfs failed (%d).\n", r); | 2167 | DRM_ERROR("registering pm debugfs failed (%d).\n", r); |
2173 | 2168 | ||
2174 | r = amdgpu_gem_debugfs_init(adev); | 2169 | r = amdgpu_debugfs_gem_init(adev); |
2175 | if (r) | 2170 | if (r) |
2176 | DRM_ERROR("registering gem debugfs failed (%d).\n", r); | 2171 | DRM_ERROR("registering gem debugfs failed (%d).\n", r); |
2177 | 2172 | ||
@@ -3020,765 +3015,3 @@ void amdgpu_get_pcie_info(struct amdgpu_device *adev) | |||
3020 | } | 3015 | } |
3021 | } | 3016 | } |
3022 | 3017 | ||
3023 | /* | ||
3024 | * Debugfs | ||
3025 | */ | ||
3026 | int amdgpu_debugfs_add_files(struct amdgpu_device *adev, | ||
3027 | const struct drm_info_list *files, | ||
3028 | unsigned nfiles) | ||
3029 | { | ||
3030 | unsigned i; | ||
3031 | |||
3032 | for (i = 0; i < adev->debugfs_count; i++) { | ||
3033 | if (adev->debugfs[i].files == files) { | ||
3034 | /* Already registered */ | ||
3035 | return 0; | ||
3036 | } | ||
3037 | } | ||
3038 | |||
3039 | i = adev->debugfs_count + 1; | ||
3040 | if (i > AMDGPU_DEBUGFS_MAX_COMPONENTS) { | ||
3041 | DRM_ERROR("Reached maximum number of debugfs components.\n"); | ||
3042 | DRM_ERROR("Report so we increase " | ||
3043 | "AMDGPU_DEBUGFS_MAX_COMPONENTS.\n"); | ||
3044 | return -EINVAL; | ||
3045 | } | ||
3046 | adev->debugfs[adev->debugfs_count].files = files; | ||
3047 | adev->debugfs[adev->debugfs_count].num_files = nfiles; | ||
3048 | adev->debugfs_count = i; | ||
3049 | #if defined(CONFIG_DEBUG_FS) | ||
3050 | drm_debugfs_create_files(files, nfiles, | ||
3051 | adev->ddev->primary->debugfs_root, | ||
3052 | adev->ddev->primary); | ||
3053 | #endif | ||
3054 | return 0; | ||
3055 | } | ||
3056 | |||
3057 | #if defined(CONFIG_DEBUG_FS) | ||
3058 | |||
3059 | static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | ||
3060 | size_t size, loff_t *pos) | ||
3061 | { | ||
3062 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3063 | ssize_t result = 0; | ||
3064 | int r; | ||
3065 | bool pm_pg_lock, use_bank; | ||
3066 | unsigned instance_bank, sh_bank, se_bank; | ||
3067 | |||
3068 | if (size & 0x3 || *pos & 0x3) | ||
3069 | return -EINVAL; | ||
3070 | |||
3071 | /* are we reading registers for which a PG lock is necessary? */ | ||
3072 | pm_pg_lock = (*pos >> 23) & 1; | ||
3073 | |||
3074 | if (*pos & (1ULL << 62)) { | ||
3075 | se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24; | ||
3076 | sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34; | ||
3077 | instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44; | ||
3078 | |||
3079 | if (se_bank == 0x3FF) | ||
3080 | se_bank = 0xFFFFFFFF; | ||
3081 | if (sh_bank == 0x3FF) | ||
3082 | sh_bank = 0xFFFFFFFF; | ||
3083 | if (instance_bank == 0x3FF) | ||
3084 | instance_bank = 0xFFFFFFFF; | ||
3085 | use_bank = 1; | ||
3086 | } else { | ||
3087 | use_bank = 0; | ||
3088 | } | ||
3089 | |||
3090 | *pos &= (1UL << 22) - 1; | ||
3091 | |||
3092 | if (use_bank) { | ||
3093 | if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) || | ||
3094 | (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) | ||
3095 | return -EINVAL; | ||
3096 | mutex_lock(&adev->grbm_idx_mutex); | ||
3097 | amdgpu_gfx_select_se_sh(adev, se_bank, | ||
3098 | sh_bank, instance_bank); | ||
3099 | } | ||
3100 | |||
3101 | if (pm_pg_lock) | ||
3102 | mutex_lock(&adev->pm.mutex); | ||
3103 | |||
3104 | while (size) { | ||
3105 | uint32_t value; | ||
3106 | |||
3107 | if (*pos > adev->rmmio_size) | ||
3108 | goto end; | ||
3109 | |||
3110 | value = RREG32(*pos >> 2); | ||
3111 | r = put_user(value, (uint32_t *)buf); | ||
3112 | if (r) { | ||
3113 | result = r; | ||
3114 | goto end; | ||
3115 | } | ||
3116 | |||
3117 | result += 4; | ||
3118 | buf += 4; | ||
3119 | *pos += 4; | ||
3120 | size -= 4; | ||
3121 | } | ||
3122 | |||
3123 | end: | ||
3124 | if (use_bank) { | ||
3125 | amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); | ||
3126 | mutex_unlock(&adev->grbm_idx_mutex); | ||
3127 | } | ||
3128 | |||
3129 | if (pm_pg_lock) | ||
3130 | mutex_unlock(&adev->pm.mutex); | ||
3131 | |||
3132 | return result; | ||
3133 | } | ||
3134 | |||
3135 | static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, | ||
3136 | size_t size, loff_t *pos) | ||
3137 | { | ||
3138 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3139 | ssize_t result = 0; | ||
3140 | int r; | ||
3141 | bool pm_pg_lock, use_bank; | ||
3142 | unsigned instance_bank, sh_bank, se_bank; | ||
3143 | |||
3144 | if (size & 0x3 || *pos & 0x3) | ||
3145 | return -EINVAL; | ||
3146 | |||
3147 | /* are we reading registers for which a PG lock is necessary? */ | ||
3148 | pm_pg_lock = (*pos >> 23) & 1; | ||
3149 | |||
3150 | if (*pos & (1ULL << 62)) { | ||
3151 | se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24; | ||
3152 | sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34; | ||
3153 | instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44; | ||
3154 | |||
3155 | if (se_bank == 0x3FF) | ||
3156 | se_bank = 0xFFFFFFFF; | ||
3157 | if (sh_bank == 0x3FF) | ||
3158 | sh_bank = 0xFFFFFFFF; | ||
3159 | if (instance_bank == 0x3FF) | ||
3160 | instance_bank = 0xFFFFFFFF; | ||
3161 | use_bank = 1; | ||
3162 | } else { | ||
3163 | use_bank = 0; | ||
3164 | } | ||
3165 | |||
3166 | *pos &= (1UL << 22) - 1; | ||
3167 | |||
3168 | if (use_bank) { | ||
3169 | if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) || | ||
3170 | (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) | ||
3171 | return -EINVAL; | ||
3172 | mutex_lock(&adev->grbm_idx_mutex); | ||
3173 | amdgpu_gfx_select_se_sh(adev, se_bank, | ||
3174 | sh_bank, instance_bank); | ||
3175 | } | ||
3176 | |||
3177 | if (pm_pg_lock) | ||
3178 | mutex_lock(&adev->pm.mutex); | ||
3179 | |||
3180 | while (size) { | ||
3181 | uint32_t value; | ||
3182 | |||
3183 | if (*pos > adev->rmmio_size) | ||
3184 | return result; | ||
3185 | |||
3186 | r = get_user(value, (uint32_t *)buf); | ||
3187 | if (r) | ||
3188 | return r; | ||
3189 | |||
3190 | WREG32(*pos >> 2, value); | ||
3191 | |||
3192 | result += 4; | ||
3193 | buf += 4; | ||
3194 | *pos += 4; | ||
3195 | size -= 4; | ||
3196 | } | ||
3197 | |||
3198 | if (use_bank) { | ||
3199 | amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); | ||
3200 | mutex_unlock(&adev->grbm_idx_mutex); | ||
3201 | } | ||
3202 | |||
3203 | if (pm_pg_lock) | ||
3204 | mutex_unlock(&adev->pm.mutex); | ||
3205 | |||
3206 | return result; | ||
3207 | } | ||
3208 | |||
3209 | static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, | ||
3210 | size_t size, loff_t *pos) | ||
3211 | { | ||
3212 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3213 | ssize_t result = 0; | ||
3214 | int r; | ||
3215 | |||
3216 | if (size & 0x3 || *pos & 0x3) | ||
3217 | return -EINVAL; | ||
3218 | |||
3219 | while (size) { | ||
3220 | uint32_t value; | ||
3221 | |||
3222 | value = RREG32_PCIE(*pos >> 2); | ||
3223 | r = put_user(value, (uint32_t *)buf); | ||
3224 | if (r) | ||
3225 | return r; | ||
3226 | |||
3227 | result += 4; | ||
3228 | buf += 4; | ||
3229 | *pos += 4; | ||
3230 | size -= 4; | ||
3231 | } | ||
3232 | |||
3233 | return result; | ||
3234 | } | ||
3235 | |||
3236 | static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf, | ||
3237 | size_t size, loff_t *pos) | ||
3238 | { | ||
3239 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3240 | ssize_t result = 0; | ||
3241 | int r; | ||
3242 | |||
3243 | if (size & 0x3 || *pos & 0x3) | ||
3244 | return -EINVAL; | ||
3245 | |||
3246 | while (size) { | ||
3247 | uint32_t value; | ||
3248 | |||
3249 | r = get_user(value, (uint32_t *)buf); | ||
3250 | if (r) | ||
3251 | return r; | ||
3252 | |||
3253 | WREG32_PCIE(*pos >> 2, value); | ||
3254 | |||
3255 | result += 4; | ||
3256 | buf += 4; | ||
3257 | *pos += 4; | ||
3258 | size -= 4; | ||
3259 | } | ||
3260 | |||
3261 | return result; | ||
3262 | } | ||
3263 | |||
3264 | static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, | ||
3265 | size_t size, loff_t *pos) | ||
3266 | { | ||
3267 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3268 | ssize_t result = 0; | ||
3269 | int r; | ||
3270 | |||
3271 | if (size & 0x3 || *pos & 0x3) | ||
3272 | return -EINVAL; | ||
3273 | |||
3274 | while (size) { | ||
3275 | uint32_t value; | ||
3276 | |||
3277 | value = RREG32_DIDT(*pos >> 2); | ||
3278 | r = put_user(value, (uint32_t *)buf); | ||
3279 | if (r) | ||
3280 | return r; | ||
3281 | |||
3282 | result += 4; | ||
3283 | buf += 4; | ||
3284 | *pos += 4; | ||
3285 | size -= 4; | ||
3286 | } | ||
3287 | |||
3288 | return result; | ||
3289 | } | ||
3290 | |||
3291 | static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf, | ||
3292 | size_t size, loff_t *pos) | ||
3293 | { | ||
3294 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3295 | ssize_t result = 0; | ||
3296 | int r; | ||
3297 | |||
3298 | if (size & 0x3 || *pos & 0x3) | ||
3299 | return -EINVAL; | ||
3300 | |||
3301 | while (size) { | ||
3302 | uint32_t value; | ||
3303 | |||
3304 | r = get_user(value, (uint32_t *)buf); | ||
3305 | if (r) | ||
3306 | return r; | ||
3307 | |||
3308 | WREG32_DIDT(*pos >> 2, value); | ||
3309 | |||
3310 | result += 4; | ||
3311 | buf += 4; | ||
3312 | *pos += 4; | ||
3313 | size -= 4; | ||
3314 | } | ||
3315 | |||
3316 | return result; | ||
3317 | } | ||
3318 | |||
3319 | static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, | ||
3320 | size_t size, loff_t *pos) | ||
3321 | { | ||
3322 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3323 | ssize_t result = 0; | ||
3324 | int r; | ||
3325 | |||
3326 | if (size & 0x3 || *pos & 0x3) | ||
3327 | return -EINVAL; | ||
3328 | |||
3329 | while (size) { | ||
3330 | uint32_t value; | ||
3331 | |||
3332 | value = RREG32_SMC(*pos); | ||
3333 | r = put_user(value, (uint32_t *)buf); | ||
3334 | if (r) | ||
3335 | return r; | ||
3336 | |||
3337 | result += 4; | ||
3338 | buf += 4; | ||
3339 | *pos += 4; | ||
3340 | size -= 4; | ||
3341 | } | ||
3342 | |||
3343 | return result; | ||
3344 | } | ||
3345 | |||
3346 | static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf, | ||
3347 | size_t size, loff_t *pos) | ||
3348 | { | ||
3349 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3350 | ssize_t result = 0; | ||
3351 | int r; | ||
3352 | |||
3353 | if (size & 0x3 || *pos & 0x3) | ||
3354 | return -EINVAL; | ||
3355 | |||
3356 | while (size) { | ||
3357 | uint32_t value; | ||
3358 | |||
3359 | r = get_user(value, (uint32_t *)buf); | ||
3360 | if (r) | ||
3361 | return r; | ||
3362 | |||
3363 | WREG32_SMC(*pos, value); | ||
3364 | |||
3365 | result += 4; | ||
3366 | buf += 4; | ||
3367 | *pos += 4; | ||
3368 | size -= 4; | ||
3369 | } | ||
3370 | |||
3371 | return result; | ||
3372 | } | ||
3373 | |||
3374 | static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, | ||
3375 | size_t size, loff_t *pos) | ||
3376 | { | ||
3377 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3378 | ssize_t result = 0; | ||
3379 | int r; | ||
3380 | uint32_t *config, no_regs = 0; | ||
3381 | |||
3382 | if (size & 0x3 || *pos & 0x3) | ||
3383 | return -EINVAL; | ||
3384 | |||
3385 | config = kmalloc_array(256, sizeof(*config), GFP_KERNEL); | ||
3386 | if (!config) | ||
3387 | return -ENOMEM; | ||
3388 | |||
3389 | /* version, increment each time something is added */ | ||
3390 | config[no_regs++] = 3; | ||
3391 | config[no_regs++] = adev->gfx.config.max_shader_engines; | ||
3392 | config[no_regs++] = adev->gfx.config.max_tile_pipes; | ||
3393 | config[no_regs++] = adev->gfx.config.max_cu_per_sh; | ||
3394 | config[no_regs++] = adev->gfx.config.max_sh_per_se; | ||
3395 | config[no_regs++] = adev->gfx.config.max_backends_per_se; | ||
3396 | config[no_regs++] = adev->gfx.config.max_texture_channel_caches; | ||
3397 | config[no_regs++] = adev->gfx.config.max_gprs; | ||
3398 | config[no_regs++] = adev->gfx.config.max_gs_threads; | ||
3399 | config[no_regs++] = adev->gfx.config.max_hw_contexts; | ||
3400 | config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend; | ||
3401 | config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend; | ||
3402 | config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size; | ||
3403 | config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size; | ||
3404 | config[no_regs++] = adev->gfx.config.num_tile_pipes; | ||
3405 | config[no_regs++] = adev->gfx.config.backend_enable_mask; | ||
3406 | config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes; | ||
3407 | config[no_regs++] = adev->gfx.config.mem_row_size_in_kb; | ||
3408 | config[no_regs++] = adev->gfx.config.shader_engine_tile_size; | ||
3409 | config[no_regs++] = adev->gfx.config.num_gpus; | ||
3410 | config[no_regs++] = adev->gfx.config.multi_gpu_tile_size; | ||
3411 | config[no_regs++] = adev->gfx.config.mc_arb_ramcfg; | ||
3412 | config[no_regs++] = adev->gfx.config.gb_addr_config; | ||
3413 | config[no_regs++] = adev->gfx.config.num_rbs; | ||
3414 | |||
3415 | /* rev==1 */ | ||
3416 | config[no_regs++] = adev->rev_id; | ||
3417 | config[no_regs++] = adev->pg_flags; | ||
3418 | config[no_regs++] = adev->cg_flags; | ||
3419 | |||
3420 | /* rev==2 */ | ||
3421 | config[no_regs++] = adev->family; | ||
3422 | config[no_regs++] = adev->external_rev_id; | ||
3423 | |||
3424 | /* rev==3 */ | ||
3425 | config[no_regs++] = adev->pdev->device; | ||
3426 | config[no_regs++] = adev->pdev->revision; | ||
3427 | config[no_regs++] = adev->pdev->subsystem_device; | ||
3428 | config[no_regs++] = adev->pdev->subsystem_vendor; | ||
3429 | |||
3430 | while (size && (*pos < no_regs * 4)) { | ||
3431 | uint32_t value; | ||
3432 | |||
3433 | value = config[*pos >> 2]; | ||
3434 | r = put_user(value, (uint32_t *)buf); | ||
3435 | if (r) { | ||
3436 | kfree(config); | ||
3437 | return r; | ||
3438 | } | ||
3439 | |||
3440 | result += 4; | ||
3441 | buf += 4; | ||
3442 | *pos += 4; | ||
3443 | size -= 4; | ||
3444 | } | ||
3445 | |||
3446 | kfree(config); | ||
3447 | return result; | ||
3448 | } | ||
3449 | |||
3450 | static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, | ||
3451 | size_t size, loff_t *pos) | ||
3452 | { | ||
3453 | struct amdgpu_device *adev = file_inode(f)->i_private; | ||
3454 | int idx, x, outsize, r, valuesize; | ||
3455 | uint32_t values[16]; | ||
3456 | |||
3457 | if (size & 3 || *pos & 0x3) | ||
3458 | return -EINVAL; | ||
3459 | |||
3460 | if (amdgpu_dpm == 0) | ||
3461 | return -EINVAL; | ||
3462 | |||
3463 | /* convert offset to sensor number */ | ||
3464 | idx = *pos >> 2; | ||
3465 | |||
3466 | valuesize = sizeof(values); | ||
3467 | if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor) | ||
3468 | r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize); | ||
3469 | else | ||
3470 | return -EINVAL; | ||
3471 | |||
3472 | if (size > valuesize) | ||
3473 | return -EINVAL; | ||
3474 | |||
3475 | outsize = 0; | ||
3476 | x = 0; | ||
3477 | if (!r) { | ||
3478 | while (size) { | ||
3479 | r = put_user(values[x++], (int32_t *)buf); | ||
3480 | buf += 4; | ||
3481 | size -= 4; | ||
3482 | outsize += 4; | ||
3483 | } | ||
3484 | } | ||
3485 | |||
3486 | return !r ? outsize : r; | ||
3487 | } | ||
3488 | |||
3489 | static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, | ||
3490 | size_t size, loff_t *pos) | ||
3491 | { | ||
3492 | struct amdgpu_device *adev = f->f_inode->i_private; | ||
3493 | int r, x; | ||
3494 | ssize_t result=0; | ||
3495 | uint32_t offset, se, sh, cu, wave, simd, data[32]; | ||
3496 | |||
3497 | if (size & 3 || *pos & 3) | ||
3498 | return -EINVAL; | ||
3499 | |||
3500 | /* decode offset */ | ||
3501 | offset = (*pos & GENMASK_ULL(6, 0)); | ||
3502 | se = (*pos & GENMASK_ULL(14, 7)) >> 7; | ||
3503 | sh = (*pos & GENMASK_ULL(22, 15)) >> 15; | ||
3504 | cu = (*pos & GENMASK_ULL(30, 23)) >> 23; | ||
3505 | wave = (*pos & GENMASK_ULL(36, 31)) >> 31; | ||
3506 | simd = (*pos & GENMASK_ULL(44, 37)) >> 37; | ||
3507 | |||
3508 | /* switch to the specific se/sh/cu */ | ||
3509 | mutex_lock(&adev->grbm_idx_mutex); | ||
3510 | amdgpu_gfx_select_se_sh(adev, se, sh, cu); | ||
3511 | |||
3512 | x = 0; | ||
3513 | if (adev->gfx.funcs->read_wave_data) | ||
3514 | adev->gfx.funcs->read_wave_data(adev, simd, wave, data, &x); | ||
3515 | |||
3516 | amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); | ||
3517 | mutex_unlock(&adev->grbm_idx_mutex); | ||
3518 | |||
3519 | if (!x) | ||
3520 | return -EINVAL; | ||
3521 | |||
3522 | while (size && (offset < x * 4)) { | ||
3523 | uint32_t value; | ||
3524 | |||
3525 | value = data[offset >> 2]; | ||
3526 | r = put_user(value, (uint32_t *)buf); | ||
3527 | if (r) | ||
3528 | return r; | ||
3529 | |||
3530 | result += 4; | ||
3531 | buf += 4; | ||
3532 | offset += 4; | ||
3533 | size -= 4; | ||
3534 | } | ||
3535 | |||
3536 | return result; | ||
3537 | } | ||
3538 | |||
3539 | static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, | ||
3540 | size_t size, loff_t *pos) | ||
3541 | { | ||
3542 | struct amdgpu_device *adev = f->f_inode->i_private; | ||
3543 | int r; | ||
3544 | ssize_t result = 0; | ||
3545 | uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; | ||
3546 | |||
3547 | if (size & 3 || *pos & 3) | ||
3548 | return -EINVAL; | ||
3549 | |||
3550 | /* decode offset */ | ||
3551 | offset = *pos & GENMASK_ULL(11, 0); | ||
3552 | se = (*pos & GENMASK_ULL(19, 12)) >> 12; | ||
3553 | sh = (*pos & GENMASK_ULL(27, 20)) >> 20; | ||
3554 | cu = (*pos & GENMASK_ULL(35, 28)) >> 28; | ||
3555 | wave = (*pos & GENMASK_ULL(43, 36)) >> 36; | ||
3556 | simd = (*pos & GENMASK_ULL(51, 44)) >> 44; | ||
3557 | thread = (*pos & GENMASK_ULL(59, 52)) >> 52; | ||
3558 | bank = (*pos & GENMASK_ULL(61, 60)) >> 60; | ||
3559 | |||
3560 | data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL); | ||
3561 | if (!data) | ||
3562 | return -ENOMEM; | ||
3563 | |||
3564 | /* switch to the specific se/sh/cu */ | ||
3565 | mutex_lock(&adev->grbm_idx_mutex); | ||
3566 | amdgpu_gfx_select_se_sh(adev, se, sh, cu); | ||
3567 | |||
3568 | if (bank == 0) { | ||
3569 | if (adev->gfx.funcs->read_wave_vgprs) | ||
3570 | adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data); | ||
3571 | } else { | ||
3572 | if (adev->gfx.funcs->read_wave_sgprs) | ||
3573 | adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data); | ||
3574 | } | ||
3575 | |||
3576 | amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); | ||
3577 | mutex_unlock(&adev->grbm_idx_mutex); | ||
3578 | |||
3579 | while (size) { | ||
3580 | uint32_t value; | ||
3581 | |||
3582 | value = data[offset++]; | ||
3583 | r = put_user(value, (uint32_t *)buf); | ||
3584 | if (r) { | ||
3585 | result = r; | ||
3586 | goto err; | ||
3587 | } | ||
3588 | |||
3589 | result += 4; | ||
3590 | buf += 4; | ||
3591 | size -= 4; | ||
3592 | } | ||
3593 | |||
3594 | err: | ||
3595 | kfree(data); | ||
3596 | return result; | ||
3597 | } | ||
3598 | |||
3599 | static const struct file_operations amdgpu_debugfs_regs_fops = { | ||
3600 | .owner = THIS_MODULE, | ||
3601 | .read = amdgpu_debugfs_regs_read, | ||
3602 | .write = amdgpu_debugfs_regs_write, | ||
3603 | .llseek = default_llseek | ||
3604 | }; | ||
3605 | static const struct file_operations amdgpu_debugfs_regs_didt_fops = { | ||
3606 | .owner = THIS_MODULE, | ||
3607 | .read = amdgpu_debugfs_regs_didt_read, | ||
3608 | .write = amdgpu_debugfs_regs_didt_write, | ||
3609 | .llseek = default_llseek | ||
3610 | }; | ||
3611 | static const struct file_operations amdgpu_debugfs_regs_pcie_fops = { | ||
3612 | .owner = THIS_MODULE, | ||
3613 | .read = amdgpu_debugfs_regs_pcie_read, | ||
3614 | .write = amdgpu_debugfs_regs_pcie_write, | ||
3615 | .llseek = default_llseek | ||
3616 | }; | ||
3617 | static const struct file_operations amdgpu_debugfs_regs_smc_fops = { | ||
3618 | .owner = THIS_MODULE, | ||
3619 | .read = amdgpu_debugfs_regs_smc_read, | ||
3620 | .write = amdgpu_debugfs_regs_smc_write, | ||
3621 | .llseek = default_llseek | ||
3622 | }; | ||
3623 | |||
3624 | static const struct file_operations amdgpu_debugfs_gca_config_fops = { | ||
3625 | .owner = THIS_MODULE, | ||
3626 | .read = amdgpu_debugfs_gca_config_read, | ||
3627 | .llseek = default_llseek | ||
3628 | }; | ||
3629 | |||
3630 | static const struct file_operations amdgpu_debugfs_sensors_fops = { | ||
3631 | .owner = THIS_MODULE, | ||
3632 | .read = amdgpu_debugfs_sensor_read, | ||
3633 | .llseek = default_llseek | ||
3634 | }; | ||
3635 | |||
3636 | static const struct file_operations amdgpu_debugfs_wave_fops = { | ||
3637 | .owner = THIS_MODULE, | ||
3638 | .read = amdgpu_debugfs_wave_read, | ||
3639 | .llseek = default_llseek | ||
3640 | }; | ||
3641 | static const struct file_operations amdgpu_debugfs_gpr_fops = { | ||
3642 | .owner = THIS_MODULE, | ||
3643 | .read = amdgpu_debugfs_gpr_read, | ||
3644 | .llseek = default_llseek | ||
3645 | }; | ||
3646 | |||
3647 | static const struct file_operations *debugfs_regs[] = { | ||
3648 | &amdgpu_debugfs_regs_fops, | ||
3649 | &amdgpu_debugfs_regs_didt_fops, | ||
3650 | &amdgpu_debugfs_regs_pcie_fops, | ||
3651 | &amdgpu_debugfs_regs_smc_fops, | ||
3652 | &amdgpu_debugfs_gca_config_fops, | ||
3653 | &amdgpu_debugfs_sensors_fops, | ||
3654 | &amdgpu_debugfs_wave_fops, | ||
3655 | &amdgpu_debugfs_gpr_fops, | ||
3656 | }; | ||
3657 | |||
3658 | static const char *debugfs_regs_names[] = { | ||
3659 | "amdgpu_regs", | ||
3660 | "amdgpu_regs_didt", | ||
3661 | "amdgpu_regs_pcie", | ||
3662 | "amdgpu_regs_smc", | ||
3663 | "amdgpu_gca_config", | ||
3664 | "amdgpu_sensors", | ||
3665 | "amdgpu_wave", | ||
3666 | "amdgpu_gpr", | ||
3667 | }; | ||
3668 | |||
3669 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) | ||
3670 | { | ||
3671 | struct drm_minor *minor = adev->ddev->primary; | ||
3672 | struct dentry *ent, *root = minor->debugfs_root; | ||
3673 | unsigned i, j; | ||
3674 | |||
3675 | for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { | ||
3676 | ent = debugfs_create_file(debugfs_regs_names[i], | ||
3677 | S_IFREG | S_IRUGO, root, | ||
3678 | adev, debugfs_regs[i]); | ||
3679 | if (IS_ERR(ent)) { | ||
3680 | for (j = 0; j < i; j++) { | ||
3681 | debugfs_remove(adev->debugfs_regs[i]); | ||
3682 | adev->debugfs_regs[i] = NULL; | ||
3683 | } | ||
3684 | return PTR_ERR(ent); | ||
3685 | } | ||
3686 | |||
3687 | if (!i) | ||
3688 | i_size_write(ent->d_inode, adev->rmmio_size); | ||
3689 | adev->debugfs_regs[i] = ent; | ||
3690 | } | ||
3691 | |||
3692 | return 0; | ||
3693 | } | ||
3694 | |||
3695 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) | ||
3696 | { | ||
3697 | unsigned i; | ||
3698 | |||
3699 | for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { | ||
3700 | if (adev->debugfs_regs[i]) { | ||
3701 | debugfs_remove(adev->debugfs_regs[i]); | ||
3702 | adev->debugfs_regs[i] = NULL; | ||
3703 | } | ||
3704 | } | ||
3705 | } | ||
3706 | |||
3707 | static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data) | ||
3708 | { | ||
3709 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
3710 | struct drm_device *dev = node->minor->dev; | ||
3711 | struct amdgpu_device *adev = dev->dev_private; | ||
3712 | int r = 0, i; | ||
3713 | |||
3714 | /* hold on the scheduler */ | ||
3715 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | ||
3716 | struct amdgpu_ring *ring = adev->rings[i]; | ||
3717 | |||
3718 | if (!ring || !ring->sched.thread) | ||
3719 | continue; | ||
3720 | kthread_park(ring->sched.thread); | ||
3721 | } | ||
3722 | |||
3723 | seq_printf(m, "run ib test:\n"); | ||
3724 | r = amdgpu_ib_ring_tests(adev); | ||
3725 | if (r) | ||
3726 | seq_printf(m, "ib ring tests failed (%d).\n", r); | ||
3727 | else | ||
3728 | seq_printf(m, "ib ring tests passed.\n"); | ||
3729 | |||
3730 | /* go on the scheduler */ | ||
3731 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | ||
3732 | struct amdgpu_ring *ring = adev->rings[i]; | ||
3733 | |||
3734 | if (!ring || !ring->sched.thread) | ||
3735 | continue; | ||
3736 | kthread_unpark(ring->sched.thread); | ||
3737 | } | ||
3738 | |||
3739 | return 0; | ||
3740 | } | ||
3741 | |||
3742 | static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data) | ||
3743 | { | ||
3744 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
3745 | struct drm_device *dev = node->minor->dev; | ||
3746 | struct amdgpu_device *adev = dev->dev_private; | ||
3747 | |||
3748 | seq_write(m, adev->bios, adev->bios_size); | ||
3749 | return 0; | ||
3750 | } | ||
3751 | |||
3752 | static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data) | ||
3753 | { | ||
3754 | struct drm_info_node *node = (struct drm_info_node *)m->private; | ||
3755 | struct drm_device *dev = node->minor->dev; | ||
3756 | struct amdgpu_device *adev = dev->dev_private; | ||
3757 | |||
3758 | seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev)); | ||
3759 | return 0; | ||
3760 | } | ||
3761 | |||
3762 | static const struct drm_info_list amdgpu_debugfs_list[] = { | ||
3763 | {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump}, | ||
3764 | {"amdgpu_test_ib", &amdgpu_debugfs_test_ib}, | ||
3765 | {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram} | ||
3766 | }; | ||
3767 | |||
3768 | static int amdgpu_debugfs_init(struct amdgpu_device *adev) | ||
3769 | { | ||
3770 | return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list, | ||
3771 | ARRAY_SIZE(amdgpu_debugfs_list)); | ||
3772 | } | ||
3773 | |||
3774 | #else | ||
3775 | static int amdgpu_debugfs_init(struct amdgpu_device *adev) | ||
3776 | { | ||
3777 | return 0; | ||
3778 | } | ||
3779 | static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) | ||
3780 | { | ||
3781 | return 0; | ||
3782 | } | ||
3783 | static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { } | ||
3784 | #endif | ||