]>
Commit | Line | Data |
---|---|---|
2984506f BS |
1 | #ifndef __NVKM_BUS_HWSQ_H__ |
2 | #define __NVKM_BUS_HWSQ_H__ | |
2984506f BS |
3 | #include <subdev/bus.h> |
4 | ||
5 | struct hwsq { | |
5f8824de BS |
6 | struct nvkm_subdev *subdev; |
7 | struct nvkm_hwsq *hwsq; | |
2984506f BS |
8 | int sequence; |
9 | }; | |
10 | ||
11 | struct hwsq_reg { | |
12 | int sequence; | |
13 | bool force; | |
3834b632 RS |
14 | u32 addr; |
15 | u32 stride; /* in bytes */ | |
16 | u32 mask; | |
2984506f BS |
17 | u32 data; |
18 | }; | |
19 | ||
3834b632 RS |
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 | ||
2984506f BS |
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, | |
3834b632 RS |
39 | .addr = addr1, |
40 | .stride = addr2 - addr1, | |
41 | .mask = 0x3, | |
2984506f BS |
42 | .data = 0xdeadbeef, |
43 | }; | |
44 | } | |
45 | ||
46 | static inline struct hwsq_reg | |
47 | hwsq_reg(u32 addr) | |
48 | { | |
3834b632 RS |
49 | return (struct hwsq_reg) { |
50 | .sequence = 0, | |
51 | .force = 0, | |
52 | .addr = addr, | |
53 | .stride = 0, | |
54 | .mask = 0x1, | |
55 | .data = 0xdeadbeef, | |
56 | }; | |
2984506f BS |
57 | } |
58 | ||
59 | static inline int | |
5f8824de | 60 | hwsq_init(struct hwsq *ram, struct nvkm_subdev *subdev) |
2984506f | 61 | { |
2984506f BS |
62 | int ret; |
63 | ||
bb23f9d7 | 64 | ret = nvkm_hwsq_init(subdev, &ram->hwsq); |
2984506f BS |
65 | if (ret) |
66 | return ret; | |
67 | ||
68 | ram->sequence++; | |
69 | ram->subdev = subdev; | |
70 | return 0; | |
71 | } | |
72 | ||
73 | static inline int | |
74 | hwsq_exec(struct hwsq *ram, bool exec) | |
75 | { | |
76 | int ret = 0; | |
77 | if (ram->subdev) { | |
5f8824de | 78 | ret = nvkm_hwsq_fini(&ram->hwsq, exec); |
2984506f BS |
79 | ram->subdev = NULL; |
80 | } | |
81 | return ret; | |
82 | } | |
83 | ||
84 | static inline u32 | |
85 | hwsq_rd32(struct hwsq *ram, struct hwsq_reg *reg) | |
86 | { | |
14caba44 | 87 | struct nvkm_device *device = ram->subdev->device; |
2984506f | 88 | if (reg->sequence != ram->sequence) |
14caba44 | 89 | reg->data = nvkm_rd32(device, reg->addr); |
2984506f BS |
90 | return reg->data; |
91 | } | |
92 | ||
93 | static inline void | |
94 | hwsq_wr32(struct hwsq *ram, struct hwsq_reg *reg, u32 data) | |
95 | { | |
3834b632 RS |
96 | u32 mask, off = 0; |
97 | ||
2984506f BS |
98 | reg->sequence = ram->sequence; |
99 | reg->data = data; | |
3834b632 RS |
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 | } | |
2984506f BS |
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 | { | |
5f8824de | 127 | nvkm_hwsq_setf(ram->hwsq, flag, data); |
2984506f BS |
128 | } |
129 | ||
130 | static inline void | |
131 | hwsq_wait(struct hwsq *ram, u8 flag, u8 data) | |
132 | { | |
5f8824de | 133 | nvkm_hwsq_wait(ram->hwsq, flag, data); |
2984506f BS |
134 | } |
135 | ||
136 | static inline void | |
137 | hwsq_nsec(struct hwsq *ram, u32 nsec) | |
138 | { | |
5f8824de | 139 | nvkm_hwsq_nsec(ram->hwsq, nsec); |
2984506f | 140 | } |
2984506f | 141 | #endif |