ramfuc.h 3.8 KB
Newer Older
1 2 3
#ifndef __NVKM_FBRAM_FUC_H__
#define __NVKM_FBRAM_FUC_H__

4
#include <subdev/pmu.h>
5 6 7 8 9 10 11 12 13 14

struct ramfuc {
	struct nouveau_memx *memx;
	struct nouveau_fb *pfb;
	int sequence;
};

struct ramfuc_reg {
	int sequence;
	bool force;
15 16 17
	u32 addr;
	u32 stride; /* in bytes */
	u32 mask;
18 19 20
	u32 data;
};

21 22 23 24 25 26 27 28 29 30 31 32
static inline struct ramfuc_reg
ramfuc_stride(u32 addr, u32 stride, u32 mask)
{
	return (struct ramfuc_reg) {
		.sequence = 0,
		.addr = addr,
		.stride = stride,
		.mask = mask,
		.data = 0xdeadbeef,
	};
}

33 34 35 36 37
static inline struct ramfuc_reg
ramfuc_reg2(u32 addr1, u32 addr2)
{
	return (struct ramfuc_reg) {
		.sequence = 0,
38 39 40
		.addr = addr1,
		.stride = addr2 - addr1,
		.mask = 0x3,
41 42 43 44
		.data = 0xdeadbeef,
	};
}

45
static noinline struct ramfuc_reg
46 47
ramfuc_reg(u32 addr)
{
48 49 50 51 52 53 54
	return (struct ramfuc_reg) {
		.sequence = 0,
		.addr = addr,
		.stride = 0,
		.mask = 0x1,
		.data = 0xdeadbeef,
	};
55 56 57 58 59
}

static inline int
ramfuc_init(struct ramfuc *ram, struct nouveau_fb *pfb)
{
60
	struct nouveau_pmu *pmu = nouveau_pmu(pfb);
61 62
	int ret;

63
	ret = nouveau_memx_init(pmu, &ram->memx);
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
	if (ret)
		return ret;

	ram->sequence++;
	ram->pfb = pfb;
	return 0;
}

static inline int
ramfuc_exec(struct ramfuc *ram, bool exec)
{
	int ret = 0;
	if (ram->pfb) {
		ret = nouveau_memx_fini(&ram->memx, exec);
		ram->pfb = NULL;
	}
	return ret;
}

static inline u32
ramfuc_rd32(struct ramfuc *ram, struct ramfuc_reg *reg)
{
	if (reg->sequence != ram->sequence)
87
		reg->data = nv_rd32(ram->pfb, reg->addr);
88 89 90 91 92 93
	return reg->data;
}

static inline void
ramfuc_wr32(struct ramfuc *ram, struct ramfuc_reg *reg, u32 data)
{
94 95
	unsigned int mask, off = 0;

96 97
	reg->sequence = ram->sequence;
	reg->data = data;
98 99 100 101 102 103 104 105

	for (mask = reg->mask; mask > 0; mask = (mask & ~1) >> 1) {
		if (mask & 1) {
			nouveau_memx_wr32(ram->memx, reg->addr+off, reg->data);
		}

		off += reg->stride;
	}
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
}

static inline void
ramfuc_nuke(struct ramfuc *ram, struct ramfuc_reg *reg)
{
	reg->force = true;
}

static inline u32
ramfuc_mask(struct ramfuc *ram, struct ramfuc_reg *reg, u32 mask, u32 data)
{
	u32 temp = ramfuc_rd32(ram, reg);
	if (temp != ((temp & ~mask) | data) || reg->force) {
		ramfuc_wr32(ram, reg, (temp & ~mask) | data);
		reg->force = false;
	}
	return temp;
}

static inline void
ramfuc_wait(struct ramfuc *ram, u32 addr, u32 mask, u32 data, u32 nsec)
{
	nouveau_memx_wait(ram->memx, addr, mask, data, nsec);
}

static inline void
ramfuc_nsec(struct ramfuc *ram, u32 nsec)
{
	nouveau_memx_nsec(ram->memx, nsec);
}

137 138 139 140 141 142
static inline void
ramfuc_wait_vblank(struct ramfuc *ram)
{
	nouveau_memx_wait_vblank(ram->memx);
}

143 144 145 146 147 148 149 150 151
static inline void
ramfuc_train(struct ramfuc *ram)
{
	nouveau_memx_train(ram->memx);
}

static inline int
ramfuc_train_result(struct nouveau_fb *pfb, u32 *result, u32 rsize)
{
152
	struct nouveau_pmu *pmu = nouveau_pmu(pfb);
153

154
	return nouveau_memx_train_result(pmu, result, rsize);
155 156
}

157
static inline void
158
ramfuc_block(struct ramfuc *ram)
159
{
160
	nouveau_memx_block(ram->memx);
161 162 163
}

static inline void
164
ramfuc_unblock(struct ramfuc *ram)
165
{
166
	nouveau_memx_unblock(ram->memx);
167 168
}

169 170
#define ram_init(s,p)        ramfuc_init(&(s)->base, (p))
#define ram_exec(s,e)        ramfuc_exec(&(s)->base, (e))
171
#define ram_have(s,r)        ((s)->r_##r.addr != 0x000000)
172 173 174 175 176 177 178
#define ram_rd32(s,r)        ramfuc_rd32(&(s)->base, &(s)->r_##r)
#define ram_wr32(s,r,d)      ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
#define ram_nuke(s,r)        ramfuc_nuke(&(s)->base, &(s)->r_##r)
#define ram_mask(s,r,m,d)    ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d))
#define ram_wait(s,r,m,d,n)  ramfuc_wait(&(s)->base, (r), (m), (d), (n))
#define ram_nsec(s,n)        ramfuc_nsec(&(s)->base, (n))
#define ram_wait_vblank(s)   ramfuc_wait_vblank(&(s)->base)
179 180
#define ram_train(s)         ramfuc_train(&(s)->base)
#define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))
181 182
#define ram_block(s)         ramfuc_block(&(s)->base)
#define ram_unblock(s)       ramfuc_unblock(&(s)->base)
183 184

#endif