0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "base.h"
0023
0024 #include <nvif/push507c.h>
0025
0026 #include <nvhw/class/cl907c.h>
0027
0028 static int
0029 base907c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
0030 {
0031 struct nvif_push *push = wndw->wndw.push;
0032 int ret;
0033
0034 if ((ret = PUSH_WAIT(push, 10)))
0035 return ret;
0036
0037 PUSH_MTHD(push, NV907C, SET_PRESENT_CONTROL,
0038 NVVAL(NV907C, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
0039 NVDEF(NV907C, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE) |
0040 NVVAL(NV907C, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
0041
0042 PUSH_MTHD(push, NV907C, SET_CONTEXT_DMAS_ISO(0), asyw->image.handle, 1);
0043
0044 PUSH_MTHD(push, NV907C, SURFACE_SET_OFFSET(0, 0), asyw->image.offset[0] >> 8,
0045 SURFACE_SET_OFFSET(0, 1), 0x00000000,
0046
0047 SURFACE_SET_SIZE(0),
0048 NVVAL(NV907C, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
0049 NVVAL(NV907C, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
0050
0051 SURFACE_SET_STORAGE(0),
0052 NVVAL(NV907C, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
0053 NVVAL(NV907C, SURFACE_SET_STORAGE, PITCH, asyw->image.pitch[0] >> 8) |
0054 NVVAL(NV907C, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
0055 NVVAL(NV907C, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
0056
0057 SURFACE_SET_PARAMS(0),
0058 NVVAL(NV907C, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
0059 NVDEF(NV907C, SURFACE_SET_PARAMS, SUPER_SAMPLE, X1_AA) |
0060 NVDEF(NV907C, SURFACE_SET_PARAMS, GAMMA, LINEAR) |
0061 NVDEF(NV907C, SURFACE_SET_PARAMS, LAYOUT, FRM));
0062 return 0;
0063 }
0064
0065 static int
0066 base907c_xlut_clr(struct nv50_wndw *wndw)
0067 {
0068 struct nvif_push *push = wndw->wndw.push;
0069 int ret;
0070
0071 if ((ret = PUSH_WAIT(push, 6)))
0072 return ret;
0073
0074 PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO,
0075 NVDEF(NV907C, SET_BASE_LUT_LO, ENABLE, DISABLE));
0076
0077 PUSH_MTHD(push, NV907C, SET_OUTPUT_LUT_LO,
0078 NVDEF(NV907C, SET_OUTPUT_LUT_LO, ENABLE, DISABLE));
0079
0080 PUSH_MTHD(push, NV907C, SET_CONTEXT_DMA_LUT, 0x00000000);
0081 return 0;
0082 }
0083
0084 static int
0085 base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
0086 {
0087 struct nvif_push *push = wndw->wndw.push;
0088 int ret;
0089
0090 if ((ret = PUSH_WAIT(push, 6)))
0091 return ret;
0092
0093 PUSH_MTHD(push, NV907C, SET_BASE_LUT_LO,
0094 NVVAL(NV907C, SET_BASE_LUT_LO, ENABLE, asyw->xlut.i.enable) |
0095 NVVAL(NV907C, SET_BASE_LUT_LO, MODE, asyw->xlut.i.mode),
0096
0097 SET_BASE_LUT_HI, asyw->xlut.i.offset >> 8,
0098
0099 SET_OUTPUT_LUT_LO,
0100 NVDEF(NV907C, SET_OUTPUT_LUT_LO, ENABLE, USE_CORE_LUT));
0101
0102 PUSH_MTHD(push, NV907C, SET_CONTEXT_DMA_LUT, asyw->xlut.handle);
0103 return 0;
0104 }
0105
0106 static void
0107 base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
0108 {
0109 if (size == 1024)
0110 asyw->xlut.i.mode = NV907C_SET_BASE_LUT_LO_MODE_INTERPOLATE_1025_UNITY_RANGE;
0111 else
0112 asyw->xlut.i.mode = NV907C_SET_BASE_LUT_LO_MODE_INTERPOLATE_257_UNITY_RANGE;
0113
0114 asyw->xlut.i.enable = NV907C_SET_BASE_LUT_LO_ENABLE_ENABLE;
0115 asyw->xlut.i.load = head907d_olut_load;
0116 }
0117
0118 static inline u32
0119 csc_drm_to_base(u64 in)
0120 {
0121
0122 bool sign = in & BIT_ULL(63);
0123 u32 integer = (in >> 32) & 0x7fffffff;
0124 u32 fraction = in & 0xffffffff;
0125
0126 if (integer >= 4) {
0127 return (1 << 18) - (sign ? 0 : 1);
0128 } else {
0129 u32 ret = (integer << 16) | (fraction >> 16);
0130 if (sign)
0131 ret = -ret;
0132 return ret & GENMASK(18, 0);
0133 }
0134 }
0135
0136 void
0137 base907c_csc(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
0138 const struct drm_color_ctm *ctm)
0139 {
0140 int i, j;
0141
0142 for (j = 0; j < 3; j++) {
0143 for (i = 0; i < 4; i++) {
0144 u32 *val = &asyw->csc.matrix[j * 4 + i];
0145
0146
0147 if (i == 3) {
0148 *val = 0;
0149 } else {
0150 *val = csc_drm_to_base(ctm->matrix[j * 3 + i]);
0151 }
0152 }
0153 }
0154 }
0155
0156 static int
0157 base907c_csc_clr(struct nv50_wndw *wndw)
0158 {
0159 struct nvif_push *push = wndw->wndw.push;
0160 int ret;
0161
0162 if ((ret = PUSH_WAIT(push, 2)))
0163 return ret;
0164
0165 PUSH_MTHD(push, NV907C, SET_CSC_RED2RED,
0166 NVDEF(NV907C, SET_CSC_RED2RED, OWNER, CORE));
0167 return 0;
0168 }
0169
0170 static int
0171 base907c_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
0172 {
0173 struct nvif_push *push = wndw->wndw.push;
0174 int ret;
0175
0176 if ((ret = PUSH_WAIT(push, 13)))
0177 return ret;
0178
0179 PUSH_MTHD(push, NV907C, SET_CSC_RED2RED,
0180 NVDEF(NV907C, SET_CSC_RED2RED, OWNER, BASE) |
0181 NVVAL(NV907C, SET_CSC_RED2RED, COEFF, asyw->csc.matrix[0]),
0182
0183 SET_CSC_GRN2RED, &asyw->csc.matrix[1], 11);
0184 return 0;
0185 }
0186
0187 const struct nv50_wndw_func
0188 base907c = {
0189 .acquire = base507c_acquire,
0190 .release = base507c_release,
0191 .sema_set = base507c_sema_set,
0192 .sema_clr = base507c_sema_clr,
0193 .ntfy_reset = base507c_ntfy_reset,
0194 .ntfy_set = base507c_ntfy_set,
0195 .ntfy_clr = base507c_ntfy_clr,
0196 .ntfy_wait_begun = base507c_ntfy_wait_begun,
0197 .ilut = base907c_ilut,
0198 .csc = base907c_csc,
0199 .csc_set = base907c_csc_set,
0200 .csc_clr = base907c_csc_clr,
0201 .olut_core = true,
0202 .ilut_size = 1024,
0203 .xlut_set = base907c_xlut_set,
0204 .xlut_clr = base907c_xlut_clr,
0205 .image_set = base907c_image_set,
0206 .image_clr = base507c_image_clr,
0207 .update = base507c_update,
0208 };
0209
0210 int
0211 base907c_new(struct nouveau_drm *drm, int head, s32 oclass,
0212 struct nv50_wndw **pwndw)
0213 {
0214 return base507c_new_(&base907c, base507c_format, drm, head, oclass,
0215 0x00000002 << (head * 4), pwndw);
0216 }