adf_transport_debug.c (5862B)
1// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) 2/* Copyright(c) 2014 - 2020 Intel Corporation */ 3#include <linux/mutex.h> 4#include <linux/slab.h> 5#include <linux/seq_file.h> 6#include "adf_accel_devices.h" 7#include "adf_transport_internal.h" 8#include "adf_transport_access_macros.h" 9 10static DEFINE_MUTEX(ring_read_lock); 11static DEFINE_MUTEX(bank_read_lock); 12 13static void *adf_ring_start(struct seq_file *sfile, loff_t *pos) 14{ 15 struct adf_etr_ring_data *ring = sfile->private; 16 17 mutex_lock(&ring_read_lock); 18 if (*pos == 0) 19 return SEQ_START_TOKEN; 20 21 if (*pos >= (ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size) / 22 ADF_MSG_SIZE_TO_BYTES(ring->msg_size))) 23 return NULL; 24 25 return ring->base_addr + 26 (ADF_MSG_SIZE_TO_BYTES(ring->msg_size) * (*pos)++); 27} 28 29static void *adf_ring_next(struct seq_file *sfile, void *v, loff_t *pos) 30{ 31 struct adf_etr_ring_data *ring = sfile->private; 32 33 if (*pos >= (ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size) / 34 ADF_MSG_SIZE_TO_BYTES(ring->msg_size))) 35 return NULL; 36 37 return ring->base_addr + 38 (ADF_MSG_SIZE_TO_BYTES(ring->msg_size) * (*pos)++); 39} 40 41static int adf_ring_show(struct seq_file *sfile, void *v) 42{ 43 struct adf_etr_ring_data *ring = sfile->private; 44 struct adf_etr_bank_data *bank = ring->bank; 45 struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(bank->accel_dev); 46 void __iomem *csr = ring->bank->csr_addr; 47 48 if (v == SEQ_START_TOKEN) { 49 int head, tail, empty; 50 51 head = csr_ops->read_csr_ring_head(csr, bank->bank_number, 52 ring->ring_number); 53 tail = csr_ops->read_csr_ring_tail(csr, bank->bank_number, 54 ring->ring_number); 55 empty = csr_ops->read_csr_e_stat(csr, bank->bank_number); 56 57 seq_puts(sfile, "------- Ring configuration -------\n"); 58 seq_printf(sfile, "ring name: %s\n", 59 ring->ring_debug->ring_name); 60 seq_printf(sfile, "ring num %d, bank num %d\n", 61 ring->ring_number, ring->bank->bank_number); 62 seq_printf(sfile, "head %x, tail %x, empty: %d\n", 63 head, tail, (empty & 1 << ring->ring_number) 64 >> ring->ring_number); 65 seq_printf(sfile, "ring size %lld, msg size %d\n", 66 (long long)ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size), 67 ADF_MSG_SIZE_TO_BYTES(ring->msg_size)); 68 seq_puts(sfile, "----------- Ring data ------------\n"); 69 return 0; 70 } 71 seq_hex_dump(sfile, "", DUMP_PREFIX_ADDRESS, 32, 4, 72 v, ADF_MSG_SIZE_TO_BYTES(ring->msg_size), false); 73 return 0; 74} 75 76static void adf_ring_stop(struct seq_file *sfile, void *v) 77{ 78 mutex_unlock(&ring_read_lock); 79} 80 81static const struct seq_operations adf_ring_debug_sops = { 82 .start = adf_ring_start, 83 .next = adf_ring_next, 84 .stop = adf_ring_stop, 85 .show = adf_ring_show 86}; 87 88DEFINE_SEQ_ATTRIBUTE(adf_ring_debug); 89 90int adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name) 91{ 92 struct adf_etr_ring_debug_entry *ring_debug; 93 char entry_name[8]; 94 95 ring_debug = kzalloc(sizeof(*ring_debug), GFP_KERNEL); 96 if (!ring_debug) 97 return -ENOMEM; 98 99 strlcpy(ring_debug->ring_name, name, sizeof(ring_debug->ring_name)); 100 snprintf(entry_name, sizeof(entry_name), "ring_%02d", 101 ring->ring_number); 102 103 ring_debug->debug = debugfs_create_file(entry_name, S_IRUSR, 104 ring->bank->bank_debug_dir, 105 ring, &adf_ring_debug_fops); 106 ring->ring_debug = ring_debug; 107 return 0; 108} 109 110void adf_ring_debugfs_rm(struct adf_etr_ring_data *ring) 111{ 112 if (ring->ring_debug) { 113 debugfs_remove(ring->ring_debug->debug); 114 kfree(ring->ring_debug); 115 ring->ring_debug = NULL; 116 } 117} 118 119static void *adf_bank_start(struct seq_file *sfile, loff_t *pos) 120{ 121 struct adf_etr_bank_data *bank = sfile->private; 122 u8 num_rings_per_bank = GET_NUM_RINGS_PER_BANK(bank->accel_dev); 123 124 mutex_lock(&bank_read_lock); 125 if (*pos == 0) 126 return SEQ_START_TOKEN; 127 128 if (*pos >= num_rings_per_bank) 129 return NULL; 130 131 return pos; 132} 133 134static void *adf_bank_next(struct seq_file *sfile, void *v, loff_t *pos) 135{ 136 struct adf_etr_bank_data *bank = sfile->private; 137 u8 num_rings_per_bank = GET_NUM_RINGS_PER_BANK(bank->accel_dev); 138 139 if (++(*pos) >= num_rings_per_bank) 140 return NULL; 141 142 return pos; 143} 144 145static int adf_bank_show(struct seq_file *sfile, void *v) 146{ 147 struct adf_etr_bank_data *bank = sfile->private; 148 struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(bank->accel_dev); 149 150 if (v == SEQ_START_TOKEN) { 151 seq_printf(sfile, "------- Bank %d configuration -------\n", 152 bank->bank_number); 153 } else { 154 int ring_id = *((int *)v) - 1; 155 struct adf_etr_ring_data *ring = &bank->rings[ring_id]; 156 void __iomem *csr = bank->csr_addr; 157 int head, tail, empty; 158 159 if (!(bank->ring_mask & 1 << ring_id)) 160 return 0; 161 162 head = csr_ops->read_csr_ring_head(csr, bank->bank_number, 163 ring->ring_number); 164 tail = csr_ops->read_csr_ring_tail(csr, bank->bank_number, 165 ring->ring_number); 166 empty = csr_ops->read_csr_e_stat(csr, bank->bank_number); 167 168 seq_printf(sfile, 169 "ring num %02d, head %04x, tail %04x, empty: %d\n", 170 ring->ring_number, head, tail, 171 (empty & 1 << ring->ring_number) >> 172 ring->ring_number); 173 } 174 return 0; 175} 176 177static void adf_bank_stop(struct seq_file *sfile, void *v) 178{ 179 mutex_unlock(&bank_read_lock); 180} 181 182static const struct seq_operations adf_bank_debug_sops = { 183 .start = adf_bank_start, 184 .next = adf_bank_next, 185 .stop = adf_bank_stop, 186 .show = adf_bank_show 187}; 188 189DEFINE_SEQ_ATTRIBUTE(adf_bank_debug); 190 191int adf_bank_debugfs_add(struct adf_etr_bank_data *bank) 192{ 193 struct adf_accel_dev *accel_dev = bank->accel_dev; 194 struct dentry *parent = accel_dev->transport->debug; 195 char name[8]; 196 197 snprintf(name, sizeof(name), "bank_%02d", bank->bank_number); 198 bank->bank_debug_dir = debugfs_create_dir(name, parent); 199 bank->bank_debug_cfg = debugfs_create_file("config", S_IRUSR, 200 bank->bank_debug_dir, bank, 201 &adf_bank_debug_fops); 202 return 0; 203} 204 205void adf_bank_debugfs_rm(struct adf_etr_bank_data *bank) 206{ 207 debugfs_remove(bank->bank_debug_cfg); 208 debugfs_remove(bank->bank_debug_dir); 209}