1c39f472eSBen Skeggs #ifndef __NVKM_FBRAM_FUC_H__ 2c39f472eSBen Skeggs #define __NVKM_FBRAM_FUC_H__ 36758745bSBen Skeggs #include <subdev/fb.h> 4ebb58dc2SBen Skeggs #include <subdev/pmu.h> 5c39f472eSBen Skeggs 6c39f472eSBen Skeggs struct ramfuc { 7639c308eSBen Skeggs struct nvkm_memx *memx; 8b1e4553cSBen Skeggs struct nvkm_fb *fb; 9c39f472eSBen Skeggs int sequence; 10c39f472eSBen Skeggs }; 11c39f472eSBen Skeggs 12c39f472eSBen Skeggs struct ramfuc_reg { 13c39f472eSBen Skeggs int sequence; 14c39f472eSBen Skeggs bool force; 15c39f472eSBen Skeggs u32 addr; 16c39f472eSBen Skeggs u32 stride; /* in bytes */ 17c39f472eSBen Skeggs u32 mask; 18c39f472eSBen Skeggs u32 data; 19c39f472eSBen Skeggs }; 20c39f472eSBen Skeggs 21c39f472eSBen Skeggs static inline struct ramfuc_reg 22c39f472eSBen Skeggs ramfuc_stride(u32 addr, u32 stride, u32 mask) 23c39f472eSBen Skeggs { 24c39f472eSBen Skeggs return (struct ramfuc_reg) { 25c39f472eSBen Skeggs .sequence = 0, 26c39f472eSBen Skeggs .addr = addr, 27c39f472eSBen Skeggs .stride = stride, 28c39f472eSBen Skeggs .mask = mask, 29c39f472eSBen Skeggs .data = 0xdeadbeef, 30c39f472eSBen Skeggs }; 31c39f472eSBen Skeggs } 32c39f472eSBen Skeggs 33c39f472eSBen Skeggs static inline struct ramfuc_reg 34c39f472eSBen Skeggs ramfuc_reg2(u32 addr1, u32 addr2) 35c39f472eSBen Skeggs { 36c39f472eSBen Skeggs return (struct ramfuc_reg) { 37c39f472eSBen Skeggs .sequence = 0, 38c39f472eSBen Skeggs .addr = addr1, 39c39f472eSBen Skeggs .stride = addr2 - addr1, 40c39f472eSBen Skeggs .mask = 0x3, 41c39f472eSBen Skeggs .data = 0xdeadbeef, 42c39f472eSBen Skeggs }; 43c39f472eSBen Skeggs } 44c39f472eSBen Skeggs 45c39f472eSBen Skeggs static noinline struct ramfuc_reg 46c39f472eSBen Skeggs ramfuc_reg(u32 addr) 47c39f472eSBen Skeggs { 48c39f472eSBen Skeggs return (struct ramfuc_reg) { 49c39f472eSBen Skeggs .sequence = 0, 50c39f472eSBen Skeggs .addr = addr, 51c39f472eSBen Skeggs .stride = 0, 52c39f472eSBen Skeggs .mask = 0x1, 53c39f472eSBen Skeggs .data = 0xdeadbeef, 54c39f472eSBen Skeggs }; 55c39f472eSBen Skeggs } 56c39f472eSBen Skeggs 57c39f472eSBen Skeggs static inline int 58b1e4553cSBen Skeggs ramfuc_init(struct ramfuc *ram, struct nvkm_fb *fb) 59c39f472eSBen Skeggs { 60b1e4553cSBen Skeggs struct nvkm_pmu *pmu = nvkm_pmu(fb); 61c39f472eSBen Skeggs int ret; 62c39f472eSBen Skeggs 63639c308eSBen Skeggs ret = nvkm_memx_init(pmu, &ram->memx); 64c39f472eSBen Skeggs if (ret) 65c39f472eSBen Skeggs return ret; 66c39f472eSBen Skeggs 67c39f472eSBen Skeggs ram->sequence++; 68b1e4553cSBen Skeggs ram->fb = fb; 69c39f472eSBen Skeggs return 0; 70c39f472eSBen Skeggs } 71c39f472eSBen Skeggs 72c39f472eSBen Skeggs static inline int 73c39f472eSBen Skeggs ramfuc_exec(struct ramfuc *ram, bool exec) 74c39f472eSBen Skeggs { 75c39f472eSBen Skeggs int ret = 0; 76b1e4553cSBen Skeggs if (ram->fb) { 77639c308eSBen Skeggs ret = nvkm_memx_fini(&ram->memx, exec); 78b1e4553cSBen Skeggs ram->fb = NULL; 79c39f472eSBen Skeggs } 80c39f472eSBen Skeggs return ret; 81c39f472eSBen Skeggs } 82c39f472eSBen Skeggs 83c39f472eSBen Skeggs static inline u32 84c39f472eSBen Skeggs ramfuc_rd32(struct ramfuc *ram, struct ramfuc_reg *reg) 85c39f472eSBen Skeggs { 866758745bSBen Skeggs struct nvkm_device *device = ram->fb->subdev.device; 87c39f472eSBen Skeggs if (reg->sequence != ram->sequence) 886758745bSBen Skeggs reg->data = nvkm_rd32(device, reg->addr); 89c39f472eSBen Skeggs return reg->data; 90c39f472eSBen Skeggs } 91c39f472eSBen Skeggs 92c39f472eSBen Skeggs static inline void 93c39f472eSBen Skeggs ramfuc_wr32(struct ramfuc *ram, struct ramfuc_reg *reg, u32 data) 94c39f472eSBen Skeggs { 95c39f472eSBen Skeggs unsigned int mask, off = 0; 96c39f472eSBen Skeggs 97c39f472eSBen Skeggs reg->sequence = ram->sequence; 98c39f472eSBen Skeggs reg->data = data; 99c39f472eSBen Skeggs 100c39f472eSBen Skeggs for (mask = reg->mask; mask > 0; mask = (mask & ~1) >> 1) { 101639c308eSBen Skeggs if (mask & 1) 102639c308eSBen Skeggs nvkm_memx_wr32(ram->memx, reg->addr+off, reg->data); 103c39f472eSBen Skeggs off += reg->stride; 104c39f472eSBen Skeggs } 105c39f472eSBen Skeggs } 106c39f472eSBen Skeggs 107c39f472eSBen Skeggs static inline void 108c39f472eSBen Skeggs ramfuc_nuke(struct ramfuc *ram, struct ramfuc_reg *reg) 109c39f472eSBen Skeggs { 110c39f472eSBen Skeggs reg->force = true; 111c39f472eSBen Skeggs } 112c39f472eSBen Skeggs 113c39f472eSBen Skeggs static inline u32 114c39f472eSBen Skeggs ramfuc_mask(struct ramfuc *ram, struct ramfuc_reg *reg, u32 mask, u32 data) 115c39f472eSBen Skeggs { 116c39f472eSBen Skeggs u32 temp = ramfuc_rd32(ram, reg); 117c39f472eSBen Skeggs if (temp != ((temp & ~mask) | data) || reg->force) { 118c39f472eSBen Skeggs ramfuc_wr32(ram, reg, (temp & ~mask) | data); 119c39f472eSBen Skeggs reg->force = false; 120c39f472eSBen Skeggs } 121c39f472eSBen Skeggs return temp; 122c39f472eSBen Skeggs } 123c39f472eSBen Skeggs 124c39f472eSBen Skeggs static inline void 125c39f472eSBen Skeggs ramfuc_wait(struct ramfuc *ram, u32 addr, u32 mask, u32 data, u32 nsec) 126c39f472eSBen Skeggs { 127639c308eSBen Skeggs nvkm_memx_wait(ram->memx, addr, mask, data, nsec); 128c39f472eSBen Skeggs } 129c39f472eSBen Skeggs 130c39f472eSBen Skeggs static inline void 131c39f472eSBen Skeggs ramfuc_nsec(struct ramfuc *ram, u32 nsec) 132c39f472eSBen Skeggs { 133639c308eSBen Skeggs nvkm_memx_nsec(ram->memx, nsec); 134c39f472eSBen Skeggs } 135c39f472eSBen Skeggs 136c39f472eSBen Skeggs static inline void 137c39f472eSBen Skeggs ramfuc_wait_vblank(struct ramfuc *ram) 138c39f472eSBen Skeggs { 139639c308eSBen Skeggs nvkm_memx_wait_vblank(ram->memx); 140c39f472eSBen Skeggs } 141c39f472eSBen Skeggs 142c39f472eSBen Skeggs static inline void 143c39f472eSBen Skeggs ramfuc_train(struct ramfuc *ram) 144c39f472eSBen Skeggs { 145639c308eSBen Skeggs nvkm_memx_train(ram->memx); 146c39f472eSBen Skeggs } 147c39f472eSBen Skeggs 148c39f472eSBen Skeggs static inline int 149b1e4553cSBen Skeggs ramfuc_train_result(struct nvkm_fb *fb, u32 *result, u32 rsize) 150c39f472eSBen Skeggs { 151b1e4553cSBen Skeggs struct nvkm_pmu *pmu = nvkm_pmu(fb); 152c39f472eSBen Skeggs 153639c308eSBen Skeggs return nvkm_memx_train_result(pmu, result, rsize); 154c39f472eSBen Skeggs } 155c39f472eSBen Skeggs 156c39f472eSBen Skeggs static inline void 157c39f472eSBen Skeggs ramfuc_block(struct ramfuc *ram) 158c39f472eSBen Skeggs { 159639c308eSBen Skeggs nvkm_memx_block(ram->memx); 160c39f472eSBen Skeggs } 161c39f472eSBen Skeggs 162c39f472eSBen Skeggs static inline void 163c39f472eSBen Skeggs ramfuc_unblock(struct ramfuc *ram) 164c39f472eSBen Skeggs { 165639c308eSBen Skeggs nvkm_memx_unblock(ram->memx); 166c39f472eSBen Skeggs } 167c39f472eSBen Skeggs 168c39f472eSBen Skeggs #define ram_init(s,p) ramfuc_init(&(s)->base, (p)) 169c39f472eSBen Skeggs #define ram_exec(s,e) ramfuc_exec(&(s)->base, (e)) 170c39f472eSBen Skeggs #define ram_have(s,r) ((s)->r_##r.addr != 0x000000) 171c39f472eSBen Skeggs #define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r) 172c39f472eSBen Skeggs #define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d)) 173c39f472eSBen Skeggs #define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r) 174c39f472eSBen Skeggs #define ram_mask(s,r,m,d) ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d)) 175c39f472eSBen Skeggs #define ram_wait(s,r,m,d,n) ramfuc_wait(&(s)->base, (r), (m), (d), (n)) 176c39f472eSBen Skeggs #define ram_nsec(s,n) ramfuc_nsec(&(s)->base, (n)) 177c39f472eSBen Skeggs #define ram_wait_vblank(s) ramfuc_wait_vblank(&(s)->base) 178c39f472eSBen Skeggs #define ram_train(s) ramfuc_train(&(s)->base) 179c39f472eSBen Skeggs #define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l)) 180c39f472eSBen Skeggs #define ram_block(s) ramfuc_block(&(s)->base) 181c39f472eSBen Skeggs #define ram_unblock(s) ramfuc_unblock(&(s)->base) 182c39f472eSBen Skeggs #endif 183