1 #ifndef __NVKM_BUS_HWSQ_H__ 2 #define __NVKM_BUS_HWSQ_H__ 3 #include <subdev/bus.h> 4 5 struct hwsq { 6 struct nvkm_subdev *subdev; 7 struct nvkm_hwsq *hwsq; 8 int sequence; 9 }; 10 11 struct hwsq_reg { 12 int sequence; 13 bool force; 14 u32 addr; 15 u32 stride; /* in bytes */ 16 u32 mask; 17 u32 data; 18 }; 19 20 static inline struct hwsq_reg 21 hwsq_stride(u32 addr, u32 stride, u32 mask) 22 { 23 return (struct hwsq_reg) { 24 .sequence = 0, 25 .force = 0, 26 .addr = addr, 27 .stride = stride, 28 .mask = mask, 29 .data = 0xdeadbeef, 30 }; 31 } 32 33 static inline struct hwsq_reg 34 hwsq_reg2(u32 addr1, u32 addr2) 35 { 36 return (struct hwsq_reg) { 37 .sequence = 0, 38 .force = 0, 39 .addr = addr1, 40 .stride = addr2 - addr1, 41 .mask = 0x3, 42 .data = 0xdeadbeef, 43 }; 44 } 45 46 static inline struct hwsq_reg 47 hwsq_reg(u32 addr) 48 { 49 return (struct hwsq_reg) { 50 .sequence = 0, 51 .force = 0, 52 .addr = addr, 53 .stride = 0, 54 .mask = 0x1, 55 .data = 0xdeadbeef, 56 }; 57 } 58 59 static inline int 60 hwsq_init(struct hwsq *ram, struct nvkm_subdev *subdev) 61 { 62 struct nvkm_bus *pbus = nvkm_bus(subdev); 63 int ret; 64 65 ret = nvkm_hwsq_init(pbus, &ram->hwsq); 66 if (ret) 67 return ret; 68 69 ram->sequence++; 70 ram->subdev = subdev; 71 return 0; 72 } 73 74 static inline int 75 hwsq_exec(struct hwsq *ram, bool exec) 76 { 77 int ret = 0; 78 if (ram->subdev) { 79 ret = nvkm_hwsq_fini(&ram->hwsq, exec); 80 ram->subdev = NULL; 81 } 82 return ret; 83 } 84 85 static inline u32 86 hwsq_rd32(struct hwsq *ram, struct hwsq_reg *reg) 87 { 88 if (reg->sequence != ram->sequence) 89 reg->data = nv_rd32(ram->subdev, reg->addr); 90 return reg->data; 91 } 92 93 static inline void 94 hwsq_wr32(struct hwsq *ram, struct hwsq_reg *reg, u32 data) 95 { 96 u32 mask, off = 0; 97 98 reg->sequence = ram->sequence; 99 reg->data = data; 100 101 for (mask = reg->mask; mask > 0; mask = (mask & ~1) >> 1) { 102 if (mask & 1) 103 nvkm_hwsq_wr32(ram->hwsq, reg->addr+off, reg->data); 104 105 off += reg->stride; 106 } 107 } 108 109 static inline void 110 hwsq_nuke(struct hwsq *ram, struct hwsq_reg *reg) 111 { 112 reg->force = true; 113 } 114 115 static inline u32 116 hwsq_mask(struct hwsq *ram, struct hwsq_reg *reg, u32 mask, u32 data) 117 { 118 u32 temp = hwsq_rd32(ram, reg); 119 if (temp != ((temp & ~mask) | data) || reg->force) 120 hwsq_wr32(ram, reg, (temp & ~mask) | data); 121 return temp; 122 } 123 124 static inline void 125 hwsq_setf(struct hwsq *ram, u8 flag, int data) 126 { 127 nvkm_hwsq_setf(ram->hwsq, flag, data); 128 } 129 130 static inline void 131 hwsq_wait(struct hwsq *ram, u8 flag, u8 data) 132 { 133 nvkm_hwsq_wait(ram->hwsq, flag, data); 134 } 135 136 static inline void 137 hwsq_nsec(struct hwsq *ram, u32 nsec) 138 { 139 nvkm_hwsq_nsec(ram->hwsq, nsec); 140 } 141 #endif 142