Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2018 Red Hat Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
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     /* base takes a 19-bit 2's complement value in S3.16 format */
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             /* DRM does not support constant offset, while
0146              * HW CSC does. Skip it. */
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 }