.. | .. |
---|
21 | 21 | */ |
---|
22 | 22 | #include "base.h" |
---|
23 | 23 | |
---|
24 | | -static void |
---|
| 24 | +#include <nvif/push507c.h> |
---|
| 25 | + |
---|
| 26 | +#include <nvhw/class/cl907c.h> |
---|
| 27 | + |
---|
| 28 | +static int |
---|
25 | 29 | base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
---|
26 | 30 | { |
---|
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; |
---|
45 | 63 | } |
---|
46 | 64 | |
---|
47 | | -static void |
---|
| 65 | +static int |
---|
48 | 66 | base907c_xlut_clr(struct nv50_wndw *wndw) |
---|
49 | 67 | { |
---|
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; |
---|
60 | 82 | } |
---|
61 | 83 | |
---|
62 | | -static void |
---|
| 84 | +static int |
---|
63 | 85 | base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) |
---|
64 | 86 | { |
---|
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); |
---|
75 | 137 | } |
---|
76 | 138 | } |
---|
77 | 139 | |
---|
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) |
---|
80 | 143 | { |
---|
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; |
---|
83 | 189 | } |
---|
84 | 190 | |
---|
85 | 191 | const struct nv50_wndw_func |
---|
.. | .. |
---|
93 | 199 | .ntfy_clr = base507c_ntfy_clr, |
---|
94 | 200 | .ntfy_wait_begun = base507c_ntfy_wait_begun, |
---|
95 | 201 | .ilut = base907c_ilut, |
---|
| 202 | + .csc = base907c_csc, |
---|
| 203 | + .csc_set = base907c_csc_set, |
---|
| 204 | + .csc_clr = base907c_csc_clr, |
---|
96 | 205 | .olut_core = true, |
---|
| 206 | + .ilut_size = 1024, |
---|
97 | 207 | .xlut_set = base907c_xlut_set, |
---|
98 | 208 | .xlut_clr = base907c_xlut_clr, |
---|
99 | 209 | .image_set = base907c_image_set, |
---|