1 | #ifndef __NVKM_BUS_HWSQ_H__ |
2 | #define __NVKM_BUS_HWSQ_H__ |
3 | |
4 | #include <subdev/bus.h> |
5 | |
6 | struct hwsq { |
7 | struct nouveau_subdev *subdev; |
8 | struct nouveau_hwsq *hwsq; |
9 | int sequence; |
10 | }; |
11 | |
12 | struct hwsq_reg { |
13 | int sequence; |
14 | bool force; |
15 | u32 addr[2]; |
16 | u32 data; |
17 | }; |
18 | |
19 | static inline struct hwsq_reg |
20 | hwsq_reg2(u32 addr1, u32 addr2) |
21 | { |
22 | return (struct hwsq_reg) { |
23 | .sequence = 0, |
24 | .force = 0, |
25 | .addr = { addr1, addr2 }, |
26 | .data = 0xdeadbeef, |
27 | }; |
28 | } |
29 | |
30 | static inline struct hwsq_reg |
31 | hwsq_reg(u32 addr) |
32 | { |
33 | return hwsq_reg2(addr, addr); |
34 | } |
35 | |
36 | static inline int |
37 | hwsq_init(struct hwsq *ram, struct nouveau_subdev *subdev) |
38 | { |
39 | struct nouveau_bus *pbus = nouveau_bus(subdev); |
40 | int ret; |
41 | |
42 | ret = nouveau_hwsq_init(pbus, &ram->hwsq); |
43 | if (ret) |
44 | return ret; |
45 | |
46 | ram->sequence++; |
47 | ram->subdev = subdev; |
48 | return 0; |
49 | } |
50 | |
51 | static inline int |
52 | hwsq_exec(struct hwsq *ram, bool exec) |
53 | { |
54 | int ret = 0; |
55 | if (ram->subdev) { |
56 | ret = nouveau_hwsq_fini(&ram->hwsq, exec); |
57 | ram->subdev = NULL; |
58 | } |
59 | return ret; |
60 | } |
61 | |
62 | static inline u32 |
63 | hwsq_rd32(struct hwsq *ram, struct hwsq_reg *reg) |
64 | { |
65 | if (reg->sequence != ram->sequence) |
66 | reg->data = nv_rd32(ram->subdev, reg->addr[0]); |
67 | return reg->data; |
68 | } |
69 | |
70 | static inline void |
71 | hwsq_wr32(struct hwsq *ram, struct hwsq_reg *reg, u32 data) |
72 | { |
73 | reg->sequence = ram->sequence; |
74 | reg->data = data; |
75 | if (reg->addr[0] != reg->addr[1]) |
76 | nouveau_hwsq_wr32(ram->hwsq, reg->addr[1], reg->data); |
77 | nouveau_hwsq_wr32(ram->hwsq, reg->addr[0], reg->data); |
78 | } |
79 | |
80 | static inline void |
81 | hwsq_nuke(struct hwsq *ram, struct hwsq_reg *reg) |
82 | { |
83 | reg->force = true; |
84 | } |
85 | |
86 | static inline u32 |
87 | hwsq_mask(struct hwsq *ram, struct hwsq_reg *reg, u32 mask, u32 data) |
88 | { |
89 | u32 temp = hwsq_rd32(ram, reg); |
90 | if (temp != ((temp & ~mask) | data) || reg->force) |
91 | hwsq_wr32(ram, reg, (temp & ~mask) | data); |
92 | return temp; |
93 | } |
94 | |
95 | static inline void |
96 | hwsq_setf(struct hwsq *ram, u8 flag, int data) |
97 | { |
98 | nouveau_hwsq_setf(ram->hwsq, flag, data); |
99 | } |
100 | |
101 | static inline void |
102 | hwsq_wait(struct hwsq *ram, u8 flag, u8 data) |
103 | { |
104 | nouveau_hwsq_wait(ram->hwsq, flag, data); |
105 | } |
106 | |
107 | static inline void |
108 | hwsq_nsec(struct hwsq *ram, u32 nsec) |
109 | { |
110 | nouveau_hwsq_nsec(ram->hwsq, nsec); |
111 | } |
112 | |
113 | #endif |
114 | |