msm_gpu.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2013 Red Hat
  4. * Author: Rob Clark <robdclark@gmail.com>
  5. */
  6. #ifndef __MSM_GPU_H__
  7. #define __MSM_GPU_H__
  8. #include <linux/adreno-smmu-priv.h>
  9. #include <linux/clk.h>
  10. #include <linux/devfreq.h>
  11. #include <linux/interconnect.h>
  12. #include <linux/pm_opp.h>
  13. #include <linux/regulator/consumer.h>
  14. #include "msm_drv.h"
  15. #include "msm_fence.h"
  16. #include "msm_ringbuffer.h"
  17. #include "msm_gem.h"
  18. struct msm_gem_submit;
  19. struct msm_gpu_perfcntr;
  20. struct msm_gpu_state;
  21. struct msm_file_private;
  22. struct msm_gpu_config {
  23. const char *ioname;
  24. unsigned int nr_rings;
  25. };
  26. /* So far, with hardware that I've seen to date, we can have:
  27. * + zero, one, or two z180 2d cores
  28. * + a3xx or a2xx 3d core, which share a common CP (the firmware
  29. * for the CP seems to implement some different PM4 packet types
  30. * but the basics of cmdstream submission are the same)
  31. *
  32. * Which means that the eventual complete "class" hierarchy, once
  33. * support for all past and present hw is in place, becomes:
  34. * + msm_gpu
  35. * + adreno_gpu
  36. * + a3xx_gpu
  37. * + a2xx_gpu
  38. * + z180_gpu
  39. */
  40. struct msm_gpu_funcs {
  41. int (*get_param)(struct msm_gpu *gpu, struct msm_file_private *ctx,
  42. uint32_t param, uint64_t *value, uint32_t *len);
  43. int (*set_param)(struct msm_gpu *gpu, struct msm_file_private *ctx,
  44. uint32_t param, uint64_t value, uint32_t len);
  45. int (*hw_init)(struct msm_gpu *gpu);
  46. /**
  47. * @ucode_load: Optional hook to upload fw to GEM objs
  48. */
  49. int (*ucode_load)(struct msm_gpu *gpu);
  50. int (*pm_suspend)(struct msm_gpu *gpu);
  51. int (*pm_resume)(struct msm_gpu *gpu);
  52. void (*submit)(struct msm_gpu *gpu, struct msm_gem_submit *submit);
  53. void (*flush)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
  54. irqreturn_t (*irq)(struct msm_gpu *irq);
  55. struct msm_ringbuffer *(*active_ring)(struct msm_gpu *gpu);
  56. void (*recover)(struct msm_gpu *gpu);
  57. void (*destroy)(struct msm_gpu *gpu);
  58. #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
  59. /* show GPU status in debugfs: */
  60. void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state,
  61. struct drm_printer *p);
  62. /* for generation specific debugfs: */
  63. void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
  64. #endif
  65. /* note: gpu_busy() can assume that we have been pm_resumed */
  66. u64 (*gpu_busy)(struct msm_gpu *gpu, unsigned long *out_sample_rate);
  67. struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
  68. int (*gpu_state_put)(struct msm_gpu_state *state);
  69. unsigned long (*gpu_get_freq)(struct msm_gpu *gpu);
  70. /* note: gpu_set_freq() can assume that we have been pm_resumed */
  71. void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp,
  72. bool suspended);
  73. struct msm_gem_address_space *(*create_address_space)
  74. (struct msm_gpu *gpu, struct platform_device *pdev);
  75. struct msm_gem_address_space *(*create_private_address_space)
  76. (struct msm_gpu *gpu);
  77. uint32_t (*get_rptr)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
  78. /**
  79. * progress: Has the GPU made progress?
  80. *
  81. * Return true if GPU position in cmdstream has advanced (or changed)
  82. * since the last call. To avoid false negatives, this should account
  83. * for cmdstream that is buffered in this FIFO upstream of the CP fw.
  84. */
  85. bool (*progress)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
  86. };
  87. /* Additional state for iommu faults: */
  88. struct msm_gpu_fault_info {
  89. u64 ttbr0;
  90. unsigned long iova;
  91. int flags;
  92. const char *type;
  93. const char *block;
  94. };
  95. /**
  96. * struct msm_gpu_devfreq - devfreq related state
  97. */
  98. struct msm_gpu_devfreq {
  99. /** devfreq: devfreq instance */
  100. struct devfreq *devfreq;
  101. /** lock: lock for "suspended", "busy_cycles", and "time" */
  102. struct mutex lock;
  103. /**
  104. * idle_freq:
  105. *
  106. * Shadow frequency used while the GPU is idle. From the PoV of
  107. * the devfreq governor, we are continuing to sample busyness and
  108. * adjust frequency while the GPU is idle, but we use this shadow
  109. * value as the GPU is actually clamped to minimum frequency while
  110. * it is inactive.
  111. */
  112. unsigned long idle_freq;
  113. /**
  114. * boost_constraint:
  115. *
  116. * A PM QoS constraint to boost min freq for a period of time
  117. * until the boost expires.
  118. */
  119. struct dev_pm_qos_request boost_freq;
  120. /**
  121. * busy_cycles: Last busy counter value, for calculating elapsed busy
  122. * cycles since last sampling period.
  123. */
  124. u64 busy_cycles;
  125. /** time: Time of last sampling period. */
  126. ktime_t time;
  127. /** idle_time: Time of last transition to idle: */
  128. ktime_t idle_time;
  129. /**
  130. * idle_work:
  131. *
  132. * Used to delay clamping to idle freq on active->idle transition.
  133. */
  134. struct msm_hrtimer_work idle_work;
  135. /**
  136. * boost_work:
  137. *
  138. * Used to reset the boost_constraint after the boost period has
  139. * elapsed
  140. */
  141. struct msm_hrtimer_work boost_work;
  142. /** suspended: tracks if we're suspended */
  143. bool suspended;
  144. };
  145. struct msm_gpu {
  146. const char *name;
  147. struct drm_device *dev;
  148. struct platform_device *pdev;
  149. const struct msm_gpu_funcs *funcs;
  150. struct adreno_smmu_priv adreno_smmu;
  151. /* performance counters (hw & sw): */
  152. spinlock_t perf_lock;
  153. bool perfcntr_active;
  154. struct {
  155. bool active;
  156. ktime_t time;
  157. } last_sample;
  158. uint32_t totaltime, activetime; /* sw counters */
  159. uint32_t last_cntrs[5]; /* hw counters */
  160. const struct msm_gpu_perfcntr *perfcntrs;
  161. uint32_t num_perfcntrs;
  162. struct msm_ringbuffer *rb[MSM_GPU_MAX_RINGS];
  163. int nr_rings;
  164. /**
  165. * sysprof_active:
  166. *
  167. * The count of contexts that have enabled system profiling.
  168. */
  169. refcount_t sysprof_active;
  170. /**
  171. * cur_ctx_seqno:
  172. *
  173. * The ctx->seqno value of the last context to submit rendering,
  174. * and the one with current pgtables installed (for generations
  175. * that support per-context pgtables). Tracked by seqno rather
  176. * than pointer value to avoid dangling pointers, and cases where
  177. * a ctx can be freed and a new one created with the same address.
  178. */
  179. int cur_ctx_seqno;
  180. /**
  181. * lock:
  182. *
  183. * General lock for serializing all the gpu things.
  184. *
  185. * TODO move to per-ring locking where feasible (ie. submit/retire
  186. * path, etc)
  187. */
  188. struct mutex lock;
  189. /**
  190. * active_submits:
  191. *
  192. * The number of submitted but not yet retired submits, used to
  193. * determine transitions between active and idle.
  194. *
  195. * Protected by active_lock
  196. */
  197. int active_submits;
  198. /** lock: protects active_submits and idle/active transitions */
  199. struct mutex active_lock;
  200. /* does gpu need hw_init? */
  201. bool needs_hw_init;
  202. /**
  203. * global_faults: number of GPU hangs not attributed to a particular
  204. * address space
  205. */
  206. int global_faults;
  207. void __iomem *mmio;
  208. int irq;
  209. struct msm_gem_address_space *aspace;
  210. /* Power Control: */
  211. struct regulator *gpu_reg, *gpu_cx;
  212. struct clk_bulk_data *grp_clks;
  213. int nr_clocks;
  214. struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk;
  215. uint32_t fast_rate;
  216. /* Hang and Inactivity Detection:
  217. */
  218. #define DRM_MSM_INACTIVE_PERIOD 66 /* in ms (roughly four frames) */
  219. #define DRM_MSM_HANGCHECK_DEFAULT_PERIOD 500 /* in ms */
  220. #define DRM_MSM_HANGCHECK_PROGRESS_RETRIES 3
  221. struct timer_list hangcheck_timer;
  222. /* Fault info for most recent iova fault: */
  223. struct msm_gpu_fault_info fault_info;
  224. /* work for handling GPU ioval faults: */
  225. struct kthread_work fault_work;
  226. /* work for handling GPU recovery: */
  227. struct kthread_work recover_work;
  228. /** retire_event: notified when submits are retired: */
  229. wait_queue_head_t retire_event;
  230. /* work for handling active-list retiring: */
  231. struct kthread_work retire_work;
  232. /* worker for retire/recover: */
  233. struct kthread_worker *worker;
  234. struct drm_gem_object *memptrs_bo;
  235. struct msm_gpu_devfreq devfreq;
  236. uint32_t suspend_count;
  237. struct msm_gpu_state *crashstate;
  238. /* True if the hardware supports expanded apriv (a650 and newer) */
  239. bool hw_apriv;
  240. /**
  241. * @allow_relocs: allow relocs in SUBMIT ioctl
  242. *
  243. * Mesa won't use relocs for driver version 1.4.0 and later. This
  244. * switch-over happened early enough in mesa a6xx bringup that we
  245. * can disallow relocs for a6xx and newer.
  246. */
  247. bool allow_relocs;
  248. struct thermal_cooling_device *cooling;
  249. };
  250. static inline struct msm_gpu *dev_to_gpu(struct device *dev)
  251. {
  252. struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
  253. if (!adreno_smmu)
  254. return NULL;
  255. return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);
  256. }
  257. /* It turns out that all targets use the same ringbuffer size */
  258. #define MSM_GPU_RINGBUFFER_SZ SZ_32K
  259. #define MSM_GPU_RINGBUFFER_BLKSIZE 32
  260. #define MSM_GPU_RB_CNTL_DEFAULT \
  261. (AXXX_CP_RB_CNTL_BUFSZ(ilog2(MSM_GPU_RINGBUFFER_SZ / 8)) | \
  262. AXXX_CP_RB_CNTL_BLKSZ(ilog2(MSM_GPU_RINGBUFFER_BLKSIZE / 8)))
  263. static inline bool msm_gpu_active(struct msm_gpu *gpu)
  264. {
  265. int i;
  266. for (i = 0; i < gpu->nr_rings; i++) {
  267. struct msm_ringbuffer *ring = gpu->rb[i];
  268. if (fence_after(ring->fctx->last_fence, ring->memptrs->fence))
  269. return true;
  270. }
  271. return false;
  272. }
  273. /* Perf-Counters:
  274. * The select_reg and select_val are just there for the benefit of the child
  275. * class that actually enables the perf counter.. but msm_gpu base class
  276. * will handle sampling/displaying the counters.
  277. */
  278. struct msm_gpu_perfcntr {
  279. uint32_t select_reg;
  280. uint32_t sample_reg;
  281. uint32_t select_val;
  282. const char *name;
  283. };
  284. /*
  285. * The number of priority levels provided by drm gpu scheduler. The
  286. * DRM_SCHED_PRIORITY_KERNEL priority level is treated specially in some
  287. * cases, so we don't use it (no need for kernel generated jobs).
  288. */
  289. #define NR_SCHED_PRIORITIES (1 + DRM_SCHED_PRIORITY_LOW - DRM_SCHED_PRIORITY_HIGH)
  290. /**
  291. * struct msm_file_private - per-drm_file context
  292. *
  293. * @queuelock: synchronizes access to submitqueues list
  294. * @submitqueues: list of &msm_gpu_submitqueue created by userspace
  295. * @queueid: counter incremented each time a submitqueue is created,
  296. * used to assign &msm_gpu_submitqueue.id
  297. * @aspace: the per-process GPU address-space
  298. * @ref: reference count
  299. * @seqno: unique per process seqno
  300. */
  301. struct msm_file_private {
  302. rwlock_t queuelock;
  303. struct list_head submitqueues;
  304. int queueid;
  305. struct msm_gem_address_space *aspace;
  306. struct kref ref;
  307. int seqno;
  308. /**
  309. * sysprof:
  310. *
  311. * The value of MSM_PARAM_SYSPROF set by userspace. This is
  312. * intended to be used by system profiling tools like Mesa's
  313. * pps-producer (perfetto), and restricted to CAP_SYS_ADMIN.
  314. *
  315. * Setting a value of 1 will preserve performance counters across
  316. * context switches. Setting a value of 2 will in addition
  317. * suppress suspend. (Performance counters lose state across
  318. * power collapse, which is undesirable for profiling in some
  319. * cases.)
  320. *
  321. * The value automatically reverts to zero when the drm device
  322. * file is closed.
  323. */
  324. int sysprof;
  325. /**
  326. * comm: Overridden task comm, see MSM_PARAM_COMM
  327. *
  328. * Accessed under msm_gpu::lock
  329. */
  330. char *comm;
  331. /**
  332. * cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE
  333. *
  334. * Accessed under msm_gpu::lock
  335. */
  336. char *cmdline;
  337. /**
  338. * elapsed:
  339. *
  340. * The total (cumulative) elapsed time GPU was busy with rendering
  341. * from this context in ns.
  342. */
  343. uint64_t elapsed_ns;
  344. /**
  345. * cycles:
  346. *
  347. * The total (cumulative) GPU cycles elapsed attributed to this
  348. * context.
  349. */
  350. uint64_t cycles;
  351. /**
  352. * entities:
  353. *
  354. * Table of per-priority-level sched entities used by submitqueues
  355. * associated with this &drm_file. Because some userspace apps
  356. * make assumptions about rendering from multiple gl contexts
  357. * (of the same priority) within the process happening in FIFO
  358. * order without requiring any fencing beyond MakeCurrent(), we
  359. * create at most one &drm_sched_entity per-process per-priority-
  360. * level.
  361. */
  362. struct drm_sched_entity *entities[NR_SCHED_PRIORITIES * MSM_GPU_MAX_RINGS];
  363. /**
  364. * ctx_mem:
  365. *
  366. * Total amount of memory of GEM buffers with handles attached for
  367. * this context.
  368. */
  369. atomic64_t ctx_mem;
  370. };
  371. /**
  372. * msm_gpu_convert_priority - Map userspace priority to ring # and sched priority
  373. *
  374. * @gpu: the gpu instance
  375. * @prio: the userspace priority level
  376. * @ring_nr: [out] the ringbuffer the userspace priority maps to
  377. * @sched_prio: [out] the gpu scheduler priority level which the userspace
  378. * priority maps to
  379. *
  380. * With drm/scheduler providing it's own level of prioritization, our total
  381. * number of available priority levels is (nr_rings * NR_SCHED_PRIORITIES).
  382. * Each ring is associated with it's own scheduler instance. However, our
  383. * UABI is that lower numerical values are higher priority. So mapping the
  384. * single userspace priority level into ring_nr and sched_prio takes some
  385. * care. The userspace provided priority (when a submitqueue is created)
  386. * is mapped to ring nr and scheduler priority as such:
  387. *
  388. * ring_nr = userspace_prio / NR_SCHED_PRIORITIES
  389. * sched_prio = NR_SCHED_PRIORITIES -
  390. * (userspace_prio % NR_SCHED_PRIORITIES) - 1
  391. *
  392. * This allows generations without preemption (nr_rings==1) to have some
  393. * amount of prioritization, and provides more priority levels for gens
  394. * that do have preemption.
  395. */
  396. static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio,
  397. unsigned *ring_nr, enum drm_sched_priority *sched_prio)
  398. {
  399. unsigned rn, sp;
  400. rn = div_u64_rem(prio, NR_SCHED_PRIORITIES, &sp);
  401. /* invert sched priority to map to higher-numeric-is-higher-
  402. * priority convention
  403. */
  404. sp = NR_SCHED_PRIORITIES - sp - 1;
  405. if (rn >= gpu->nr_rings)
  406. return -EINVAL;
  407. *ring_nr = rn;
  408. *sched_prio = sp;
  409. return 0;
  410. }
  411. /**
  412. * struct msm_gpu_submitqueues - Userspace created context.
  413. *
  414. * A submitqueue is associated with a gl context or vk queue (or equiv)
  415. * in userspace.
  416. *
  417. * @id: userspace id for the submitqueue, unique within the drm_file
  418. * @flags: userspace flags for the submitqueue, specified at creation
  419. * (currently unusued)
  420. * @ring_nr: the ringbuffer used by this submitqueue, which is determined
  421. * by the submitqueue's priority
  422. * @faults: the number of GPU hangs associated with this submitqueue
  423. * @last_fence: the sequence number of the last allocated fence (for error
  424. * checking)
  425. * @ctx: the per-drm_file context associated with the submitqueue (ie.
  426. * which set of pgtables do submits jobs associated with the
  427. * submitqueue use)
  428. * @node: node in the context's list of submitqueues
  429. * @fence_idr: maps fence-id to dma_fence for userspace visible fence
  430. * seqno, protected by submitqueue lock
  431. * @idr_lock: for serializing access to fence_idr
  432. * @lock: submitqueue lock for serializing submits on a queue
  433. * @ref: reference count
  434. * @entity: the submit job-queue
  435. */
  436. struct msm_gpu_submitqueue {
  437. int id;
  438. u32 flags;
  439. u32 ring_nr;
  440. int faults;
  441. uint32_t last_fence;
  442. struct msm_file_private *ctx;
  443. struct list_head node;
  444. struct idr fence_idr;
  445. struct spinlock idr_lock;
  446. struct mutex lock;
  447. struct kref ref;
  448. struct drm_sched_entity *entity;
  449. };
  450. struct msm_gpu_state_bo {
  451. u64 iova;
  452. size_t size;
  453. u32 flags;
  454. void *data;
  455. bool encoded;
  456. char name[32];
  457. };
  458. struct msm_gpu_state {
  459. struct kref ref;
  460. struct timespec64 time;
  461. struct {
  462. u64 iova;
  463. u32 fence;
  464. u32 seqno;
  465. u32 rptr;
  466. u32 wptr;
  467. void *data;
  468. int data_size;
  469. bool encoded;
  470. } ring[MSM_GPU_MAX_RINGS];
  471. int nr_registers;
  472. u32 *registers;
  473. u32 rbbm_status;
  474. char *comm;
  475. char *cmd;
  476. struct msm_gpu_fault_info fault_info;
  477. int nr_bos;
  478. struct msm_gpu_state_bo *bos;
  479. };
  480. static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data)
  481. {
  482. writel(data, gpu->mmio + (reg << 2));
  483. }
  484. static inline u32 gpu_read(struct msm_gpu *gpu, u32 reg)
  485. {
  486. return readl(gpu->mmio + (reg << 2));
  487. }
  488. static inline void gpu_rmw(struct msm_gpu *gpu, u32 reg, u32 mask, u32 or)
  489. {
  490. msm_rmw(gpu->mmio + (reg << 2), mask, or);
  491. }
  492. static inline u64 gpu_read64(struct msm_gpu *gpu, u32 reg)
  493. {
  494. u64 val;
  495. /*
  496. * Why not a readq here? Two reasons: 1) many of the LO registers are
  497. * not quad word aligned and 2) the GPU hardware designers have a bit
  498. * of a history of putting registers where they fit, especially in
  499. * spins. The longer a GPU family goes the higher the chance that
  500. * we'll get burned. We could do a series of validity checks if we
  501. * wanted to, but really is a readq() that much better? Nah.
  502. */
  503. /*
  504. * For some lo/hi registers (like perfcounters), the hi value is latched
  505. * when the lo is read, so make sure to read the lo first to trigger
  506. * that
  507. */
  508. val = (u64) readl(gpu->mmio + (reg << 2));
  509. val |= ((u64) readl(gpu->mmio + ((reg + 1) << 2)) << 32);
  510. return val;
  511. }
  512. static inline void gpu_write64(struct msm_gpu *gpu, u32 reg, u64 val)
  513. {
  514. /* Why not a writeq here? Read the screed above */
  515. writel(lower_32_bits(val), gpu->mmio + (reg << 2));
  516. writel(upper_32_bits(val), gpu->mmio + ((reg + 1) << 2));
  517. }
  518. int msm_gpu_pm_suspend(struct msm_gpu *gpu);
  519. int msm_gpu_pm_resume(struct msm_gpu *gpu);
  520. void msm_gpu_show_fdinfo(struct msm_gpu *gpu, struct msm_file_private *ctx,
  521. struct drm_printer *p);
  522. int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
  523. struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
  524. u32 id);
  525. int msm_submitqueue_create(struct drm_device *drm,
  526. struct msm_file_private *ctx,
  527. u32 prio, u32 flags, u32 *id);
  528. int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
  529. struct drm_msm_submitqueue_query *args);
  530. int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
  531. void msm_submitqueue_close(struct msm_file_private *ctx);
  532. void msm_submitqueue_destroy(struct kref *kref);
  533. int msm_file_private_set_sysprof(struct msm_file_private *ctx,
  534. struct msm_gpu *gpu, int sysprof);
  535. void __msm_file_private_destroy(struct kref *kref);
  536. static inline void msm_file_private_put(struct msm_file_private *ctx)
  537. {
  538. kref_put(&ctx->ref, __msm_file_private_destroy);
  539. }
  540. static inline struct msm_file_private *msm_file_private_get(
  541. struct msm_file_private *ctx)
  542. {
  543. kref_get(&ctx->ref);
  544. return ctx;
  545. }
  546. void msm_devfreq_init(struct msm_gpu *gpu);
  547. void msm_devfreq_cleanup(struct msm_gpu *gpu);
  548. void msm_devfreq_resume(struct msm_gpu *gpu);
  549. void msm_devfreq_suspend(struct msm_gpu *gpu);
  550. void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor);
  551. void msm_devfreq_active(struct msm_gpu *gpu);
  552. void msm_devfreq_idle(struct msm_gpu *gpu);
  553. int msm_gpu_hw_init(struct msm_gpu *gpu);
  554. void msm_gpu_perfcntr_start(struct msm_gpu *gpu);
  555. void msm_gpu_perfcntr_stop(struct msm_gpu *gpu);
  556. int msm_gpu_perfcntr_sample(struct msm_gpu *gpu, uint32_t *activetime,
  557. uint32_t *totaltime, uint32_t ncntrs, uint32_t *cntrs);
  558. void msm_gpu_retire(struct msm_gpu *gpu);
  559. void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit);
  560. int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
  561. struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
  562. const char *name, struct msm_gpu_config *config);
  563. struct msm_gem_address_space *
  564. msm_gpu_create_private_address_space(struct msm_gpu *gpu, struct task_struct *task);
  565. void msm_gpu_cleanup(struct msm_gpu *gpu);
  566. struct msm_gpu *adreno_load_gpu(struct drm_device *dev);
  567. void __init adreno_register(void);
  568. void __exit adreno_unregister(void);
  569. static inline void msm_submitqueue_put(struct msm_gpu_submitqueue *queue)
  570. {
  571. if (queue)
  572. kref_put(&queue->ref, msm_submitqueue_destroy);
  573. }
  574. static inline struct msm_gpu_state *msm_gpu_crashstate_get(struct msm_gpu *gpu)
  575. {
  576. struct msm_gpu_state *state = NULL;
  577. mutex_lock(&gpu->lock);
  578. if (gpu->crashstate) {
  579. kref_get(&gpu->crashstate->ref);
  580. state = gpu->crashstate;
  581. }
  582. mutex_unlock(&gpu->lock);
  583. return state;
  584. }
  585. static inline void msm_gpu_crashstate_put(struct msm_gpu *gpu)
  586. {
  587. mutex_lock(&gpu->lock);
  588. if (gpu->crashstate) {
  589. if (gpu->funcs->gpu_state_put(gpu->crashstate))
  590. gpu->crashstate = NULL;
  591. }
  592. mutex_unlock(&gpu->lock);
  593. }
  594. /*
  595. * Simple macro to semi-cleanly add the MAP_PRIV flag for targets that can
  596. * support expanded privileges
  597. */
  598. #define check_apriv(gpu, flags) \
  599. (((gpu)->hw_apriv ? MSM_BO_MAP_PRIV : 0) | (flags))
  600. #endif /* __MSM_GPU_H__ */