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 10 static DEFINE_MUTEX(ring_read_lock); 11 static DEFINE_MUTEX(bank_read_lock); 12 13 static 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 29 static 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 41 static 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 76 static void adf_ring_stop(struct seq_file *sfile, void *v) 77 { 78 mutex_unlock(&ring_read_lock); 79 } 80 81 static 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 88 DEFINE_SEQ_ATTRIBUTE(adf_ring_debug); 89 90 int 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 strscpy(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 110 void 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 119 static 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 134 static 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 145 static 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 177 static void adf_bank_stop(struct seq_file *sfile, void *v) 178 { 179 mutex_unlock(&bank_read_lock); 180 } 181 182 static 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 189 DEFINE_SEQ_ATTRIBUTE(adf_bank_debug); 190 191 int 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 205 void 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 } 210