1#ifndef __NVKM_FBRAM_FUC_H__ 2#define __NVKM_FBRAM_FUC_H__ 3#include <subdev/pmu.h> 4 5struct ramfuc { 6 struct nvkm_memx *memx; 7 struct nvkm_fb *pfb; 8 int sequence; 9}; 10 11struct ramfuc_reg { 12 int sequence; 13 bool force; 14 u32 addr; 15 u32 stride; /* in bytes */ 16 u32 mask; 17 u32 data; 18}; 19 20static inline struct ramfuc_reg 21ramfuc_stride(u32 addr, u32 stride, u32 mask) 22{ 23 return (struct ramfuc_reg) { 24 .sequence = 0, 25 .addr = addr, 26 .stride = stride, 27 .mask = mask, 28 .data = 0xdeadbeef, 29 }; 30} 31 32static inline struct ramfuc_reg 33ramfuc_reg2(u32 addr1, u32 addr2) 34{ 35 return (struct ramfuc_reg) { 36 .sequence = 0, 37 .addr = addr1, 38 .stride = addr2 - addr1, 39 .mask = 0x3, 40 .data = 0xdeadbeef, 41 }; 42} 43 44static noinline struct ramfuc_reg 45ramfuc_reg(u32 addr) 46{ 47 return (struct ramfuc_reg) { 48 .sequence = 0, 49 .addr = addr, 50 .stride = 0, 51 .mask = 0x1, 52 .data = 0xdeadbeef, 53 }; 54} 55 56static inline int 57ramfuc_init(struct ramfuc *ram, struct nvkm_fb *pfb) 58{ 59 struct nvkm_pmu *pmu = nvkm_pmu(pfb); 60 int ret; 61 62 ret = nvkm_memx_init(pmu, &ram->memx); 63 if (ret) 64 return ret; 65 66 ram->sequence++; 67 ram->pfb = pfb; 68 return 0; 69} 70 71static inline int 72ramfuc_exec(struct ramfuc *ram, bool exec) 73{ 74 int ret = 0; 75 if (ram->pfb) { 76 ret = nvkm_memx_fini(&ram->memx, exec); 77 ram->pfb = NULL; 78 } 79 return ret; 80} 81 82static inline u32 83ramfuc_rd32(struct ramfuc *ram, struct ramfuc_reg *reg) 84{ 85 if (reg->sequence != ram->sequence) 86 reg->data = nv_rd32(ram->pfb, reg->addr); 87 return reg->data; 88} 89 90static inline void 91ramfuc_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 void 106ramfuc_nuke(struct ramfuc *ram, struct ramfuc_reg *reg) 107{ 108 reg->force = true; 109} 110 111static inline u32 112ramfuc_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 void 123ramfuc_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 void 129ramfuc_nsec(struct ramfuc *ram, u32 nsec) 130{ 131 nvkm_memx_nsec(ram->memx, nsec); 132} 133 134static inline void 135ramfuc_wait_vblank(struct ramfuc *ram) 136{ 137 nvkm_memx_wait_vblank(ram->memx); 138} 139 140static inline void 141ramfuc_train(struct ramfuc *ram) 142{ 143 nvkm_memx_train(ram->memx); 144} 145 146static inline int 147ramfuc_train_result(struct nvkm_fb *pfb, u32 *result, u32 rsize) 148{ 149 struct nvkm_pmu *pmu = nvkm_pmu(pfb); 150 151 return nvkm_memx_train_result(pmu, result, rsize); 152} 153 154static inline void 155ramfuc_block(struct ramfuc *ram) 156{ 157 nvkm_memx_block(ram->memx); 158} 159 160static inline void 161ramfuc_unblock(struct ramfuc *ram) 162{ 163 nvkm_memx_unblock(ram->memx); 164} 165 166#define ram_init(s,p) ramfuc_init(&(s)->base, (p)) 167#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e)) 168#define ram_have(s,r) ((s)->r_##r.addr != 0x000000) 169#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r) 170#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d)) 171#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r) 172#define ram_mask(s,r,m,d) ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d)) 173#define ram_wait(s,r,m,d,n) ramfuc_wait(&(s)->base, (r), (m), (d), (n)) 174#define ram_nsec(s,n) ramfuc_nsec(&(s)->base, (n)) 175#define ram_wait_vblank(s) ramfuc_wait_vblank(&(s)->base) 176#define ram_train(s) ramfuc_train(&(s)->base) 177#define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l)) 178#define ram_block(s) ramfuc_block(&(s)->base) 179#define ram_unblock(s) ramfuc_unblock(&(s)->base) 180#endif 181