Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[linux-2.6-microblaze.git] / drivers / misc / habanalabs / common / debugfs.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Copyright 2016-2019 HabanaLabs, Ltd.
5  * All Rights Reserved.
6  */
7
8 #include "habanalabs.h"
9 #include "../include/hw_ip/mmu/mmu_general.h"
10
11 #include <linux/pci.h>
12 #include <linux/debugfs.h>
13 #include <linux/uaccess.h>
14
15 #define MMU_ADDR_BUF_SIZE       40
16 #define MMU_ASID_BUF_SIZE       10
17 #define MMU_KBUF_SIZE           (MMU_ADDR_BUF_SIZE + MMU_ASID_BUF_SIZE)
18
19 static struct dentry *hl_debug_root;
20
21 static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
22                                 u8 i2c_reg, long *val)
23 {
24         struct cpucp_packet pkt;
25         u64 result;
26         int rc;
27
28         if (!hl_device_operational(hdev, NULL))
29                 return -EBUSY;
30
31         memset(&pkt, 0, sizeof(pkt));
32
33         pkt.ctl = cpu_to_le32(CPUCP_PACKET_I2C_RD <<
34                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
35         pkt.i2c_bus = i2c_bus;
36         pkt.i2c_addr = i2c_addr;
37         pkt.i2c_reg = i2c_reg;
38
39         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
40                                                 0, &result);
41
42         *val = (long) result;
43
44         if (rc)
45                 dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc);
46
47         return rc;
48 }
49
50 static int hl_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
51                                 u8 i2c_reg, u32 val)
52 {
53         struct cpucp_packet pkt;
54         int rc;
55
56         if (!hl_device_operational(hdev, NULL))
57                 return -EBUSY;
58
59         memset(&pkt, 0, sizeof(pkt));
60
61         pkt.ctl = cpu_to_le32(CPUCP_PACKET_I2C_WR <<
62                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
63         pkt.i2c_bus = i2c_bus;
64         pkt.i2c_addr = i2c_addr;
65         pkt.i2c_reg = i2c_reg;
66         pkt.value = cpu_to_le64(val);
67
68         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
69                                                 0, NULL);
70
71         if (rc)
72                 dev_err(hdev->dev, "Failed to write to I2C, error %d\n", rc);
73
74         return rc;
75 }
76
77 static void hl_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state)
78 {
79         struct cpucp_packet pkt;
80         int rc;
81
82         if (!hl_device_operational(hdev, NULL))
83                 return;
84
85         memset(&pkt, 0, sizeof(pkt));
86
87         pkt.ctl = cpu_to_le32(CPUCP_PACKET_LED_SET <<
88                                 CPUCP_PKT_CTL_OPCODE_SHIFT);
89         pkt.led_index = cpu_to_le32(led);
90         pkt.value = cpu_to_le64(state);
91
92         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
93                                                 0, NULL);
94
95         if (rc)
96                 dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc);
97 }
98
99 static int command_buffers_show(struct seq_file *s, void *data)
100 {
101         struct hl_debugfs_entry *entry = s->private;
102         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
103         struct hl_cb *cb;
104         bool first = true;
105
106         spin_lock(&dev_entry->cb_spinlock);
107
108         list_for_each_entry(cb, &dev_entry->cb_list, debugfs_list) {
109                 if (first) {
110                         first = false;
111                         seq_puts(s, "\n");
112                         seq_puts(s, " CB ID   CTX ID   CB size    CB RefCnt    mmap?   CS counter\n");
113                         seq_puts(s, "---------------------------------------------------------------\n");
114                 }
115                 seq_printf(s,
116                         "   %03llu        %d    0x%08x      %d          %d          %d\n",
117                         cb->id, cb->ctx->asid, cb->size,
118                         kref_read(&cb->refcount),
119                         cb->mmap, atomic_read(&cb->cs_cnt));
120         }
121
122         spin_unlock(&dev_entry->cb_spinlock);
123
124         if (!first)
125                 seq_puts(s, "\n");
126
127         return 0;
128 }
129
130 static int command_submission_show(struct seq_file *s, void *data)
131 {
132         struct hl_debugfs_entry *entry = s->private;
133         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
134         struct hl_cs *cs;
135         bool first = true;
136
137         spin_lock(&dev_entry->cs_spinlock);
138
139         list_for_each_entry(cs, &dev_entry->cs_list, debugfs_list) {
140                 if (first) {
141                         first = false;
142                         seq_puts(s, "\n");
143                         seq_puts(s, " CS ID   CTX ASID   CS RefCnt   Submitted    Completed\n");
144                         seq_puts(s, "------------------------------------------------------\n");
145                 }
146                 seq_printf(s,
147                         "   %llu       %d          %d           %d            %d\n",
148                         cs->sequence, cs->ctx->asid,
149                         kref_read(&cs->refcount),
150                         cs->submitted, cs->completed);
151         }
152
153         spin_unlock(&dev_entry->cs_spinlock);
154
155         if (!first)
156                 seq_puts(s, "\n");
157
158         return 0;
159 }
160
161 static int command_submission_jobs_show(struct seq_file *s, void *data)
162 {
163         struct hl_debugfs_entry *entry = s->private;
164         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
165         struct hl_cs_job *job;
166         bool first = true;
167
168         spin_lock(&dev_entry->cs_job_spinlock);
169
170         list_for_each_entry(job, &dev_entry->cs_job_list, debugfs_list) {
171                 if (first) {
172                         first = false;
173                         seq_puts(s, "\n");
174                         seq_puts(s, " JOB ID   CS ID    CTX ASID   JOB RefCnt   H/W Queue\n");
175                         seq_puts(s, "----------------------------------------------------\n");
176                 }
177                 if (job->cs)
178                         seq_printf(s,
179                                 "   %02d      %llu        %d          %d           %d\n",
180                                 job->id, job->cs->sequence, job->cs->ctx->asid,
181                                 kref_read(&job->refcount), job->hw_queue_id);
182                 else
183                         seq_printf(s,
184                                 "   %02d      0        %d          %d           %d\n",
185                                 job->id, HL_KERNEL_ASID_ID,
186                                 kref_read(&job->refcount), job->hw_queue_id);
187         }
188
189         spin_unlock(&dev_entry->cs_job_spinlock);
190
191         if (!first)
192                 seq_puts(s, "\n");
193
194         return 0;
195 }
196
197 static int userptr_show(struct seq_file *s, void *data)
198 {
199         struct hl_debugfs_entry *entry = s->private;
200         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
201         struct hl_userptr *userptr;
202         char dma_dir[4][30] = {"DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
203                                 "DMA_FROM_DEVICE", "DMA_NONE"};
204         bool first = true;
205
206         spin_lock(&dev_entry->userptr_spinlock);
207
208         list_for_each_entry(userptr, &dev_entry->userptr_list, debugfs_list) {
209                 if (first) {
210                         first = false;
211                         seq_puts(s, "\n");
212                         seq_puts(s, " user virtual address     size             dma dir\n");
213                         seq_puts(s, "----------------------------------------------------------\n");
214                 }
215                 seq_printf(s,
216                         "    0x%-14llx      %-10u    %-30s\n",
217                         userptr->addr, userptr->size, dma_dir[userptr->dir]);
218         }
219
220         spin_unlock(&dev_entry->userptr_spinlock);
221
222         if (!first)
223                 seq_puts(s, "\n");
224
225         return 0;
226 }
227
228 static int vm_show(struct seq_file *s, void *data)
229 {
230         struct hl_debugfs_entry *entry = s->private;
231         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
232         struct hl_ctx *ctx;
233         struct hl_vm *vm;
234         struct hl_vm_hash_node *hnode;
235         struct hl_userptr *userptr;
236         struct hl_vm_phys_pg_pack *phys_pg_pack = NULL;
237         enum vm_type_t *vm_type;
238         bool once = true;
239         u64 j;
240         int i;
241
242         if (!dev_entry->hdev->mmu_enable)
243                 return 0;
244
245         spin_lock(&dev_entry->ctx_mem_hash_spinlock);
246
247         list_for_each_entry(ctx, &dev_entry->ctx_mem_hash_list, debugfs_list) {
248                 once = false;
249                 seq_puts(s, "\n\n----------------------------------------------------");
250                 seq_puts(s, "\n----------------------------------------------------\n\n");
251                 seq_printf(s, "ctx asid: %u\n", ctx->asid);
252
253                 seq_puts(s, "\nmappings:\n\n");
254                 seq_puts(s, "    virtual address        size          handle\n");
255                 seq_puts(s, "----------------------------------------------------\n");
256                 mutex_lock(&ctx->mem_hash_lock);
257                 hash_for_each(ctx->mem_hash, i, hnode, node) {
258                         vm_type = hnode->ptr;
259
260                         if (*vm_type == VM_TYPE_USERPTR) {
261                                 userptr = hnode->ptr;
262                                 seq_printf(s,
263                                         "    0x%-14llx      %-10u\n",
264                                         hnode->vaddr, userptr->size);
265                         } else {
266                                 phys_pg_pack = hnode->ptr;
267                                 seq_printf(s,
268                                         "    0x%-14llx      %-10llu       %-4u\n",
269                                         hnode->vaddr, phys_pg_pack->total_size,
270                                         phys_pg_pack->handle);
271                         }
272                 }
273                 mutex_unlock(&ctx->mem_hash_lock);
274
275                 vm = &ctx->hdev->vm;
276                 spin_lock(&vm->idr_lock);
277
278                 if (!idr_is_empty(&vm->phys_pg_pack_handles))
279                         seq_puts(s, "\n\nallocations:\n");
280
281                 idr_for_each_entry(&vm->phys_pg_pack_handles, phys_pg_pack, i) {
282                         if (phys_pg_pack->asid != ctx->asid)
283                                 continue;
284
285                         seq_printf(s, "\nhandle: %u\n", phys_pg_pack->handle);
286                         seq_printf(s, "page size: %u\n\n",
287                                                 phys_pg_pack->page_size);
288                         seq_puts(s, "   physical address\n");
289                         seq_puts(s, "---------------------\n");
290                         for (j = 0 ; j < phys_pg_pack->npages ; j++) {
291                                 seq_printf(s, "    0x%-14llx\n",
292                                                 phys_pg_pack->pages[j]);
293                         }
294                 }
295                 spin_unlock(&vm->idr_lock);
296
297         }
298
299         spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
300
301         if (!once)
302                 seq_puts(s, "\n");
303
304         return 0;
305 }
306
307 static int mmu_show(struct seq_file *s, void *data)
308 {
309         struct hl_debugfs_entry *entry = s->private;
310         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
311         struct hl_device *hdev = dev_entry->hdev;
312         struct hl_ctx *ctx;
313         struct hl_mmu_hop_info hops_info = {0};
314         u64 virt_addr = dev_entry->mmu_addr, phys_addr;
315         int i;
316
317         if (!hdev->mmu_enable)
318                 return 0;
319
320         if (dev_entry->mmu_asid == HL_KERNEL_ASID_ID)
321                 ctx = hdev->kernel_ctx;
322         else
323                 ctx = hdev->compute_ctx;
324
325         if (!ctx) {
326                 dev_err(hdev->dev, "no ctx available\n");
327                 return 0;
328         }
329
330         if (hl_mmu_get_tlb_info(ctx, virt_addr, &hops_info)) {
331                 dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
332                                 virt_addr);
333                 return 0;
334         }
335
336         phys_addr = hops_info.hop_info[hops_info.used_hops - 1].hop_pte_val;
337
338         if (hops_info.scrambled_vaddr &&
339                 (dev_entry->mmu_addr != hops_info.scrambled_vaddr))
340                 seq_printf(s,
341                         "asid: %u, virt_addr: 0x%llx, scrambled virt_addr: 0x%llx,\nphys_addr: 0x%llx, scrambled_phys_addr: 0x%llx\n",
342                         dev_entry->mmu_asid, dev_entry->mmu_addr,
343                         hops_info.scrambled_vaddr,
344                         hops_info.unscrambled_paddr, phys_addr);
345         else
346                 seq_printf(s,
347                         "asid: %u, virt_addr: 0x%llx, phys_addr: 0x%llx\n",
348                         dev_entry->mmu_asid, dev_entry->mmu_addr, phys_addr);
349
350         for (i = 0 ; i < hops_info.used_hops ; i++) {
351                 seq_printf(s, "hop%d_addr: 0x%llx\n",
352                                 i, hops_info.hop_info[i].hop_addr);
353                 seq_printf(s, "hop%d_pte_addr: 0x%llx\n",
354                                 i, hops_info.hop_info[i].hop_pte_addr);
355                 seq_printf(s, "hop%d_pte: 0x%llx\n",
356                                 i, hops_info.hop_info[i].hop_pte_val);
357         }
358
359         return 0;
360 }
361
362 static ssize_t mmu_asid_va_write(struct file *file, const char __user *buf,
363                 size_t count, loff_t *f_pos)
364 {
365         struct seq_file *s = file->private_data;
366         struct hl_debugfs_entry *entry = s->private;
367         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
368         struct hl_device *hdev = dev_entry->hdev;
369         char kbuf[MMU_KBUF_SIZE];
370         char *c;
371         ssize_t rc;
372
373         if (!hdev->mmu_enable)
374                 return count;
375
376         if (count > sizeof(kbuf) - 1)
377                 goto err;
378         if (copy_from_user(kbuf, buf, count))
379                 goto err;
380         kbuf[count] = 0;
381
382         c = strchr(kbuf, ' ');
383         if (!c)
384                 goto err;
385         *c = '\0';
386
387         rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);
388         if (rc)
389                 goto err;
390
391         if (strncmp(c+1, "0x", 2))
392                 goto err;
393         rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
394         if (rc)
395                 goto err;
396
397         return count;
398
399 err:
400         dev_err(hdev->dev, "usage: echo <asid> <0xaddr> > mmu\n");
401
402         return -EINVAL;
403 }
404
405 static int engines_show(struct seq_file *s, void *data)
406 {
407         struct hl_debugfs_entry *entry = s->private;
408         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
409         struct hl_device *hdev = dev_entry->hdev;
410
411         if (atomic_read(&hdev->in_reset)) {
412                 dev_warn_ratelimited(hdev->dev,
413                                 "Can't check device idle during reset\n");
414                 return 0;
415         }
416
417         hdev->asic_funcs->is_device_idle(hdev, NULL, 0, s);
418
419         return 0;
420 }
421
422 static bool hl_is_device_va(struct hl_device *hdev, u64 addr)
423 {
424         struct asic_fixed_properties *prop = &hdev->asic_prop;
425
426         if (!hdev->mmu_enable)
427                 goto out;
428
429         if (prop->dram_supports_virtual_memory &&
430                 (addr >= prop->dmmu.start_addr && addr < prop->dmmu.end_addr))
431                 return true;
432
433         if (addr >= prop->pmmu.start_addr &&
434                 addr < prop->pmmu.end_addr)
435                 return true;
436
437         if (addr >= prop->pmmu_huge.start_addr &&
438                 addr < prop->pmmu_huge.end_addr)
439                 return true;
440 out:
441         return false;
442 }
443
444 static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr,
445                                 u64 *phys_addr)
446 {
447         struct hl_ctx *ctx = hdev->compute_ctx;
448         int rc = 0;
449
450         if (!ctx) {
451                 dev_err(hdev->dev, "no ctx available\n");
452                 return -EINVAL;
453         }
454
455         rc = hl_mmu_va_to_pa(ctx, virt_addr, phys_addr);
456         if (rc) {
457                 dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
458                                 virt_addr);
459                 rc = -EINVAL;
460         }
461
462         return rc;
463 }
464
465 static ssize_t hl_data_read32(struct file *f, char __user *buf,
466                                         size_t count, loff_t *ppos)
467 {
468         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
469         struct hl_device *hdev = entry->hdev;
470         char tmp_buf[32];
471         u64 addr = entry->addr;
472         u32 val;
473         ssize_t rc;
474
475         if (atomic_read(&hdev->in_reset)) {
476                 dev_warn_ratelimited(hdev->dev, "Can't read during reset\n");
477                 return 0;
478         }
479
480         if (*ppos)
481                 return 0;
482
483         if (hl_is_device_va(hdev, addr)) {
484                 rc = device_va_to_pa(hdev, addr, &addr);
485                 if (rc)
486                         return rc;
487         }
488
489         rc = hdev->asic_funcs->debugfs_read32(hdev, addr, &val);
490         if (rc) {
491                 dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
492                 return rc;
493         }
494
495         sprintf(tmp_buf, "0x%08x\n", val);
496         return simple_read_from_buffer(buf, count, ppos, tmp_buf,
497                         strlen(tmp_buf));
498 }
499
500 static ssize_t hl_data_write32(struct file *f, const char __user *buf,
501                                         size_t count, loff_t *ppos)
502 {
503         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
504         struct hl_device *hdev = entry->hdev;
505         u64 addr = entry->addr;
506         u32 value;
507         ssize_t rc;
508
509         if (atomic_read(&hdev->in_reset)) {
510                 dev_warn_ratelimited(hdev->dev, "Can't write during reset\n");
511                 return 0;
512         }
513
514         rc = kstrtouint_from_user(buf, count, 16, &value);
515         if (rc)
516                 return rc;
517
518         if (hl_is_device_va(hdev, addr)) {
519                 rc = device_va_to_pa(hdev, addr, &addr);
520                 if (rc)
521                         return rc;
522         }
523
524         rc = hdev->asic_funcs->debugfs_write32(hdev, addr, value);
525         if (rc) {
526                 dev_err(hdev->dev, "Failed to write 0x%08x to 0x%010llx\n",
527                         value, addr);
528                 return rc;
529         }
530
531         return count;
532 }
533
534 static ssize_t hl_data_read64(struct file *f, char __user *buf,
535                                         size_t count, loff_t *ppos)
536 {
537         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
538         struct hl_device *hdev = entry->hdev;
539         char tmp_buf[32];
540         u64 addr = entry->addr;
541         u64 val;
542         ssize_t rc;
543
544         if (*ppos)
545                 return 0;
546
547         if (hl_is_device_va(hdev, addr)) {
548                 rc = device_va_to_pa(hdev, addr, &addr);
549                 if (rc)
550                         return rc;
551         }
552
553         rc = hdev->asic_funcs->debugfs_read64(hdev, addr, &val);
554         if (rc) {
555                 dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
556                 return rc;
557         }
558
559         sprintf(tmp_buf, "0x%016llx\n", val);
560         return simple_read_from_buffer(buf, count, ppos, tmp_buf,
561                         strlen(tmp_buf));
562 }
563
564 static ssize_t hl_data_write64(struct file *f, const char __user *buf,
565                                         size_t count, loff_t *ppos)
566 {
567         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
568         struct hl_device *hdev = entry->hdev;
569         u64 addr = entry->addr;
570         u64 value;
571         ssize_t rc;
572
573         rc = kstrtoull_from_user(buf, count, 16, &value);
574         if (rc)
575                 return rc;
576
577         if (hl_is_device_va(hdev, addr)) {
578                 rc = device_va_to_pa(hdev, addr, &addr);
579                 if (rc)
580                         return rc;
581         }
582
583         rc = hdev->asic_funcs->debugfs_write64(hdev, addr, value);
584         if (rc) {
585                 dev_err(hdev->dev, "Failed to write 0x%016llx to 0x%010llx\n",
586                         value, addr);
587                 return rc;
588         }
589
590         return count;
591 }
592
593 static ssize_t hl_get_power_state(struct file *f, char __user *buf,
594                 size_t count, loff_t *ppos)
595 {
596         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
597         struct hl_device *hdev = entry->hdev;
598         char tmp_buf[200];
599         int i;
600
601         if (*ppos)
602                 return 0;
603
604         if (hdev->pdev->current_state == PCI_D0)
605                 i = 1;
606         else if (hdev->pdev->current_state == PCI_D3hot)
607                 i = 2;
608         else
609                 i = 3;
610
611         sprintf(tmp_buf,
612                 "current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
613         return simple_read_from_buffer(buf, count, ppos, tmp_buf,
614                         strlen(tmp_buf));
615 }
616
617 static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
618                                         size_t count, loff_t *ppos)
619 {
620         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
621         struct hl_device *hdev = entry->hdev;
622         u32 value;
623         ssize_t rc;
624
625         rc = kstrtouint_from_user(buf, count, 10, &value);
626         if (rc)
627                 return rc;
628
629         if (value == 1) {
630                 pci_set_power_state(hdev->pdev, PCI_D0);
631                 pci_restore_state(hdev->pdev);
632                 rc = pci_enable_device(hdev->pdev);
633         } else if (value == 2) {
634                 pci_save_state(hdev->pdev);
635                 pci_disable_device(hdev->pdev);
636                 pci_set_power_state(hdev->pdev, PCI_D3hot);
637         } else {
638                 dev_dbg(hdev->dev, "invalid power state value %u\n", value);
639                 return -EINVAL;
640         }
641
642         return count;
643 }
644
645 static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
646                                         size_t count, loff_t *ppos)
647 {
648         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
649         struct hl_device *hdev = entry->hdev;
650         char tmp_buf[32];
651         long val;
652         ssize_t rc;
653
654         if (*ppos)
655                 return 0;
656
657         rc = hl_debugfs_i2c_read(hdev, entry->i2c_bus, entry->i2c_addr,
658                         entry->i2c_reg, &val);
659         if (rc) {
660                 dev_err(hdev->dev,
661                         "Failed to read from I2C bus %d, addr %d, reg %d\n",
662                         entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
663                 return rc;
664         }
665
666         sprintf(tmp_buf, "0x%02lx\n", val);
667         rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
668                         strlen(tmp_buf));
669
670         return rc;
671 }
672
673 static ssize_t hl_i2c_data_write(struct file *f, const char __user *buf,
674                                         size_t count, loff_t *ppos)
675 {
676         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
677         struct hl_device *hdev = entry->hdev;
678         u32 value;
679         ssize_t rc;
680
681         rc = kstrtouint_from_user(buf, count, 16, &value);
682         if (rc)
683                 return rc;
684
685         rc = hl_debugfs_i2c_write(hdev, entry->i2c_bus, entry->i2c_addr,
686                         entry->i2c_reg, value);
687         if (rc) {
688                 dev_err(hdev->dev,
689                         "Failed to write 0x%02x to I2C bus %d, addr %d, reg %d\n",
690                         value, entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
691                 return rc;
692         }
693
694         return count;
695 }
696
697 static ssize_t hl_led0_write(struct file *f, const char __user *buf,
698                                         size_t count, loff_t *ppos)
699 {
700         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
701         struct hl_device *hdev = entry->hdev;
702         u32 value;
703         ssize_t rc;
704
705         rc = kstrtouint_from_user(buf, count, 10, &value);
706         if (rc)
707                 return rc;
708
709         value = value ? 1 : 0;
710
711         hl_debugfs_led_set(hdev, 0, value);
712
713         return count;
714 }
715
716 static ssize_t hl_led1_write(struct file *f, const char __user *buf,
717                                         size_t count, loff_t *ppos)
718 {
719         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
720         struct hl_device *hdev = entry->hdev;
721         u32 value;
722         ssize_t rc;
723
724         rc = kstrtouint_from_user(buf, count, 10, &value);
725         if (rc)
726                 return rc;
727
728         value = value ? 1 : 0;
729
730         hl_debugfs_led_set(hdev, 1, value);
731
732         return count;
733 }
734
735 static ssize_t hl_led2_write(struct file *f, const char __user *buf,
736                                         size_t count, loff_t *ppos)
737 {
738         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
739         struct hl_device *hdev = entry->hdev;
740         u32 value;
741         ssize_t rc;
742
743         rc = kstrtouint_from_user(buf, count, 10, &value);
744         if (rc)
745                 return rc;
746
747         value = value ? 1 : 0;
748
749         hl_debugfs_led_set(hdev, 2, value);
750
751         return count;
752 }
753
754 static ssize_t hl_device_read(struct file *f, char __user *buf,
755                                         size_t count, loff_t *ppos)
756 {
757         static const char *help =
758                 "Valid values: disable, enable, suspend, resume, cpu_timeout\n";
759         return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
760 }
761
762 static ssize_t hl_device_write(struct file *f, const char __user *buf,
763                                      size_t count, loff_t *ppos)
764 {
765         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
766         struct hl_device *hdev = entry->hdev;
767         char data[30] = {0};
768
769         /* don't allow partial writes */
770         if (*ppos != 0)
771                 return 0;
772
773         simple_write_to_buffer(data, 29, ppos, buf, count);
774
775         if (strncmp("disable", data, strlen("disable")) == 0) {
776                 hdev->disabled = true;
777         } else if (strncmp("enable", data, strlen("enable")) == 0) {
778                 hdev->disabled = false;
779         } else if (strncmp("suspend", data, strlen("suspend")) == 0) {
780                 hdev->asic_funcs->suspend(hdev);
781         } else if (strncmp("resume", data, strlen("resume")) == 0) {
782                 hdev->asic_funcs->resume(hdev);
783         } else if (strncmp("cpu_timeout", data, strlen("cpu_timeout")) == 0) {
784                 hdev->device_cpu_disabled = true;
785         } else {
786                 dev_err(hdev->dev,
787                         "Valid values: disable, enable, suspend, resume, cpu_timeout\n");
788                 count = -EINVAL;
789         }
790
791         return count;
792 }
793
794 static ssize_t hl_clk_gate_read(struct file *f, char __user *buf,
795                                         size_t count, loff_t *ppos)
796 {
797         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
798         struct hl_device *hdev = entry->hdev;
799         char tmp_buf[200];
800         ssize_t rc;
801
802         if (*ppos)
803                 return 0;
804
805         sprintf(tmp_buf, "0x%llx\n", hdev->clock_gating_mask);
806         rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
807                         strlen(tmp_buf) + 1);
808
809         return rc;
810 }
811
812 static ssize_t hl_clk_gate_write(struct file *f, const char __user *buf,
813                                      size_t count, loff_t *ppos)
814 {
815         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
816         struct hl_device *hdev = entry->hdev;
817         u64 value;
818         ssize_t rc;
819
820         if (atomic_read(&hdev->in_reset)) {
821                 dev_warn_ratelimited(hdev->dev,
822                                 "Can't change clock gating during reset\n");
823                 return 0;
824         }
825
826         rc = kstrtoull_from_user(buf, count, 16, &value);
827         if (rc)
828                 return rc;
829
830         hdev->clock_gating_mask = value;
831         hdev->asic_funcs->set_clock_gating(hdev);
832
833         return count;
834 }
835
836 static ssize_t hl_stop_on_err_read(struct file *f, char __user *buf,
837                                         size_t count, loff_t *ppos)
838 {
839         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
840         struct hl_device *hdev = entry->hdev;
841         char tmp_buf[200];
842         ssize_t rc;
843
844         if (*ppos)
845                 return 0;
846
847         sprintf(tmp_buf, "%d\n", hdev->stop_on_err);
848         rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
849                         strlen(tmp_buf) + 1);
850
851         return rc;
852 }
853
854 static ssize_t hl_stop_on_err_write(struct file *f, const char __user *buf,
855                                      size_t count, loff_t *ppos)
856 {
857         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
858         struct hl_device *hdev = entry->hdev;
859         u32 value;
860         ssize_t rc;
861
862         if (atomic_read(&hdev->in_reset)) {
863                 dev_warn_ratelimited(hdev->dev,
864                                 "Can't change stop on error during reset\n");
865                 return 0;
866         }
867
868         rc = kstrtouint_from_user(buf, count, 10, &value);
869         if (rc)
870                 return rc;
871
872         hdev->stop_on_err = value ? 1 : 0;
873
874         hl_device_reset(hdev, false, false);
875
876         return count;
877 }
878
879 static ssize_t hl_security_violations_read(struct file *f, char __user *buf,
880                                         size_t count, loff_t *ppos)
881 {
882         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
883         struct hl_device *hdev = entry->hdev;
884
885         hdev->asic_funcs->ack_protection_bits_errors(hdev);
886
887         return 0;
888 }
889
890 static const struct file_operations hl_data32b_fops = {
891         .owner = THIS_MODULE,
892         .read = hl_data_read32,
893         .write = hl_data_write32
894 };
895
896 static const struct file_operations hl_data64b_fops = {
897         .owner = THIS_MODULE,
898         .read = hl_data_read64,
899         .write = hl_data_write64
900 };
901
902 static const struct file_operations hl_i2c_data_fops = {
903         .owner = THIS_MODULE,
904         .read = hl_i2c_data_read,
905         .write = hl_i2c_data_write
906 };
907
908 static const struct file_operations hl_power_fops = {
909         .owner = THIS_MODULE,
910         .read = hl_get_power_state,
911         .write = hl_set_power_state
912 };
913
914 static const struct file_operations hl_led0_fops = {
915         .owner = THIS_MODULE,
916         .write = hl_led0_write
917 };
918
919 static const struct file_operations hl_led1_fops = {
920         .owner = THIS_MODULE,
921         .write = hl_led1_write
922 };
923
924 static const struct file_operations hl_led2_fops = {
925         .owner = THIS_MODULE,
926         .write = hl_led2_write
927 };
928
929 static const struct file_operations hl_device_fops = {
930         .owner = THIS_MODULE,
931         .read = hl_device_read,
932         .write = hl_device_write
933 };
934
935 static const struct file_operations hl_clk_gate_fops = {
936         .owner = THIS_MODULE,
937         .read = hl_clk_gate_read,
938         .write = hl_clk_gate_write
939 };
940
941 static const struct file_operations hl_stop_on_err_fops = {
942         .owner = THIS_MODULE,
943         .read = hl_stop_on_err_read,
944         .write = hl_stop_on_err_write
945 };
946
947 static const struct file_operations hl_security_violations_fops = {
948         .owner = THIS_MODULE,
949         .read = hl_security_violations_read
950 };
951
952 static const struct hl_info_list hl_debugfs_list[] = {
953         {"command_buffers", command_buffers_show, NULL},
954         {"command_submission", command_submission_show, NULL},
955         {"command_submission_jobs", command_submission_jobs_show, NULL},
956         {"userptr", userptr_show, NULL},
957         {"vm", vm_show, NULL},
958         {"mmu", mmu_show, mmu_asid_va_write},
959         {"engines", engines_show, NULL}
960 };
961
962 static int hl_debugfs_open(struct inode *inode, struct file *file)
963 {
964         struct hl_debugfs_entry *node = inode->i_private;
965
966         return single_open(file, node->info_ent->show, node);
967 }
968
969 static ssize_t hl_debugfs_write(struct file *file, const char __user *buf,
970                 size_t count, loff_t *f_pos)
971 {
972         struct hl_debugfs_entry *node = file->f_inode->i_private;
973
974         if (node->info_ent->write)
975                 return node->info_ent->write(file, buf, count, f_pos);
976         else
977                 return -EINVAL;
978
979 }
980
981 static const struct file_operations hl_debugfs_fops = {
982         .owner = THIS_MODULE,
983         .open = hl_debugfs_open,
984         .read = seq_read,
985         .write = hl_debugfs_write,
986         .llseek = seq_lseek,
987         .release = single_release,
988 };
989
990 void hl_debugfs_add_device(struct hl_device *hdev)
991 {
992         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
993         int count = ARRAY_SIZE(hl_debugfs_list);
994         struct hl_debugfs_entry *entry;
995         int i;
996
997         dev_entry->hdev = hdev;
998         dev_entry->entry_arr = kmalloc_array(count,
999                                         sizeof(struct hl_debugfs_entry),
1000                                         GFP_KERNEL);
1001         if (!dev_entry->entry_arr)
1002                 return;
1003
1004         INIT_LIST_HEAD(&dev_entry->file_list);
1005         INIT_LIST_HEAD(&dev_entry->cb_list);
1006         INIT_LIST_HEAD(&dev_entry->cs_list);
1007         INIT_LIST_HEAD(&dev_entry->cs_job_list);
1008         INIT_LIST_HEAD(&dev_entry->userptr_list);
1009         INIT_LIST_HEAD(&dev_entry->ctx_mem_hash_list);
1010         mutex_init(&dev_entry->file_mutex);
1011         spin_lock_init(&dev_entry->cb_spinlock);
1012         spin_lock_init(&dev_entry->cs_spinlock);
1013         spin_lock_init(&dev_entry->cs_job_spinlock);
1014         spin_lock_init(&dev_entry->userptr_spinlock);
1015         spin_lock_init(&dev_entry->ctx_mem_hash_spinlock);
1016
1017         dev_entry->root = debugfs_create_dir(dev_name(hdev->dev),
1018                                                 hl_debug_root);
1019
1020         debugfs_create_x64("addr",
1021                                 0644,
1022                                 dev_entry->root,
1023                                 &dev_entry->addr);
1024
1025         debugfs_create_file("data32",
1026                                 0644,
1027                                 dev_entry->root,
1028                                 dev_entry,
1029                                 &hl_data32b_fops);
1030
1031         debugfs_create_file("data64",
1032                                 0644,
1033                                 dev_entry->root,
1034                                 dev_entry,
1035                                 &hl_data64b_fops);
1036
1037         debugfs_create_file("set_power_state",
1038                                 0200,
1039                                 dev_entry->root,
1040                                 dev_entry,
1041                                 &hl_power_fops);
1042
1043         debugfs_create_u8("i2c_bus",
1044                                 0644,
1045                                 dev_entry->root,
1046                                 &dev_entry->i2c_bus);
1047
1048         debugfs_create_u8("i2c_addr",
1049                                 0644,
1050                                 dev_entry->root,
1051                                 &dev_entry->i2c_addr);
1052
1053         debugfs_create_u8("i2c_reg",
1054                                 0644,
1055                                 dev_entry->root,
1056                                 &dev_entry->i2c_reg);
1057
1058         debugfs_create_file("i2c_data",
1059                                 0644,
1060                                 dev_entry->root,
1061                                 dev_entry,
1062                                 &hl_i2c_data_fops);
1063
1064         debugfs_create_file("led0",
1065                                 0200,
1066                                 dev_entry->root,
1067                                 dev_entry,
1068                                 &hl_led0_fops);
1069
1070         debugfs_create_file("led1",
1071                                 0200,
1072                                 dev_entry->root,
1073                                 dev_entry,
1074                                 &hl_led1_fops);
1075
1076         debugfs_create_file("led2",
1077                                 0200,
1078                                 dev_entry->root,
1079                                 dev_entry,
1080                                 &hl_led2_fops);
1081
1082         debugfs_create_file("device",
1083                                 0200,
1084                                 dev_entry->root,
1085                                 dev_entry,
1086                                 &hl_device_fops);
1087
1088         debugfs_create_file("clk_gate",
1089                                 0200,
1090                                 dev_entry->root,
1091                                 dev_entry,
1092                                 &hl_clk_gate_fops);
1093
1094         debugfs_create_file("stop_on_err",
1095                                 0644,
1096                                 dev_entry->root,
1097                                 dev_entry,
1098                                 &hl_stop_on_err_fops);
1099
1100         debugfs_create_file("dump_security_violations",
1101                                 0644,
1102                                 dev_entry->root,
1103                                 dev_entry,
1104                                 &hl_security_violations_fops);
1105
1106         for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
1107                 debugfs_create_file(hl_debugfs_list[i].name,
1108                                         0444,
1109                                         dev_entry->root,
1110                                         entry,
1111                                         &hl_debugfs_fops);
1112                 entry->info_ent = &hl_debugfs_list[i];
1113                 entry->dev_entry = dev_entry;
1114         }
1115 }
1116
1117 void hl_debugfs_remove_device(struct hl_device *hdev)
1118 {
1119         struct hl_dbg_device_entry *entry = &hdev->hl_debugfs;
1120
1121         debugfs_remove_recursive(entry->root);
1122
1123         mutex_destroy(&entry->file_mutex);
1124         kfree(entry->entry_arr);
1125 }
1126
1127 void hl_debugfs_add_file(struct hl_fpriv *hpriv)
1128 {
1129         struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1130
1131         mutex_lock(&dev_entry->file_mutex);
1132         list_add(&hpriv->debugfs_list, &dev_entry->file_list);
1133         mutex_unlock(&dev_entry->file_mutex);
1134 }
1135
1136 void hl_debugfs_remove_file(struct hl_fpriv *hpriv)
1137 {
1138         struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1139
1140         mutex_lock(&dev_entry->file_mutex);
1141         list_del(&hpriv->debugfs_list);
1142         mutex_unlock(&dev_entry->file_mutex);
1143 }
1144
1145 void hl_debugfs_add_cb(struct hl_cb *cb)
1146 {
1147         struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1148
1149         spin_lock(&dev_entry->cb_spinlock);
1150         list_add(&cb->debugfs_list, &dev_entry->cb_list);
1151         spin_unlock(&dev_entry->cb_spinlock);
1152 }
1153
1154 void hl_debugfs_remove_cb(struct hl_cb *cb)
1155 {
1156         struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1157
1158         spin_lock(&dev_entry->cb_spinlock);
1159         list_del(&cb->debugfs_list);
1160         spin_unlock(&dev_entry->cb_spinlock);
1161 }
1162
1163 void hl_debugfs_add_cs(struct hl_cs *cs)
1164 {
1165         struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1166
1167         spin_lock(&dev_entry->cs_spinlock);
1168         list_add(&cs->debugfs_list, &dev_entry->cs_list);
1169         spin_unlock(&dev_entry->cs_spinlock);
1170 }
1171
1172 void hl_debugfs_remove_cs(struct hl_cs *cs)
1173 {
1174         struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1175
1176         spin_lock(&dev_entry->cs_spinlock);
1177         list_del(&cs->debugfs_list);
1178         spin_unlock(&dev_entry->cs_spinlock);
1179 }
1180
1181 void hl_debugfs_add_job(struct hl_device *hdev, struct hl_cs_job *job)
1182 {
1183         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1184
1185         spin_lock(&dev_entry->cs_job_spinlock);
1186         list_add(&job->debugfs_list, &dev_entry->cs_job_list);
1187         spin_unlock(&dev_entry->cs_job_spinlock);
1188 }
1189
1190 void hl_debugfs_remove_job(struct hl_device *hdev, struct hl_cs_job *job)
1191 {
1192         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1193
1194         spin_lock(&dev_entry->cs_job_spinlock);
1195         list_del(&job->debugfs_list);
1196         spin_unlock(&dev_entry->cs_job_spinlock);
1197 }
1198
1199 void hl_debugfs_add_userptr(struct hl_device *hdev, struct hl_userptr *userptr)
1200 {
1201         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1202
1203         spin_lock(&dev_entry->userptr_spinlock);
1204         list_add(&userptr->debugfs_list, &dev_entry->userptr_list);
1205         spin_unlock(&dev_entry->userptr_spinlock);
1206 }
1207
1208 void hl_debugfs_remove_userptr(struct hl_device *hdev,
1209                                 struct hl_userptr *userptr)
1210 {
1211         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1212
1213         spin_lock(&dev_entry->userptr_spinlock);
1214         list_del(&userptr->debugfs_list);
1215         spin_unlock(&dev_entry->userptr_spinlock);
1216 }
1217
1218 void hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1219 {
1220         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1221
1222         spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1223         list_add(&ctx->debugfs_list, &dev_entry->ctx_mem_hash_list);
1224         spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1225 }
1226
1227 void hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1228 {
1229         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1230
1231         spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1232         list_del(&ctx->debugfs_list);
1233         spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1234 }
1235
1236 void __init hl_debugfs_init(void)
1237 {
1238         hl_debug_root = debugfs_create_dir("habanalabs", NULL);
1239 }
1240
1241 void hl_debugfs_fini(void)
1242 {
1243         debugfs_remove_recursive(hl_debug_root);
1244 }