hw_fence_drv_debug.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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_PRINTK = 0x010000,
  18. };
  19. extern u32 msm_hw_fence_debug_level;
  20. #define dprintk(__level, __fmt, ...) \
  21. do { \
  22. if (msm_hw_fence_debug_level & __level) \
  23. if (msm_hw_fence_debug_level & HW_FENCE_PRINTK) \
  24. pr_err(__fmt, ##__VA_ARGS__); \
  25. } while (0)
  26. #define HWFNC_ERR(fmt, ...) \
  27. pr_err("[hwfence:%s:%d][err][%pS] "fmt, __func__, __LINE__, \
  28. __builtin_return_address(0), ##__VA_ARGS__)
  29. #define HWFNC_DBG_H(fmt, ...) \
  30. dprintk(HW_FENCE_HIGH, "[hwfence:%s:%d][dbgh]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  31. #define HWFNC_DBG_L(fmt, ...) \
  32. dprintk(HW_FENCE_LOW, "[hwfence:%s:%d][dbgl]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  33. #define HWFNC_DBG_INFO(fmt, ...) \
  34. dprintk(HW_FENCE_INFO, "[hwfence:%s:%d][dbgi]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  35. #define HWFNC_DBG_INIT(fmt, ...) \
  36. dprintk(HW_FENCE_INIT, "[hwfence:%s:%d][dbg]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  37. #define HWFNC_DBG_Q(fmt, ...) \
  38. dprintk(HW_FENCE_QUEUE, "[hwfence:%s:%d][dbgq]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  39. #define HWFNC_DBG_LUT(fmt, ...) \
  40. dprintk(HW_FENCE_LUT, "[hwfence:%s:%d][dbglut]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  41. #define HWFNC_DBG_IRQ(fmt, ...) \
  42. dprintk(HW_FENCE_IRQ, "[hwfence:%s:%d][dbgirq]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  43. #define HWFNC_WARN(fmt, ...) \
  44. pr_warn("[hwfence:%s:%d][warn][%pS] "fmt, __func__, __LINE__, \
  45. __builtin_return_address(0), ##__VA_ARGS__)
  46. int hw_fence_debug_debugfs_register(struct hw_fence_driver_data *drv_data);
  47. #if IS_ENABLED(CONFIG_DEBUG_FS)
  48. int process_validation_client_loopback(struct hw_fence_driver_data *drv_data, int client_id);
  49. extern const struct file_operations hw_sync_debugfs_fops;
  50. struct hw_fence_out_clients_map {
  51. int ipc_client_id; /* ipc client id for the hw fence client */
  52. int ipc_signal_id; /* ipc signal id for the hw fence client */
  53. };
  54. /* These signals are the ones that the actual clients should be triggering, hw-fence driver
  55. * does not need to have knowledge of these signals. Adding them here for debugging purposes.
  56. * Only fence controller and the cliens know these id's, since these
  57. * are to trigger the ipcc from the 'client hw-core' to the 'hw-fence controller'
  58. * The index of this struct must match the enum hw_fence_client_id
  59. */
  60. static const struct hw_fence_out_clients_map
  61. dbg_out_clients_signal_map_no_dpu[HW_FENCE_CLIENT_MAX] = {
  62. {HW_FENCE_IPC_CLIENT_ID_APPS, 0}, /* CTRL_LOOPBACK */
  63. {HW_FENCE_IPC_CLIENT_ID_GPU, 0}, /* CTX0 */
  64. {HW_FENCE_IPC_CLIENT_ID_APPS, 2}, /* CTL0 */
  65. {HW_FENCE_IPC_CLIENT_ID_APPS, 4}, /* CTL1 */
  66. {HW_FENCE_IPC_CLIENT_ID_APPS, 6}, /* CTL2 */
  67. {HW_FENCE_IPC_CLIENT_ID_APPS, 8}, /* CTL3 */
  68. {HW_FENCE_IPC_CLIENT_ID_APPS, 10}, /* CTL4 */
  69. {HW_FENCE_IPC_CLIENT_ID_APPS, 12}, /* CTL5 */
  70. {HW_FENCE_IPC_CLIENT_ID_APPS, 21}, /* VAL0 */
  71. {HW_FENCE_IPC_CLIENT_ID_APPS, 22}, /* VAL1 */
  72. {HW_FENCE_IPC_CLIENT_ID_APPS, 23}, /* VAL2 */
  73. {HW_FENCE_IPC_CLIENT_ID_APPS, 24}, /* VAL3 */
  74. {HW_FENCE_IPC_CLIENT_ID_APPS, 25}, /* VAL4 */
  75. {HW_FENCE_IPC_CLIENT_ID_APPS, 26}, /* VAL5 */
  76. {HW_FENCE_IPC_CLIENT_ID_APPS, 27}, /* VAL6 */
  77. };
  78. /**
  79. * struct hw_dma_fence - fences created by hw-fence for debugging.
  80. * @base: base dma-fence structure, this must remain at beginning of the struct.
  81. * @name: name of each fence.
  82. * @client_handle: handle for the client owner of this fence, this is returned by the hw-fence
  83. * driver after a successful registration of the client and used by this fence
  84. * during release.
  85. */
  86. struct hw_dma_fence {
  87. struct dma_fence base;
  88. char name[HW_FENCE_NAME_SIZE];
  89. void *client_handle;
  90. };
  91. static inline struct hw_dma_fence *to_hw_dma_fence(struct dma_fence *fence)
  92. {
  93. return container_of(fence, struct hw_dma_fence, base);
  94. }
  95. static inline void _cleanup_fences(int i, struct dma_fence **fences, spinlock_t **fences_lock)
  96. {
  97. struct hw_dma_fence *dma_fence;
  98. int fence_idx;
  99. for (fence_idx = i; fence_idx >= 0 ; fence_idx--) {
  100. kfree(fences_lock[fence_idx]);
  101. dma_fence = to_hw_dma_fence(fences[fence_idx]);
  102. kfree(dma_fence);
  103. }
  104. kfree(fences_lock);
  105. kfree(fences);
  106. }
  107. static const char *hw_fence_dbg_get_driver_name(struct dma_fence *fence)
  108. {
  109. struct hw_dma_fence *hw_dma_fence = to_hw_dma_fence(fence);
  110. return hw_dma_fence->name;
  111. }
  112. static const char *hw_fence_dbg_get_timeline_name(struct dma_fence *fence)
  113. {
  114. struct hw_dma_fence *hw_dma_fence = to_hw_dma_fence(fence);
  115. return hw_dma_fence->name;
  116. }
  117. static bool hw_fence_dbg_enable_signaling(struct dma_fence *fence)
  118. {
  119. return true;
  120. }
  121. static void _hw_fence_release(struct hw_dma_fence *hw_dma_fence)
  122. {
  123. if (IS_ERR_OR_NULL(hw_dma_fence->client_handle)) {
  124. HWFNC_ERR("invalid hwfence data, won't release hw_fence!\n");
  125. return;
  126. }
  127. /* release hw-fence */
  128. if (msm_hw_fence_destroy(hw_dma_fence->client_handle, &hw_dma_fence->base))
  129. HWFNC_ERR("failed to release hw_fence!\n");
  130. }
  131. static void hw_fence_dbg_release(struct dma_fence *fence)
  132. {
  133. struct hw_dma_fence *hw_dma_fence;
  134. if (!fence)
  135. return;
  136. HWFNC_DBG_H("release backing fence %pK\n", fence);
  137. hw_dma_fence = to_hw_dma_fence(fence);
  138. if (test_bit(MSM_HW_FENCE_FLAG_ENABLED_BIT, &fence->flags))
  139. _hw_fence_release(hw_dma_fence);
  140. kfree(fence->lock);
  141. kfree(hw_dma_fence);
  142. }
  143. static struct dma_fence_ops hw_fence_dbg_ops = {
  144. .get_driver_name = hw_fence_dbg_get_driver_name,
  145. .get_timeline_name = hw_fence_dbg_get_timeline_name,
  146. .enable_signaling = hw_fence_dbg_enable_signaling,
  147. .wait = dma_fence_default_wait,
  148. .release = hw_fence_dbg_release,
  149. };
  150. #endif /* CONFIG_DEBUG_FS */
  151. #endif /* __HW_FENCE_DRV_DEBUG */