0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "wndw.h"
0023 #include "atom.h"
0024
0025 #include <drm/drm_atomic_helper.h>
0026 #include <drm/drm_plane_helper.h>
0027 #include <nouveau_bo.h>
0028
0029 #include <nvif/pushc37b.h>
0030
0031 #include <nvhw/class/clc57e.h>
0032
0033 static int
0034 wndwc57e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
0035 {
0036 struct nvif_push *push = wndw->wndw.push;
0037 int ret;
0038
0039 if ((ret = PUSH_WAIT(push, 17)))
0040 return ret;
0041
0042 PUSH_MTHD(push, NVC57E, SET_PRESENT_CONTROL,
0043 NVVAL(NVC57E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) |
0044 NVVAL(NVC57E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
0045 NVDEF(NVC57E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE));
0046
0047 PUSH_MTHD(push, NVC57E, SET_SIZE,
0048 NVVAL(NVC57E, SET_SIZE, WIDTH, asyw->image.w) |
0049 NVVAL(NVC57E, SET_SIZE, HEIGHT, asyw->image.h),
0050
0051 SET_STORAGE,
0052 NVVAL(NVC57E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
0053 NVVAL(NVC57E, SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
0054
0055 SET_PARAMS,
0056 NVVAL(NVC57E, SET_PARAMS, FORMAT, asyw->image.format) |
0057 NVDEF(NVC57E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) |
0058 NVDEF(NVC57E, SET_PARAMS, SWAP_UV, DISABLE) |
0059 NVDEF(NVC57E, SET_PARAMS, FMT_ROUNDING_MODE, ROUND_TO_NEAREST),
0060
0061 SET_PLANAR_STORAGE(0),
0062 NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) |
0063 NVVAL(NVC57E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6));
0064
0065 PUSH_MTHD(push, NVC57E, SET_CONTEXT_DMA_ISO(0), asyw->image.handle, 1);
0066 PUSH_MTHD(push, NVC57E, SET_OFFSET(0), asyw->image.offset[0] >> 8);
0067
0068 PUSH_MTHD(push, NVC57E, SET_POINT_IN(0),
0069 NVVAL(NVC57E, SET_POINT_IN, X, asyw->state.src_x >> 16) |
0070 NVVAL(NVC57E, SET_POINT_IN, Y, asyw->state.src_y >> 16));
0071
0072 PUSH_MTHD(push, NVC57E, SET_SIZE_IN,
0073 NVVAL(NVC57E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) |
0074 NVVAL(NVC57E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16));
0075
0076 PUSH_MTHD(push, NVC57E, SET_SIZE_OUT,
0077 NVVAL(NVC57E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) |
0078 NVVAL(NVC57E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h));
0079 return 0;
0080 }
0081
0082 int
0083 wndwc57e_csc_clr(struct nv50_wndw *wndw)
0084 {
0085 struct nvif_push *push = wndw->wndw.push;
0086 const u32 identity[12] = {
0087 0x00010000, 0x00000000, 0x00000000, 0x00000000,
0088 0x00000000, 0x00010000, 0x00000000, 0x00000000,
0089 0x00000000, 0x00000000, 0x00010000, 0x00000000,
0090 };
0091 int ret;
0092
0093 if ((ret = PUSH_WAIT(push, 1 + ARRAY_SIZE(identity))))
0094 return ret;
0095
0096 PUSH_MTHD(push, NVC57E, SET_FMT_COEFFICIENT_C00, identity, ARRAY_SIZE(identity));
0097 return 0;
0098 }
0099
0100 int
0101 wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
0102 {
0103 struct nvif_push *push = wndw->wndw.push;
0104 int ret;
0105
0106 if ((ret = PUSH_WAIT(push, 13)))
0107 return ret;
0108
0109 PUSH_MTHD(push, NVC57E, SET_FMT_COEFFICIENT_C00, asyw->csc.matrix, 12);
0110 return 0;
0111 }
0112
0113 int
0114 wndwc57e_ilut_clr(struct nv50_wndw *wndw)
0115 {
0116 struct nvif_push *push = wndw->wndw.push;
0117 int ret;
0118
0119 if ((ret = PUSH_WAIT(push, 2)))
0120 return ret;
0121
0122 PUSH_MTHD(push, NVC57E, SET_CONTEXT_DMA_ILUT, 0x00000000);
0123 return 0;
0124 }
0125
0126 int
0127 wndwc57e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
0128 {
0129 struct nvif_push *push = wndw->wndw.push;
0130 int ret;
0131
0132 if ((ret = PUSH_WAIT(push, 4)))
0133 return ret;
0134
0135 PUSH_MTHD(push, NVC57E, SET_ILUT_CONTROL,
0136 NVVAL(NVC57E, SET_ILUT_CONTROL, SIZE, asyw->xlut.i.size) |
0137 NVVAL(NVC57E, SET_ILUT_CONTROL, MODE, asyw->xlut.i.mode) |
0138 NVVAL(NVC57E, SET_ILUT_CONTROL, INTERPOLATE, asyw->xlut.i.output_mode),
0139
0140 SET_CONTEXT_DMA_ILUT, asyw->xlut.handle,
0141 SET_OFFSET_ILUT, asyw->xlut.i.offset >> 8);
0142 return 0;
0143 }
0144
0145 static u16
0146 fixedU0_16_FP16(u16 fixed)
0147 {
0148 int sign = 0, exp = 0, man = 0;
0149 if (fixed) {
0150 while (--exp && !(fixed & 0x8000))
0151 fixed <<= 1;
0152 man = ((fixed << 1) & 0xffc0) >> 6;
0153 exp += 15;
0154 }
0155 return (sign << 15) | (exp << 10) | man;
0156 }
0157
0158 static void
0159 wndwc57e_ilut_load(struct drm_color_lut *in, int size, void __iomem *mem)
0160 {
0161 memset_io(mem, 0x00, 0x20);
0162 mem += 0x20;
0163
0164 for (; size--; in++, mem += 0x08) {
0165 u16 r = fixedU0_16_FP16(drm_color_lut_extract(in-> red, 16));
0166 u16 g = fixedU0_16_FP16(drm_color_lut_extract(in->green, 16));
0167 u16 b = fixedU0_16_FP16(drm_color_lut_extract(in-> blue, 16));
0168 writew(r, mem + 0);
0169 writew(g, mem + 2);
0170 writew(b, mem + 4);
0171 }
0172
0173
0174
0175
0176 writew(readw(mem - 8), mem + 0);
0177 writew(readw(mem - 6), mem + 2);
0178 writew(readw(mem - 4), mem + 4);
0179 }
0180
0181 void
0182 wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
0183 {
0184 if (!size)
0185 size = 1024;
0186
0187 if (size == 256)
0188 asyw->xlut.i.mode = NVC57E_SET_ILUT_CONTROL_MODE_DIRECT8;
0189 else
0190 asyw->xlut.i.mode = NVC57E_SET_ILUT_CONTROL_MODE_DIRECT10;
0191
0192 asyw->xlut.i.size = 4 + size + 1 ;
0193 asyw->xlut.i.output_mode = NVC57E_SET_ILUT_CONTROL_INTERPOLATE_DISABLE;
0194 asyw->xlut.i.load = wndwc57e_ilut_load;
0195 }
0196
0197
0198
0199
0200
0201
0202
0203 const u64 wndwc57e_modifiers[] = {
0204 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0),
0205 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1),
0206 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2),
0207 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3),
0208 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4),
0209 DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5),
0210 DRM_FORMAT_MOD_LINEAR,
0211 DRM_FORMAT_MOD_INVALID
0212 };
0213
0214 static const struct nv50_wndw_func
0215 wndwc57e = {
0216 .acquire = wndwc37e_acquire,
0217 .release = wndwc37e_release,
0218 .sema_set = wndwc37e_sema_set,
0219 .sema_clr = wndwc37e_sema_clr,
0220 .ntfy_set = wndwc37e_ntfy_set,
0221 .ntfy_clr = wndwc37e_ntfy_clr,
0222 .ntfy_reset = corec37d_ntfy_init,
0223 .ntfy_wait_begun = base507c_ntfy_wait_begun,
0224 .ilut = wndwc57e_ilut,
0225 .ilut_identity = true,
0226 .ilut_size = 1024,
0227 .xlut_set = wndwc57e_ilut_set,
0228 .xlut_clr = wndwc57e_ilut_clr,
0229 .csc = base907c_csc,
0230 .csc_set = wndwc57e_csc_set,
0231 .csc_clr = wndwc57e_csc_clr,
0232 .image_set = wndwc57e_image_set,
0233 .image_clr = wndwc37e_image_clr,
0234 .blend_set = wndwc37e_blend_set,
0235 .update = wndwc37e_update,
0236 };
0237
0238 int
0239 wndwc57e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
0240 s32 oclass, struct nv50_wndw **pwndw)
0241 {
0242 return wndwc37e_new_(&wndwc57e, drm, type, index, oclass,
0243 BIT(index >> 1), pwndw);
0244 }