brintos

brintos / linux-shallow public Read only

0
0
Text · 3.8 KiB · 247c0f8 Raw
179 lines · c
1/* SPDX-License-Identifier: MIT */2#ifndef __NVKM_FBRAM_FUC_H__3#define __NVKM_FBRAM_FUC_H__4#include <subdev/fb.h>5#include <subdev/pmu.h>6 7struct ramfuc {8	struct nvkm_memx *memx;9	struct nvkm_fb *fb;10	int sequence;11};12 13struct ramfuc_reg {14	int sequence;15	bool force;16	u32 addr;17	u32 stride; /* in bytes */18	u32 mask;19	u32 data;20};21 22static inline struct ramfuc_reg23ramfuc_stride(u32 addr, u32 stride, u32 mask)24{25	return (struct ramfuc_reg) {26		.sequence = 0,27		.addr = addr,28		.stride = stride,29		.mask = mask,30		.data = 0xdeadbeef,31	};32}33 34static inline struct ramfuc_reg35ramfuc_reg2(u32 addr1, u32 addr2)36{37	return (struct ramfuc_reg) {38		.sequence = 0,39		.addr = addr1,40		.stride = addr2 - addr1,41		.mask = 0x3,42		.data = 0xdeadbeef,43	};44}45 46static noinline struct ramfuc_reg47ramfuc_reg(u32 addr)48{49	return (struct ramfuc_reg) {50		.sequence = 0,51		.addr = addr,52		.stride = 0,53		.mask = 0x1,54		.data = 0xdeadbeef,55	};56}57 58static inline int59ramfuc_init(struct ramfuc *ram, struct nvkm_fb *fb)60{61	int ret = nvkm_memx_init(fb->subdev.device->pmu, &ram->memx);62	if (ret)63		return ret;64 65	ram->sequence++;66	ram->fb = fb;67	return 0;68}69 70static inline int71ramfuc_exec(struct ramfuc *ram, bool exec)72{73	int ret = 0;74	if (ram->fb) {75		ret = nvkm_memx_fini(&ram->memx, exec);76		ram->fb = NULL;77	}78	return ret;79}80 81static inline u3282ramfuc_rd32(struct ramfuc *ram, struct ramfuc_reg *reg)83{84	struct nvkm_device *device = ram->fb->subdev.device;85	if (reg->sequence != ram->sequence)86		reg->data = nvkm_rd32(device, reg->addr);87	return reg->data;88}89 90static inline void91ramfuc_wr32(struct ramfuc *ram, struct ramfuc_reg *reg, u32 data)92{93	unsigned int mask, off = 0;94 95	reg->sequence = ram->sequence;96	reg->data = data;97 98	for (mask = reg->mask; mask > 0; mask = (mask & ~1) >> 1) {99		if (mask & 1)100			nvkm_memx_wr32(ram->memx, reg->addr+off, reg->data);101		off += reg->stride;102	}103}104 105static inline void106ramfuc_nuke(struct ramfuc *ram, struct ramfuc_reg *reg)107{108	reg->force = true;109}110 111static inline u32112ramfuc_mask(struct ramfuc *ram, struct ramfuc_reg *reg, u32 mask, u32 data)113{114	u32 temp = ramfuc_rd32(ram, reg);115	if (temp != ((temp & ~mask) | data) || reg->force) {116		ramfuc_wr32(ram, reg, (temp & ~mask) | data);117		reg->force = false;118	}119	return temp;120}121 122static inline void123ramfuc_wait(struct ramfuc *ram, u32 addr, u32 mask, u32 data, u32 nsec)124{125	nvkm_memx_wait(ram->memx, addr, mask, data, nsec);126}127 128static inline void129ramfuc_nsec(struct ramfuc *ram, u32 nsec)130{131	nvkm_memx_nsec(ram->memx, nsec);132}133 134static inline void135ramfuc_wait_vblank(struct ramfuc *ram)136{137	nvkm_memx_wait_vblank(ram->memx);138}139 140static inline void141ramfuc_train(struct ramfuc *ram)142{143	nvkm_memx_train(ram->memx);144}145 146static inline int147ramfuc_train_result(struct nvkm_fb *fb, u32 *result, u32 rsize)148{149	return nvkm_memx_train_result(fb->subdev.device->pmu, result, rsize);150}151 152static inline void153ramfuc_block(struct ramfuc *ram)154{155	nvkm_memx_block(ram->memx);156}157 158static inline void159ramfuc_unblock(struct ramfuc *ram)160{161	nvkm_memx_unblock(ram->memx);162}163 164#define ram_init(s,p)        ramfuc_init(&(s)->base, (p))165#define ram_exec(s,e)        ramfuc_exec(&(s)->base, (e))166#define ram_have(s,r)        ((s)->r_##r.addr != 0x000000)167#define ram_rd32(s,r)        ramfuc_rd32(&(s)->base, &(s)->r_##r)168#define ram_wr32(s,r,d)      ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))169#define ram_nuke(s,r)        ramfuc_nuke(&(s)->base, &(s)->r_##r)170#define ram_mask(s,r,m,d)    ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d))171#define ram_wait(s,r,m,d,n)  ramfuc_wait(&(s)->base, (r), (m), (d), (n))172#define ram_nsec(s,n)        ramfuc_nsec(&(s)->base, (n))173#define ram_wait_vblank(s)   ramfuc_wait_vblank(&(s)->base)174#define ram_train(s)         ramfuc_train(&(s)->base)175#define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))176#define ram_block(s)         ramfuc_block(&(s)->base)177#define ram_unblock(s)       ramfuc_unblock(&(s)->base)178#endif179