hw_fence_drv_debug.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2022 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_WARN(fmt, ...) \
  47. pr_warn("[hwfence:%s:%d][warn][%pS] "fmt, __func__, __LINE__, \
  48. __builtin_return_address(0), ##__VA_ARGS__)
  49. int hw_fence_debug_debugfs_register(struct hw_fence_driver_data *drv_data);
  50. #if IS_ENABLED(CONFIG_DEBUG_FS)
  51. int process_validation_client_loopback(struct hw_fence_driver_data *drv_data, int client_id);
  52. extern const struct file_operations hw_sync_debugfs_fops;
  53. struct hw_fence_out_clients_map {
  54. int ipc_client_id_vid; /* ipc client virtual id for the hw fence client */
  55. int ipc_client_id_pid; /* ipc client physical id for the hw fence client */
  56. int ipc_signal_id; /* ipc signal id for the hw fence client */
  57. };
  58. /* These signals are the ones that the actual clients should be triggering, hw-fence driver
  59. * does not need to have knowledge of these signals. Adding them here for debugging purposes.
  60. * Only fence controller and the cliens know these id's, since these
  61. * are to trigger the ipcc from the 'client hw-core' to the 'hw-fence controller'
  62. * The index of this struct must match the enum hw_fence_client_id
  63. */
  64. static const struct hw_fence_out_clients_map
  65. dbg_out_clients_signal_map_no_dpu[HW_FENCE_CLIENT_ID_VAL6 + 1] = {
  66. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 0}, /* CTRL_LOOPBACK */
  67. {HW_FENCE_IPC_CLIENT_ID_GPU_VID, HW_FENCE_IPC_CLIENT_ID_GPU_VID, 0}, /* CTX0 */
  68. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 2}, /* CTL0 */
  69. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 4}, /* CTL1 */
  70. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 6}, /* CTL2 */
  71. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 8}, /* CTL3 */
  72. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 10}, /* CTL4 */
  73. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 12}, /* CTL5 */
  74. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 21}, /* VAL0 */
  75. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 22}, /* VAL1 */
  76. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 23}, /* VAL2 */
  77. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 24}, /* VAL3 */
  78. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 25}, /* VAL4 */
  79. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 26}, /* VAL5 */
  80. {HW_FENCE_IPC_CLIENT_ID_APPS_VID, HW_FENCE_IPC_CLIENT_ID_APPS_VID, 27}, /* VAL6 */
  81. };
  82. /**
  83. * struct hw_dma_fence - fences created by hw-fence for debugging.
  84. * @base: base dma-fence structure, this must remain at beginning of the struct.
  85. * @name: name of each fence.
  86. * @client_handle: handle for the client owner of this fence, this is returned by the hw-fence
  87. * driver after a successful registration of the client and used by this fence
  88. * during release.
  89. */
  90. struct hw_dma_fence {
  91. struct dma_fence base;
  92. char name[HW_FENCE_NAME_SIZE];
  93. void *client_handle;
  94. };
  95. static inline struct hw_dma_fence *to_hw_dma_fence(struct dma_fence *fence)
  96. {
  97. return container_of(fence, struct hw_dma_fence, base);
  98. }
  99. static inline void _cleanup_fences(int i, struct dma_fence **fences, spinlock_t **fences_lock)
  100. {
  101. struct hw_dma_fence *dma_fence;
  102. int fence_idx;
  103. for (fence_idx = i; fence_idx >= 0 ; fence_idx--) {
  104. kfree(fences_lock[fence_idx]);
  105. dma_fence = to_hw_dma_fence(fences[fence_idx]);
  106. kfree(dma_fence);
  107. }
  108. kfree(fences_lock);
  109. kfree(fences);
  110. }
  111. static const char *hw_fence_dbg_get_driver_name(struct dma_fence *fence)
  112. {
  113. struct hw_dma_fence *hw_dma_fence = to_hw_dma_fence(fence);
  114. return hw_dma_fence->name;
  115. }
  116. static const char *hw_fence_dbg_get_timeline_name(struct dma_fence *fence)
  117. {
  118. struct hw_dma_fence *hw_dma_fence = to_hw_dma_fence(fence);
  119. return hw_dma_fence->name;
  120. }
  121. static bool hw_fence_dbg_enable_signaling(struct dma_fence *fence)
  122. {
  123. return true;
  124. }
  125. static void _hw_fence_release(struct hw_dma_fence *hw_dma_fence)
  126. {
  127. if (IS_ERR_OR_NULL(hw_dma_fence->client_handle)) {
  128. HWFNC_ERR("invalid hwfence data, won't release hw_fence!\n");
  129. return;
  130. }
  131. /* release hw-fence */
  132. if (msm_hw_fence_destroy(hw_dma_fence->client_handle, &hw_dma_fence->base))
  133. HWFNC_ERR("failed to release hw_fence!\n");
  134. }
  135. static void hw_fence_dbg_release(struct dma_fence *fence)
  136. {
  137. struct hw_dma_fence *hw_dma_fence;
  138. if (!fence)
  139. return;
  140. HWFNC_DBG_H("release backing fence %pK\n", fence);
  141. hw_dma_fence = to_hw_dma_fence(fence);
  142. if (test_bit(MSM_HW_FENCE_FLAG_ENABLED_BIT, &fence->flags))
  143. _hw_fence_release(hw_dma_fence);
  144. kfree(fence->lock);
  145. kfree(hw_dma_fence);
  146. }
  147. static struct dma_fence_ops hw_fence_dbg_ops = {
  148. .get_driver_name = hw_fence_dbg_get_driver_name,
  149. .get_timeline_name = hw_fence_dbg_get_timeline_name,
  150. .enable_signaling = hw_fence_dbg_enable_signaling,
  151. .wait = dma_fence_default_wait,
  152. .release = hw_fence_dbg_release,
  153. };
  154. #endif /* CONFIG_DEBUG_FS */
  155. #endif /* __HW_FENCE_DRV_DEBUG */