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