hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/gpu/drm/nouveau/dispnv50/base907c.c
....@@ -21,65 +21,171 @@
2121 */
2222 #include "base.h"
2323
24
-static void
24
+#include <nvif/push507c.h>
25
+
26
+#include <nvhw/class/cl907c.h>
27
+
28
+static int
2529 base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
2630 {
27
- u32 *push;
28
- if ((push = evo_wait(&wndw->wndw, 10))) {
29
- evo_mthd(push, 0x0084, 1);
30
- evo_data(push, asyw->image.mode << 8 |
31
- asyw->image.interval << 4);
32
- evo_mthd(push, 0x00c0, 1);
33
- evo_data(push, asyw->image.handle[0]);
34
- evo_mthd(push, 0x0400, 5);
35
- evo_data(push, asyw->image.offset[0] >> 8);
36
- evo_data(push, 0x00000000);
37
- evo_data(push, asyw->image.h << 16 | asyw->image.w);
38
- evo_data(push, asyw->image.layout << 24 |
39
- (asyw->image.pitch[0] >> 8) << 8 |
40
- asyw->image.blocks[0] << 8 |
41
- asyw->image.blockh);
42
- evo_data(push, asyw->image.format << 8);
43
- evo_kick(push, &wndw->wndw);
44
- }
31
+ struct nvif_push *push = wndw->wndw.push;
32
+ int ret;
33
+
34
+ if ((ret = PUSH_WAIT(push, 10)))
35
+ return ret;
36
+
37
+ PUSH_MTHD(push, NV907C, SET_PRESENT_CONTROL,
38
+ NVVAL(NV907C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
39
+ NVDEF(NV907C, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE) |
40
+ NVVAL(NV907C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
41
+
42
+ PUSH_MTHD(push, NV907C, SET_CONTEXT_DMAS_ISO(0), asyw->image.handle, 1);
43
+
44
+ PUSH_MTHD(push, NV907C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8,
45
+ SURFACE_SET_OFFSET(0, 1), 0x00000000,
46
+
47
+ SURFACE_SET_SIZE(0),
48
+ NVVAL(NV907C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
49
+ NVVAL(NV907C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
50
+
51
+ SURFACE_SET_STORAGE(0),
52
+ NVVAL(NV907C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
53
+ NVVAL(NV907C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) |
54
+ NVVAL(NV907C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
55
+ NVVAL(NV907C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
56
+
57
+ SURFACE_SET_PARAMS(0),
58
+ NVVAL(NV907C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
59
+ NVDEF(NV907C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) |
60
+ NVDEF(NV907C, SURFACE_SET_PARAMS, GAMMA, LINEAR) |
61
+ NVDEF(NV907C, SURFACE_SET_PARAMS, LAYOUT, FRM));
62
+ return 0;
4563 }
4664
47
-static void
65
+static int
4866 base907c_xlut_clr(struct nv50_wndw *wndw)
4967 {
50
- u32 *push;
51
- if ((push = evo_wait(&wndw->wndw, 6))) {
52
- evo_mthd(push, 0x00e0, 1);
53
- evo_data(push, 0x00000000);
54
- evo_mthd(push, 0x00e8, 1);
55
- evo_data(push, 0x00000000);
56
- evo_mthd(push, 0x00fc, 1);
57
- evo_data(push, 0x00000000);
58
- evo_kick(push, &wndw->wndw);
59
- }
68
+ struct nvif_push *push = wndw->wndw.push;
69
+ int ret;
70
+
71
+ if ((ret = PUSH_WAIT(push, 6)))
72
+ return ret;
73
+
74
+ PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO,
75
+ NVDEF(NV907C, SET_BASE_LUT_LO, ENABLE, DISABLE));
76
+
77
+ PUSH_MTHD(push, NV907C, SET_OUTPUT_LUT_LO,
78
+ NVDEF(NV907C, SET_OUTPUT_LUT_LO, ENABLE, DISABLE));
79
+
80
+ PUSH_MTHD(push, NV907C, SET_CONTEXT_DMA_LUT, 0x00000000);
81
+ return 0;
6082 }
6183
62
-static void
84
+static int
6385 base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
6486 {
65
- u32 *push;
66
- if ((push = evo_wait(&wndw->wndw, 6))) {
67
- evo_mthd(push, 0x00e0, 3);
68
- evo_data(push, asyw->xlut.i.enable << 30 |
69
- asyw->xlut.i.mode << 24);
70
- evo_data(push, asyw->xlut.i.offset >> 8);
71
- evo_data(push, 0x40000000);
72
- evo_mthd(push, 0x00fc, 1);
73
- evo_data(push, asyw->xlut.handle);
74
- evo_kick(push, &wndw->wndw);
87
+ struct nvif_push *push = wndw->wndw.push;
88
+ int ret;
89
+
90
+ if ((ret = PUSH_WAIT(push, 6)))
91
+ return ret;
92
+
93
+ PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO,
94
+ NVVAL(NV907C, SET_BASE_LUT_LO, ENABLE, asyw->xlut.i.enable) |
95
+ NVVAL(NV907C, SET_BASE_LUT_LO, MODE, asyw->xlut.i.mode),
96
+
97
+ SET_BASE_LUT_HI, asyw->xlut.i.offset >> 8,
98
+
99
+ SET_OUTPUT_LUT_LO,
100
+ NVDEF(NV907C, SET_OUTPUT_LUT_LO, ENABLE, USE_CORE_LUT));
101
+
102
+ PUSH_MTHD(push, NV907C, SET_CONTEXT_DMA_LUT, asyw->xlut.handle);
103
+ return 0;
104
+}
105
+
106
+static bool
107
+base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
108
+{
109
+ if (size != 256 && size != 1024)
110
+ return false;
111
+
112
+ if (size == 1024)
113
+ asyw->xlut.i.mode = NV907C_SET_BASE_LUT_LO_MODE_INTERPOLATE_1025_UNITY_RANGE;
114
+ else
115
+ asyw->xlut.i.mode = NV907C_SET_BASE_LUT_LO_MODE_INTERPOLATE_257_UNITY_RANGE;
116
+
117
+ asyw->xlut.i.enable = NV907C_SET_BASE_LUT_LO_ENABLE_ENABLE;
118
+ asyw->xlut.i.load = head907d_olut_load;
119
+ return true;
120
+}
121
+
122
+static inline u32
123
+csc_drm_to_base(u64 in)
124
+{
125
+ /* base takes a 19-bit 2's complement value in S3.16 format */
126
+ bool sign = in & BIT_ULL(63);
127
+ u32 integer = (in >> 32) & 0x7fffffff;
128
+ u32 fraction = in & 0xffffffff;
129
+
130
+ if (integer >= 4) {
131
+ return (1 << 18) - (sign ? 0 : 1);
132
+ } else {
133
+ u32 ret = (integer << 16) | (fraction >> 16);
134
+ if (sign)
135
+ ret = -ret;
136
+ return ret & GENMASK(18, 0);
75137 }
76138 }
77139
78
-static void
79
-base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
140
+void
141
+base907c_csc(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
142
+ const struct drm_color_ctm *ctm)
80143 {
81
- asyw->xlut.i.mode = 7;
82
- asyw->xlut.i.enable = 2;
144
+ int i, j;
145
+
146
+ for (j = 0; j < 3; j++) {
147
+ for (i = 0; i < 4; i++) {
148
+ u32 *val = &asyw->csc.matrix[j * 4 + i];
149
+ /* DRM does not support constant offset, while
150
+ * HW CSC does. Skip it. */
151
+ if (i == 3) {
152
+ *val = 0;
153
+ } else {
154
+ *val = csc_drm_to_base(ctm->matrix[j * 3 + i]);
155
+ }
156
+ }
157
+ }
158
+}
159
+
160
+static int
161
+base907c_csc_clr(struct nv50_wndw *wndw)
162
+{
163
+ struct nvif_push *push = wndw->wndw.push;
164
+ int ret;
165
+
166
+ if ((ret = PUSH_WAIT(push, 2)))
167
+ return ret;
168
+
169
+ PUSH_MTHD(push, NV907C, SET_CSC_RED2RED,
170
+ NVDEF(NV907C, SET_CSC_RED2RED, OWNER, CORE));
171
+ return 0;
172
+}
173
+
174
+static int
175
+base907c_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
176
+{
177
+ struct nvif_push *push = wndw->wndw.push;
178
+ int ret;
179
+
180
+ if ((ret = PUSH_WAIT(push, 13)))
181
+ return ret;
182
+
183
+ PUSH_MTHD(push, NV907C, SET_CSC_RED2RED,
184
+ NVDEF(NV907C, SET_CSC_RED2RED, OWNER, BASE) |
185
+ NVVAL(NV907C, SET_CSC_RED2RED, COEFF, asyw->csc.matrix[0]),
186
+
187
+ SET_CSC_GRN2RED, &asyw->csc.matrix[1], 11);
188
+ return 0;
83189 }
84190
85191 const struct nv50_wndw_func
....@@ -93,7 +199,11 @@
93199 .ntfy_clr = base507c_ntfy_clr,
94200 .ntfy_wait_begun = base507c_ntfy_wait_begun,
95201 .ilut = base907c_ilut,
202
+ .csc = base907c_csc,
203
+ .csc_set = base907c_csc_set,
204
+ .csc_clr = base907c_csc_clr,
96205 .olut_core = true,
206
+ .ilut_size = 1024,
97207 .xlut_set = base907c_xlut_set,
98208 .xlut_clr = base907c_xlut_clr,
99209 .image_set = base907c_image_set,