diff options
author | Roy Spliet <rspliet@eclipso.eu> | 2015-03-12 15:43:22 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-04-14 03:00:49 -0400 |
commit | 3834b632b2e3f8586692e80b936c52b9dc987144 (patch) | |
tree | f77342cb1c42525a2e969a87dfdc7907eb40d137 | |
parent | df16896b866a056da3c275cf416f6f4cc47934bd (diff) |
drm/nouveau/pbus/hwsq: Support strided register writes
Signed-off-by: Roy Spliet <rspliet@eclipso.eu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h index 3394a5ea8a9f..ebf709c27e3a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h | |||
@@ -11,17 +11,34 @@ struct hwsq { | |||
11 | struct hwsq_reg { | 11 | struct hwsq_reg { |
12 | int sequence; | 12 | int sequence; |
13 | bool force; | 13 | bool force; |
14 | u32 addr[2]; | 14 | u32 addr; |
15 | u32 stride; /* in bytes */ | ||
16 | u32 mask; | ||
15 | u32 data; | 17 | u32 data; |
16 | }; | 18 | }; |
17 | 19 | ||
18 | static inline struct hwsq_reg | 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 | ||
19 | hwsq_reg2(u32 addr1, u32 addr2) | 34 | hwsq_reg2(u32 addr1, u32 addr2) |
20 | { | 35 | { |
21 | return (struct hwsq_reg) { | 36 | return (struct hwsq_reg) { |
22 | .sequence = 0, | 37 | .sequence = 0, |
23 | .force = 0, | 38 | .force = 0, |
24 | .addr = { addr1, addr2 }, | 39 | .addr = addr1, |
40 | .stride = addr2 - addr1, | ||
41 | .mask = 0x3, | ||
25 | .data = 0xdeadbeef, | 42 | .data = 0xdeadbeef, |
26 | }; | 43 | }; |
27 | } | 44 | } |
@@ -29,7 +46,14 @@ hwsq_reg2(u32 addr1, u32 addr2) | |||
29 | static inline struct hwsq_reg | 46 | static inline struct hwsq_reg |
30 | hwsq_reg(u32 addr) | 47 | hwsq_reg(u32 addr) |
31 | { | 48 | { |
32 | return hwsq_reg2(addr, addr); | 49 | return (struct hwsq_reg) { |
50 | .sequence = 0, | ||
51 | .force = 0, | ||
52 | .addr = addr, | ||
53 | .stride = 0, | ||
54 | .mask = 0x1, | ||
55 | .data = 0xdeadbeef, | ||
56 | }; | ||
33 | } | 57 | } |
34 | 58 | ||
35 | static inline int | 59 | static inline int |
@@ -62,18 +86,24 @@ static inline u32 | |||
62 | hwsq_rd32(struct hwsq *ram, struct hwsq_reg *reg) | 86 | hwsq_rd32(struct hwsq *ram, struct hwsq_reg *reg) |
63 | { | 87 | { |
64 | if (reg->sequence != ram->sequence) | 88 | if (reg->sequence != ram->sequence) |
65 | reg->data = nv_rd32(ram->subdev, reg->addr[0]); | 89 | reg->data = nv_rd32(ram->subdev, reg->addr); |
66 | return reg->data; | 90 | return reg->data; |
67 | } | 91 | } |
68 | 92 | ||
69 | static inline void | 93 | static inline void |
70 | hwsq_wr32(struct hwsq *ram, struct hwsq_reg *reg, u32 data) | 94 | hwsq_wr32(struct hwsq *ram, struct hwsq_reg *reg, u32 data) |
71 | { | 95 | { |
96 | u32 mask, off = 0; | ||
97 | |||
72 | reg->sequence = ram->sequence; | 98 | reg->sequence = ram->sequence; |
73 | reg->data = data; | 99 | reg->data = data; |
74 | if (reg->addr[0] != reg->addr[1]) | 100 | |
75 | nvkm_hwsq_wr32(ram->hwsq, reg->addr[1], reg->data); | 101 | for (mask = reg->mask; mask > 0; mask = (mask & ~1) >> 1) { |
76 | nvkm_hwsq_wr32(ram->hwsq, reg->addr[0], reg->data); | 102 | if (mask & 1) |
103 | nvkm_hwsq_wr32(ram->hwsq, reg->addr+off, reg->data); | ||
104 | |||
105 | off += reg->stride; | ||
106 | } | ||
77 | } | 107 | } |
78 | 108 | ||
79 | static inline void | 109 | static inline void |