linux/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv40.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: MIT */
   2#ifndef __NVKM_GRCTX_H__
   3#define __NVKM_GRCTX_H__
   4#include <core/gpuobj.h>
   5
   6struct nvkm_grctx {
   7        struct nvkm_device *device;
   8
   9        enum {
  10                NVKM_GRCTX_PROG,
  11                NVKM_GRCTX_VALS
  12        } mode;
  13        u32 *ucode;
  14        struct nvkm_gpuobj *data;
  15
  16        u32 ctxprog_max;
  17        u32 ctxprog_len;
  18        u32 ctxprog_reg;
  19        int ctxprog_label[32];
  20        u32 ctxvals_pos;
  21        u32 ctxvals_base;
  22};
  23
  24static inline void
  25cp_out(struct nvkm_grctx *ctx, u32 inst)
  26{
  27        u32 *ctxprog = ctx->ucode;
  28
  29        if (ctx->mode != NVKM_GRCTX_PROG)
  30                return;
  31
  32        BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max);
  33        ctxprog[ctx->ctxprog_len++] = inst;
  34}
  35
  36static inline void
  37cp_lsr(struct nvkm_grctx *ctx, u32 val)
  38{
  39        cp_out(ctx, CP_LOAD_SR | val);
  40}
  41
  42static inline void
  43cp_ctx(struct nvkm_grctx *ctx, u32 reg, u32 length)
  44{
  45        ctx->ctxprog_reg = (reg - 0x00400000) >> 2;
  46
  47        ctx->ctxvals_base = ctx->ctxvals_pos;
  48        ctx->ctxvals_pos = ctx->ctxvals_base + length;
  49
  50        if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) {
  51                cp_lsr(ctx, length);
  52                length = 0;
  53        }
  54
  55        cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg);
  56}
  57
  58static inline void
  59cp_name(struct nvkm_grctx *ctx, int name)
  60{
  61        u32 *ctxprog = ctx->ucode;
  62        int i;
  63
  64        if (ctx->mode != NVKM_GRCTX_PROG)
  65                return;
  66
  67        ctx->ctxprog_label[name] = ctx->ctxprog_len;
  68        for (i = 0; i < ctx->ctxprog_len; i++) {
  69                if ((ctxprog[i] & 0xfff00000) != 0xff400000)
  70                        continue;
  71                if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT))
  72                        continue;
  73                ctxprog[i] = (ctxprog[i] & 0x00ff00ff) |
  74                             (ctx->ctxprog_len << CP_BRA_IP_SHIFT);
  75        }
  76}
  77
  78static inline void
  79_cp_bra(struct nvkm_grctx *ctx, u32 mod, int flag, int state, int name)
  80{
  81        int ip = 0;
  82
  83        if (mod != 2) {
  84                ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT;
  85                if (ip == 0)
  86                        ip = 0xff000000 | (name << CP_BRA_IP_SHIFT);
  87        }
  88
  89        cp_out(ctx, CP_BRA | (mod << 18) | ip | flag |
  90                    (state ? 0 : CP_BRA_IF_CLEAR));
  91}
  92#define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
  93#define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
  94#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
  95
  96static inline void
  97_cp_wait(struct nvkm_grctx *ctx, int flag, int state)
  98{
  99        cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
 100}
 101#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
 102
 103static inline void
 104_cp_set(struct nvkm_grctx *ctx, int flag, int state)
 105{
 106        cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
 107}
 108#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
 109
 110static inline void
 111cp_pos(struct nvkm_grctx *ctx, int offset)
 112{
 113        ctx->ctxvals_pos = offset;
 114        ctx->ctxvals_base = ctx->ctxvals_pos;
 115
 116        cp_lsr(ctx, ctx->ctxvals_pos);
 117        cp_out(ctx, CP_SET_CONTEXT_POINTER);
 118}
 119
 120static inline void
 121gr_def(struct nvkm_grctx *ctx, u32 reg, u32 val)
 122{
 123        if (ctx->mode != NVKM_GRCTX_VALS)
 124                return;
 125
 126        reg = (reg - 0x00400000) / 4;
 127        reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base;
 128
 129        nvkm_wo32(ctx->data, reg * 4, val);
 130}
 131#endif
 132