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