adreno_ringbuffer.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #ifndef __ADRENO_RINGBUFFER_H
  7. #define __ADRENO_RINGBUFFER_H
  8. /* Given a ringbuffer, return the adreno device that owns it */
  9. #define _RB_OFFSET(_id) (offsetof(struct adreno_device, ringbuffers) + \
  10. ((_id) * sizeof(struct adreno_ringbuffer)))
  11. #define ADRENO_RB_DEVICE(_rb) \
  12. ((struct adreno_device *) (((void *) (_rb)) - _RB_OFFSET((_rb)->id)))
  13. /* Adreno ringbuffer size in bytes */
  14. #define KGSL_RB_SIZE (32 * 1024)
  15. /*
  16. * A handy macro to convert the RB size to dwords since most ringbuffer
  17. * operations happen in dword increments
  18. */
  19. #define KGSL_RB_DWORDS (KGSL_RB_SIZE >> 2)
  20. /* Specifies that the command should be run in protected mode */
  21. #define F_NOTPROTECTED BIT(0)
  22. /* Indicates that the CP should wait for idle after executing the command */
  23. #define F_WFI BIT(1)
  24. /* Indicates that the poweron fixup should be executed before the command */
  25. #define F_PWRON_FIXUP BIT(2)
  26. /* Indicates that the submission should be secure */
  27. #define F_SECURE BIT(3)
  28. /* Indicates that the IBs in the submission should be skipped */
  29. #define F_SKIP BIT(4)
  30. /* Indicates that user always on timer profiling is enabled */
  31. #define F_USER_PROFILE BIT(5)
  32. /* Indicates that kernel always on timer profiling is enabled */
  33. #define F_KERNEL_PROFILE BIT(6)
  34. /* Indicates that the submission has a preamble */
  35. #define F_PREAMBLE BIT(7)
  36. #define IS_NOTPROTECTED(flags) ((flags) & F_NOTPROTECTED)
  37. #define IS_WFI(flags) ((flags) & F_WFI)
  38. #define IS_PWRON_FIXUP(flags) ((flags) & F_PWRON_FIXUP)
  39. #define IS_SECURE(flags) ((flags) & F_SECURE)
  40. #define IS_SKIP(flags) ((flags) & F_SKIP)
  41. #define IS_USER_PROFILE(flags) ((flags) & F_USER_PROFILE)
  42. #define IS_KERNEL_PROFILE(flags) ((flags) & F_KERNEL_PROFILE)
  43. #define IS_PREAMBLE(flags) ((flags) & F_PREAMBLE)
  44. struct kgsl_device;
  45. struct kgsl_device_private;
  46. /**
  47. * struct adreno_submit_time - utility structure to store the wall clock / GPU
  48. * ticks at command submit time
  49. * @ticks: GPU ticks at submit time (from the 19.2Mhz timer)
  50. * @ktime: local clock time (in nanoseconds)
  51. * @utime: Wall clock time
  52. * @drawobj: the object that we want to profile
  53. */
  54. struct adreno_submit_time {
  55. uint64_t ticks;
  56. u64 ktime;
  57. struct timespec64 utime;
  58. struct kgsl_drawobj *drawobj;
  59. };
  60. /**
  61. * This is to keep track whether the SET_PSEUDO_REGISTER packet needs to be submitted
  62. * or not
  63. */
  64. #define ADRENO_RB_SET_PSEUDO_DONE 0
  65. /**
  66. * struct adreno_ringbuffer - Definition for an adreno ringbuffer object
  67. * @flags: Internal control flags for the ringbuffer
  68. * @buffer_desc: Pointer to the ringbuffer memory descriptor
  69. * @_wptr: The next value of wptr to be written to the hardware on submit
  70. * @wptr: Local copy of the wptr offset last written to hardware
  71. * @last_wptr: offset of the last wptr that was written to CFF
  72. * @rb_ctx: The context that represents a ringbuffer
  73. * @id: Priority level of the ringbuffer, also used as an ID
  74. * @fault_detect_ts: The last retired global timestamp read during fault detect
  75. * @timestamp: The RB's global timestamp
  76. * @events: A kgsl_event_group for this context - contains the list of GPU
  77. * events
  78. * @drawctxt_active: The last pagetable that this ringbuffer is set to
  79. * @preemption_desc: The memory descriptor containing
  80. * preemption info written/read by CP
  81. * @secure_preemption_desc: The memory descriptor containing
  82. * preemption info written/read by CP for secure contexts
  83. * @perfcounter_save_restore_desc: Used by CP to save/restore the perfcounter
  84. * values across preemption
  85. * and the commands to switch pagetable on the RB
  86. * @dispatch_q: The dispatcher side queue for this ringbuffer
  87. * @ts_expire_waitq: Wait queue to wait for rb timestamp to expire
  88. * @ts_expire_waitq: Wait q to wait for rb timestamp to expire
  89. * @wptr_preempt_end: Used during preemption to check that preemption occurred
  90. * at the right rptr
  91. * @gpr11: The gpr11 value of this RB
  92. * @preempted_midway: Indicates that the RB was preempted before rptr = wptr
  93. * @preempt_lock: Lock to protect the wptr pointer while it is being updated
  94. * @skip_inline_wptr: Used during preemption to make sure wptr is updated in
  95. * hardware
  96. */
  97. struct adreno_ringbuffer {
  98. unsigned long flags;
  99. struct kgsl_memdesc *buffer_desc;
  100. unsigned int _wptr;
  101. unsigned int wptr;
  102. unsigned int last_wptr;
  103. int id;
  104. unsigned int fault_detect_ts;
  105. unsigned int timestamp;
  106. struct kgsl_event_group events;
  107. struct adreno_context *drawctxt_active;
  108. struct kgsl_memdesc *preemption_desc;
  109. struct kgsl_memdesc *secure_preemption_desc;
  110. struct kgsl_memdesc *perfcounter_save_restore_desc;
  111. struct adreno_dispatcher_drawqueue dispatch_q;
  112. wait_queue_head_t ts_expire_waitq;
  113. unsigned int wptr_preempt_end;
  114. unsigned int gpr11;
  115. int preempted_midway;
  116. spinlock_t preempt_lock;
  117. bool skip_inline_wptr;
  118. /**
  119. * @profile_desc: global memory to construct IB1s to do user side
  120. * profiling
  121. */
  122. struct kgsl_memdesc *profile_desc;
  123. /**
  124. * @profile_index: Pointer to the next "slot" in profile_desc for a user
  125. * profiling IB1. This allows for PAGE_SIZE / 16 = 256 simultaneous
  126. * commands per ringbuffer with user profiling enabled
  127. * enough.
  128. */
  129. u32 profile_index;
  130. };
  131. /* Returns the current ringbuffer */
  132. #define ADRENO_CURRENT_RINGBUFFER(a) ((a)->cur_rb)
  133. /**
  134. * adreno_ringbuffer_setup - Do generic set up on a ringbuffer
  135. * @adreno_dev: Pointer to an Adreno GPU handle
  136. * @rb: Pointer to the ringbuffer struct to set up
  137. * @id: Index of the ringbuffer
  138. *
  139. * Set up generic memory and other bits of a ringbuffer.
  140. * Return: 0 on success or negative on error.
  141. */
  142. int adreno_ringbuffer_setup(struct adreno_device *adreno_dev,
  143. struct adreno_ringbuffer *rb, int id);
  144. int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
  145. struct kgsl_drawobj_cmd *cmdobj,
  146. struct adreno_submit_time *time);
  147. void adreno_ringbuffer_stop(struct adreno_device *adreno_dev);
  148. unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb,
  149. unsigned int numcmds);
  150. int adreno_ringbuffer_waittimestamp(struct adreno_ringbuffer *rb,
  151. unsigned int timestamp,
  152. unsigned int msecs);
  153. int adreno_rb_readtimestamp(struct adreno_device *adreno_dev,
  154. void *priv, enum kgsl_timestamp_type type,
  155. unsigned int *timestamp);
  156. static inline int adreno_ringbuffer_count(struct adreno_ringbuffer *rb,
  157. unsigned int rptr)
  158. {
  159. if (rb->wptr >= rptr)
  160. return rb->wptr - rptr;
  161. return rb->wptr + KGSL_RB_DWORDS - rptr;
  162. }
  163. /* Increment a value by 4 bytes with wrap-around based on size */
  164. static inline unsigned int adreno_ringbuffer_inc_wrapped(unsigned int val,
  165. unsigned int size)
  166. {
  167. return (val + sizeof(unsigned int)) % size;
  168. }
  169. /* Decrement a value by 4 bytes with wrap-around based on size */
  170. static inline unsigned int adreno_ringbuffer_dec_wrapped(unsigned int val,
  171. unsigned int size)
  172. {
  173. return (val + size - sizeof(unsigned int)) % size;
  174. }
  175. void adreno_get_submit_time(struct adreno_device *adreno_dev,
  176. struct adreno_ringbuffer *rb,
  177. struct adreno_submit_time *time);
  178. #endif /* __ADRENO_RINGBUFFER_H */