hw_fence_drv_debug.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #ifndef __HW_FENCE_DRV_DEBUG
  6. #define __HW_FENCE_DRV_DEBUG
  7. #include "hw_fence_drv_ipc.h"
  8. #define HW_FENCE_NAME_SIZE 64
  9. enum hw_fence_drv_prio {
  10. HW_FENCE_HIGH = 0x000001, /* High density debug messages (noisy) */
  11. HW_FENCE_LOW = 0x000002, /* Low density debug messages */
  12. HW_FENCE_INFO = 0x000004, /* Informational prints */
  13. HW_FENCE_INIT = 0x00008, /* Initialization logs */
  14. HW_FENCE_QUEUE = 0x000010, /* Queue logs */
  15. HW_FENCE_LUT = 0x000020, /* Look-up and algorithm logs */
  16. HW_FENCE_IRQ = 0x000040, /* Interrupt-related messages */
  17. HW_FENCE_LOCK = 0x000080, /* Lock-related messages */
  18. HW_FENCE_PRINTK = 0x010000,
  19. };
  20. extern u32 msm_hw_fence_debug_level;
  21. #define dprintk(__level, __fmt, ...) \
  22. do { \
  23. if (msm_hw_fence_debug_level & __level) \
  24. if (msm_hw_fence_debug_level & HW_FENCE_PRINTK) \
  25. pr_err(__fmt, ##__VA_ARGS__); \
  26. } while (0)
  27. #define HWFNC_ERR(fmt, ...) \
  28. pr_err("[hwfence:%s:%d][err][%pS] "fmt, __func__, __LINE__, \
  29. __builtin_return_address(0), ##__VA_ARGS__)
  30. #define HWFNC_DBG_H(fmt, ...) \
  31. dprintk(HW_FENCE_HIGH, "[hwfence:%s:%d][dbgh]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  32. #define HWFNC_DBG_L(fmt, ...) \
  33. dprintk(HW_FENCE_LOW, "[hwfence:%s:%d][dbgl]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  34. #define HWFNC_DBG_INFO(fmt, ...) \
  35. dprintk(HW_FENCE_INFO, "[hwfence:%s:%d][dbgi]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  36. #define HWFNC_DBG_INIT(fmt, ...) \
  37. dprintk(HW_FENCE_INIT, "[hwfence:%s:%d][dbg]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  38. #define HWFNC_DBG_Q(fmt, ...) \
  39. dprintk(HW_FENCE_QUEUE, "[hwfence:%s:%d][dbgq]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  40. #define HWFNC_DBG_LUT(fmt, ...) \
  41. dprintk(HW_FENCE_LUT, "[hwfence:%s:%d][dbglut]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  42. #define HWFNC_DBG_IRQ(fmt, ...) \
  43. dprintk(HW_FENCE_IRQ, "[hwfence:%s:%d][dbgirq]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  44. #define HWFNC_DBG_LOCK(fmt, ...) \
  45. dprintk(HW_FENCE_LOCK, "[hwfence:%s:%d][dbglock]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  46. #define HWFNC_DBG_DUMP(prio, fmt, ...) \
  47. dprintk(prio, "[hwfence:%s:%d][dbgd]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  48. #define HWFNC_WARN(fmt, ...) \
  49. pr_warn("[hwfence:%s:%d][warn][%pS] "fmt, __func__, __LINE__, \
  50. __builtin_return_address(0), ##__VA_ARGS__)
  51. int hw_fence_debug_debugfs_register(struct hw_fence_driver_data *drv_data);
  52. #if IS_ENABLED(CONFIG_DEBUG_FS)
  53. int process_validation_client_loopback(struct hw_fence_driver_data *drv_data, int client_id);
  54. void hw_fence_debug_dump_queues(enum hw_fence_drv_prio prio,
  55. struct msm_hw_fence_client *hw_fence_client);
  56. void hw_fence_debug_dump_fence(enum hw_fence_drv_prio prio, struct msm_hw_fence *hw_fence, u64 hash,
  57. u32 count);
  58. void hw_fence_debug_dump_table(enum hw_fence_drv_prio prio, struct hw_fence_driver_data *drv_data);
  59. void hw_fence_debug_dump_events(enum hw_fence_drv_prio prio, struct hw_fence_driver_data *drv_data);
  60. extern const struct file_operations hw_sync_debugfs_fops;
  61. struct hw_fence_out_clients_map {
  62. int ipc_client_id_vid; /* ipc client virtual id for the hw fence client */
  63. int ipc_client_id_pid; /* ipc client physical id for the hw fence client */
  64. int ipc_signal_id; /* ipc signal id for the hw fence client */
  65. };
  66. /* These signals are the ones that the actual clients should be triggering, hw-fence driver
  67. * does not need to have knowledge of these signals. Adding them here for debugging purposes.
  68. * Only fence controller and the cliens know these id's, since these
  69. * are to trigger the ipcc from the 'client hw-core' to the 'hw-fence controller'
  70. * The index of this struct must match the enum hw_fence_client_id
  71. */
  72. static const struct hw_fence_out_clients_map
  73. dbg_out_clients_signal_map_no_dpu[HW_FENCE_CLIENT_ID_VAL6 + 1] = {
  74. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 0}, /* CTRL_LOOPBACK */
  75. {HW_FENCE_IPC_CLIENT_ID_GPU_VID, HW_FENCE_IPC_CLIENT_ID_GPU_VID, 0}, /* CTX0 */
  76. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 2}, /* CTL0 */
  77. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 4}, /* CTL1 */
  78. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 6}, /* CTL2 */
  79. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 8}, /* CTL3 */
  80. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 10}, /* CTL4 */
  81. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 12}, /* CTL5 */
  82. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 21}, /* VAL0 */
  83. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 22}, /* VAL1 */
  84. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 23}, /* VAL2 */
  85. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 24}, /* VAL3 */
  86. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 25}, /* VAL4 */
  87. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 26}, /* VAL5 */
  88. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 27}, /* VAL6 */
  89. };
  90. /**
  91. * struct hw_dma_fence - fences created by hw-fence for debugging.
  92. * @base: base dma-fence structure, this must remain at beginning of the struct.
  93. * @name: name of each fence.
  94. * @client_handle: handle for the client owner of this fence, this is returned by the hw-fence
  95. * driver after a successful registration of the client and used by this fence
  96. * during release.
  97. */
  98. struct hw_dma_fence {
  99. struct dma_fence base;
  100. char name[HW_FENCE_NAME_SIZE];
  101. void *client_handle;
  102. };
  103. static inline struct hw_dma_fence *to_hw_dma_fence(struct dma_fence *fence)
  104. {
  105. return container_of(fence, struct hw_dma_fence, base);
  106. }
  107. static inline void _cleanup_fences(int i, struct dma_fence **fences, spinlock_t **fences_lock)
  108. {
  109. struct hw_dma_fence *dma_fence;
  110. int fence_idx;
  111. for (fence_idx = i; fence_idx >= 0 ; fence_idx--) {
  112. kfree(fences_lock[fence_idx]);
  113. dma_fence = to_hw_dma_fence(fences[fence_idx]);
  114. kfree(dma_fence);
  115. }
  116. kfree(fences_lock);
  117. kfree(fences);
  118. }
  119. static const char *hw_fence_dbg_get_driver_name(struct dma_fence *fence)
  120. {
  121. struct hw_dma_fence *hw_dma_fence = to_hw_dma_fence(fence);
  122. return hw_dma_fence->name;
  123. }
  124. static const char *hw_fence_dbg_get_timeline_name(struct dma_fence *fence)
  125. {
  126. struct hw_dma_fence *hw_dma_fence = to_hw_dma_fence(fence);
  127. return hw_dma_fence->name;
  128. }
  129. static bool hw_fence_dbg_enable_signaling(struct dma_fence *fence)
  130. {
  131. return true;
  132. }
  133. static void _hw_fence_release(struct hw_dma_fence *hw_dma_fence)
  134. {
  135. if (IS_ERR_OR_NULL(hw_dma_fence->client_handle)) {
  136. HWFNC_ERR("invalid hwfence data, won't release hw_fence!\n");
  137. return;
  138. }
  139. /* release hw-fence */
  140. if (msm_hw_fence_destroy(hw_dma_fence->client_handle, &hw_dma_fence->base))
  141. HWFNC_ERR("failed to release hw_fence!\n");
  142. }
  143. static void hw_fence_dbg_release(struct dma_fence *fence)
  144. {
  145. struct hw_dma_fence *hw_dma_fence;
  146. if (!fence)
  147. return;
  148. HWFNC_DBG_H("release backing fence %pK\n", fence);
  149. hw_dma_fence = to_hw_dma_fence(fence);
  150. if (test_bit(MSM_HW_FENCE_FLAG_ENABLED_BIT, &fence->flags))
  151. _hw_fence_release(hw_dma_fence);
  152. kfree(fence->lock);
  153. kfree(hw_dma_fence);
  154. }
  155. static struct dma_fence_ops hw_fence_dbg_ops = {
  156. .get_driver_name = hw_fence_dbg_get_driver_name,
  157. .get_timeline_name = hw_fence_dbg_get_timeline_name,
  158. .enable_signaling = hw_fence_dbg_enable_signaling,
  159. .wait = dma_fence_default_wait,
  160. .release = hw_fence_dbg_release,
  161. };
  162. #endif /* CONFIG_DEBUG_FS */
  163. #endif /* __HW_FENCE_DRV_DEBUG */