Home | History | Annotate | Line # | Download | only in gt
      1  1.1  riastrad /*	$NetBSD: intel_ring.h,v 1.2 2021/12/18 23:45:30 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * SPDX-License-Identifier: MIT
      5  1.1  riastrad  *
      6  1.1  riastrad  * Copyright  2019 Intel Corporation
      7  1.1  riastrad  */
      8  1.1  riastrad 
      9  1.1  riastrad #ifndef INTEL_RING_H
     10  1.1  riastrad #define INTEL_RING_H
     11  1.1  riastrad 
     12  1.1  riastrad #include "i915_gem.h" /* GEM_BUG_ON */
     13  1.1  riastrad #include "i915_request.h"
     14  1.1  riastrad #include "intel_ring_types.h"
     15  1.1  riastrad 
     16  1.1  riastrad struct intel_engine_cs;
     17  1.1  riastrad 
     18  1.1  riastrad struct intel_ring *
     19  1.1  riastrad intel_engine_create_ring(struct intel_engine_cs *engine, int size);
     20  1.1  riastrad 
     21  1.1  riastrad u32 *intel_ring_begin(struct i915_request *rq, unsigned int num_dwords);
     22  1.1  riastrad int intel_ring_cacheline_align(struct i915_request *rq);
     23  1.1  riastrad 
     24  1.1  riastrad unsigned int intel_ring_update_space(struct intel_ring *ring);
     25  1.1  riastrad 
     26  1.1  riastrad int intel_ring_pin(struct intel_ring *ring);
     27  1.1  riastrad void intel_ring_unpin(struct intel_ring *ring);
     28  1.1  riastrad void intel_ring_reset(struct intel_ring *ring, u32 tail);
     29  1.1  riastrad 
     30  1.1  riastrad void intel_ring_free(struct kref *ref);
     31  1.1  riastrad 
     32  1.1  riastrad static inline struct intel_ring *intel_ring_get(struct intel_ring *ring)
     33  1.1  riastrad {
     34  1.1  riastrad 	kref_get(&ring->ref);
     35  1.1  riastrad 	return ring;
     36  1.1  riastrad }
     37  1.1  riastrad 
     38  1.1  riastrad static inline void intel_ring_put(struct intel_ring *ring)
     39  1.1  riastrad {
     40  1.1  riastrad 	kref_put(&ring->ref, intel_ring_free);
     41  1.1  riastrad }
     42  1.1  riastrad 
     43  1.1  riastrad static inline void intel_ring_advance(struct i915_request *rq, u32 *cs)
     44  1.1  riastrad {
     45  1.1  riastrad 	/* Dummy function.
     46  1.1  riastrad 	 *
     47  1.1  riastrad 	 * This serves as a placeholder in the code so that the reader
     48  1.1  riastrad 	 * can compare against the preceding intel_ring_begin() and
     49  1.1  riastrad 	 * check that the number of dwords emitted matches the space
     50  1.1  riastrad 	 * reserved for the command packet (i.e. the value passed to
     51  1.1  riastrad 	 * intel_ring_begin()).
     52  1.1  riastrad 	 */
     53  1.1  riastrad 	GEM_BUG_ON((rq->ring->vaddr + rq->ring->emit) != cs);
     54  1.1  riastrad }
     55  1.1  riastrad 
     56  1.1  riastrad static inline u32 intel_ring_wrap(const struct intel_ring *ring, u32 pos)
     57  1.1  riastrad {
     58  1.1  riastrad 	return pos & (ring->size - 1);
     59  1.1  riastrad }
     60  1.1  riastrad 
     61  1.1  riastrad static inline int intel_ring_direction(const struct intel_ring *ring,
     62  1.1  riastrad 				       u32 next, u32 prev)
     63  1.1  riastrad {
     64  1.1  riastrad 	typecheck(typeof(ring->size), next);
     65  1.1  riastrad 	typecheck(typeof(ring->size), prev);
     66  1.1  riastrad 	return (next - prev) << ring->wrap;
     67  1.1  riastrad }
     68  1.1  riastrad 
     69  1.1  riastrad static inline bool
     70  1.1  riastrad intel_ring_offset_valid(const struct intel_ring *ring,
     71  1.1  riastrad 			unsigned int pos)
     72  1.1  riastrad {
     73  1.1  riastrad 	if (pos & -ring->size) /* must be strictly within the ring */
     74  1.1  riastrad 		return false;
     75  1.1  riastrad 
     76  1.1  riastrad 	if (!IS_ALIGNED(pos, 8)) /* must be qword aligned */
     77  1.1  riastrad 		return false;
     78  1.1  riastrad 
     79  1.1  riastrad 	return true;
     80  1.1  riastrad }
     81  1.1  riastrad 
     82  1.1  riastrad static inline u32 intel_ring_offset(const struct i915_request *rq, void *addr)
     83  1.1  riastrad {
     84  1.1  riastrad 	/* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */
     85  1.1  riastrad 	u32 offset = addr - rq->ring->vaddr;
     86  1.1  riastrad 	GEM_BUG_ON(offset > rq->ring->size);
     87  1.1  riastrad 	return intel_ring_wrap(rq->ring, offset);
     88  1.1  riastrad }
     89  1.1  riastrad 
     90  1.1  riastrad static inline void
     91  1.1  riastrad assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
     92  1.1  riastrad {
     93  1.1  riastrad 	GEM_BUG_ON(!intel_ring_offset_valid(ring, tail));
     94  1.1  riastrad 
     95  1.1  riastrad 	/*
     96  1.1  riastrad 	 * "Ring Buffer Use"
     97  1.1  riastrad 	 *	Gen2 BSpec "1. Programming Environment" / 1.4.4.6
     98  1.1  riastrad 	 *	Gen3 BSpec "1c Memory Interface Functions" / 2.3.4.5
     99  1.1  riastrad 	 *	Gen4+ BSpec "1c Memory Interface and Command Stream" / 5.3.4.5
    100  1.1  riastrad 	 * "If the Ring Buffer Head Pointer and the Tail Pointer are on the
    101  1.1  riastrad 	 * same cacheline, the Head Pointer must not be greater than the Tail
    102  1.1  riastrad 	 * Pointer."
    103  1.1  riastrad 	 *
    104  1.1  riastrad 	 * We use ring->head as the last known location of the actual RING_HEAD,
    105  1.1  riastrad 	 * it may have advanced but in the worst case it is equally the same
    106  1.1  riastrad 	 * as ring->head and so we should never program RING_TAIL to advance
    107  1.1  riastrad 	 * into the same cacheline as ring->head.
    108  1.1  riastrad 	 */
    109  1.1  riastrad #define cacheline(a) round_down(a, CACHELINE_BYTES)
    110  1.1  riastrad 	GEM_BUG_ON(cacheline(tail) == cacheline(ring->head) &&
    111  1.1  riastrad 		   tail < ring->head);
    112  1.1  riastrad #undef cacheline
    113  1.1  riastrad }
    114  1.1  riastrad 
    115  1.1  riastrad static inline unsigned int
    116  1.1  riastrad intel_ring_set_tail(struct intel_ring *ring, unsigned int tail)
    117  1.1  riastrad {
    118  1.1  riastrad 	/* Whilst writes to the tail are strictly order, there is no
    119  1.1  riastrad 	 * serialisation between readers and the writers. The tail may be
    120  1.1  riastrad 	 * read by i915_request_retire() just as it is being updated
    121  1.1  riastrad 	 * by execlists, as although the breadcrumb is complete, the context
    122  1.1  riastrad 	 * switch hasn't been seen.
    123  1.1  riastrad 	 */
    124  1.1  riastrad 	assert_ring_tail_valid(ring, tail);
    125  1.1  riastrad 	ring->tail = tail;
    126  1.1  riastrad 	return tail;
    127  1.1  riastrad }
    128  1.1  riastrad 
    129  1.1  riastrad static inline unsigned int
    130  1.1  riastrad __intel_ring_space(unsigned int head, unsigned int tail, unsigned int size)
    131  1.1  riastrad {
    132  1.1  riastrad 	/*
    133  1.1  riastrad 	 * "If the Ring Buffer Head Pointer and the Tail Pointer are on the
    134  1.1  riastrad 	 * same cacheline, the Head Pointer must not be greater than the Tail
    135  1.1  riastrad 	 * Pointer."
    136  1.1  riastrad 	 */
    137  1.1  riastrad 	GEM_BUG_ON(!is_power_of_2(size));
    138  1.1  riastrad 	return (head - tail - CACHELINE_BYTES) & (size - 1);
    139  1.1  riastrad }
    140  1.1  riastrad 
    141  1.1  riastrad #endif /* INTEL_RING_H */
    142