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 "head.h"
0023 #include "core.h"
0024 
0025 #include <nvif/push507c.h>
0026 
0027 #include <nvhw/class/cl507d.h>
0028 
0029 int
0030 head507d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
0031 {
0032     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0033     const int i = head->base.index;
0034     int ret;
0035 
0036     if ((ret = PUSH_WAIT(push, 2)))
0037         return ret;
0038 
0039     PUSH_MTHD(push, NV507D, HEAD_SET_PROCAMP(i),
0040           NVDEF(NV507D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) |
0041           NVDEF(NV507D, HEAD_SET_PROCAMP, CHROMA_LPF, AUTO) |
0042           NVVAL(NV507D, HEAD_SET_PROCAMP, SAT_COS, asyh->procamp.sat.cos) |
0043           NVVAL(NV507D, HEAD_SET_PROCAMP, SAT_SINE, asyh->procamp.sat.sin) |
0044           NVDEF(NV507D, HEAD_SET_PROCAMP, TRANSITION, HARD));
0045     return 0;
0046 }
0047 
0048 int
0049 head507d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
0050 {
0051     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0052     const int i = head->base.index;
0053     int ret;
0054 
0055     if ((ret = PUSH_WAIT(push, 2)))
0056         return ret;
0057 
0058     PUSH_MTHD(push, NV507D, HEAD_SET_DITHER_CONTROL(i),
0059           NVVAL(NV507D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) |
0060           NVVAL(NV507D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) |
0061           NVVAL(NV507D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) |
0062           NVVAL(NV507D, HEAD_SET_DITHER_CONTROL, PHASE, 0));
0063     return 0;
0064 }
0065 
0066 int
0067 head507d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
0068 {
0069     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0070     const int i = head->base.index;
0071     u32 bounds = 0;
0072     int ret;
0073 
0074     if (asyh->ovly.cpp) {
0075         switch (asyh->ovly.cpp) {
0076         case 4: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break;
0077         case 2: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break;
0078         default:
0079             WARN_ON(1);
0080             break;
0081         }
0082         bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE);
0083     } else {
0084         bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16);
0085     }
0086 
0087     if ((ret = PUSH_WAIT(push, 2)))
0088         return ret;
0089 
0090     PUSH_MTHD(push, NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds);
0091     return 0;
0092 }
0093 
0094 int
0095 head507d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
0096 {
0097     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0098     const int i = head->base.index;
0099     u32 bounds = 0;
0100     int ret;
0101 
0102     if (asyh->base.cpp) {
0103         switch (asyh->base.cpp) {
0104         case 8: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break;
0105         case 4: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break;
0106         case 2: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break;
0107         case 1: bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_8); break;
0108         default:
0109             WARN_ON(1);
0110             break;
0111         }
0112         bounds |= NVDEF(NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE);
0113     }
0114 
0115     if ((ret = PUSH_WAIT(push, 2)))
0116         return ret;
0117 
0118     PUSH_MTHD(push, NV507D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds);
0119     return 0;
0120 }
0121 
0122 static int
0123 head507d_curs_clr(struct nv50_head *head)
0124 {
0125     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0126     const int i = head->base.index;
0127     int ret;
0128 
0129     if ((ret = PUSH_WAIT(push, 2)))
0130         return ret;
0131 
0132     PUSH_MTHD(push, NV507D, HEAD_SET_CONTROL_CURSOR(i),
0133           NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) |
0134           NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8) |
0135           NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, SIZE, W64_H64));
0136     return 0;
0137 }
0138 
0139 static int
0140 head507d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
0141 {
0142     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0143     const int i = head->base.index;
0144     int ret;
0145 
0146     if ((ret = PUSH_WAIT(push, 3)))
0147         return ret;
0148 
0149     PUSH_MTHD(push, NV507D, HEAD_SET_CONTROL_CURSOR(i),
0150           NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) |
0151           NVVAL(NV507D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) |
0152           NVVAL(NV507D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) |
0153           NVVAL(NV507D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) |
0154           NVVAL(NV507D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) |
0155           NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND) |
0156           NVDEF(NV507D, HEAD_SET_CONTROL_CURSOR, SUB_OWNER, NONE),
0157 
0158                 HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8);
0159     return 0;
0160 }
0161 
0162 int
0163 head507d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw,
0164              struct nv50_head_atom *asyh)
0165 {
0166     switch (asyw->image.format) {
0167     case 0xcf: asyh->curs.format = NV507D_HEAD_SET_CONTROL_CURSOR_FORMAT_A8R8G8B8; break;
0168     default:
0169         WARN_ON(1);
0170         return -EINVAL;
0171     }
0172     return 0;
0173 }
0174 
0175 int
0176 head507d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
0177              struct nv50_head_atom *asyh)
0178 {
0179     switch (asyw->image.w) {
0180     case 32: asyh->curs.layout = NV507D_HEAD_SET_CONTROL_CURSOR_SIZE_W32_H32; break;
0181     case 64: asyh->curs.layout = NV507D_HEAD_SET_CONTROL_CURSOR_SIZE_W64_H64; break;
0182     default:
0183         return -EINVAL;
0184     }
0185     return 0;
0186 }
0187 
0188 int
0189 head507d_core_clr(struct nv50_head *head)
0190 {
0191     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0192     const int i = head->base.index;
0193     int ret;
0194 
0195     if ((ret = PUSH_WAIT(push, 2)))
0196         return ret;
0197 
0198     PUSH_MTHD(push, NV507D, HEAD_SET_CONTEXT_DMA_ISO(i), 0x00000000);
0199     return 0;
0200 }
0201 
0202 static int
0203 head507d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh)
0204 {
0205     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0206     const int i = head->base.index;
0207     int ret;
0208 
0209     if ((ret = PUSH_WAIT(push, 9)))
0210         return ret;
0211 
0212     PUSH_MTHD(push, NV507D, HEAD_SET_OFFSET(i, 0),
0213           NVVAL(NV507D, HEAD_SET_OFFSET, ORIGIN, asyh->core.offset >> 8));
0214 
0215     PUSH_MTHD(push, NV507D, HEAD_SET_SIZE(i),
0216           NVVAL(NV507D, HEAD_SET_SIZE, WIDTH, asyh->core.w) |
0217           NVVAL(NV507D, HEAD_SET_SIZE, HEIGHT, asyh->core.h),
0218 
0219                 HEAD_SET_STORAGE(i),
0220           NVVAL(NV507D, HEAD_SET_STORAGE, BLOCK_HEIGHT, asyh->core.blockh) |
0221           NVVAL(NV507D, HEAD_SET_STORAGE, PITCH, asyh->core.pitch >> 8) |
0222           NVVAL(NV507D, HEAD_SET_STORAGE, PITCH, asyh->core.blocks) |
0223           NVVAL(NV507D, HEAD_SET_STORAGE, MEMORY_LAYOUT, asyh->core.layout),
0224 
0225                 HEAD_SET_PARAMS(i),
0226           NVVAL(NV507D, HEAD_SET_PARAMS, FORMAT, asyh->core.format) |
0227           NVVAL(NV507D, HEAD_SET_PARAMS, KIND, asyh->core.kind) |
0228           NVDEF(NV507D, HEAD_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256),
0229 
0230                 HEAD_SET_CONTEXT_DMA_ISO(i),
0231           NVVAL(NV507D, HEAD_SET_CONTEXT_DMA_ISO, HANDLE, asyh->core.handle));
0232 
0233     PUSH_MTHD(push, NV507D, HEAD_SET_VIEWPORT_POINT_IN(i, 0),
0234           NVVAL(NV507D, HEAD_SET_VIEWPORT_POINT_IN, X, asyh->core.x) |
0235           NVVAL(NV507D, HEAD_SET_VIEWPORT_POINT_IN, Y, asyh->core.y));
0236 
0237     /* EVO will complain with INVALID_STATE if we have an
0238      * active cursor and (re)specify HeadSetContextDmaIso
0239      * without also updating HeadSetOffsetCursor.
0240      */
0241     asyh->set.curs = asyh->curs.visible;
0242     asyh->set.olut = asyh->olut.handle != 0;
0243     return 0;
0244 }
0245 
0246 void
0247 head507d_core_calc(struct nv50_head *head, struct nv50_head_atom *asyh)
0248 {
0249     struct nv50_disp *disp = nv50_disp(head->base.base.dev);
0250     if ((asyh->core.visible = (asyh->base.cpp != 0))) {
0251         asyh->core.x = asyh->base.x;
0252         asyh->core.y = asyh->base.y;
0253         asyh->core.w = asyh->base.w;
0254         asyh->core.h = asyh->base.h;
0255     } else
0256     if ((asyh->core.visible = (asyh->ovly.cpp != 0)) ||
0257         (asyh->core.visible = asyh->curs.visible)) {
0258         /*XXX: We need to either find some way of having the
0259          *     primary base layer appear black, while still
0260          *     being able to display the other layers, or we
0261          *     need to allocate a dummy black surface here.
0262          */
0263         asyh->core.x = 0;
0264         asyh->core.y = 0;
0265         asyh->core.w = asyh->state.mode.hdisplay;
0266         asyh->core.h = asyh->state.mode.vdisplay;
0267     }
0268     asyh->core.handle = disp->core->chan.vram.handle;
0269     asyh->core.offset = 0;
0270     asyh->core.format = NV507D_HEAD_SET_PARAMS_FORMAT_A8R8G8B8;
0271     asyh->core.kind = NV507D_HEAD_SET_PARAMS_KIND_KIND_PITCH;
0272     asyh->core.layout = NV507D_HEAD_SET_STORAGE_MEMORY_LAYOUT_PITCH;
0273     asyh->core.blockh = NV507D_HEAD_SET_STORAGE_BLOCK_HEIGHT_ONE_GOB;
0274     asyh->core.blocks = 0;
0275     asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4;
0276 }
0277 
0278 static int
0279 head507d_olut_clr(struct nv50_head *head)
0280 {
0281     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0282     const int i = head->base.index;
0283     int ret;
0284 
0285     if ((ret = PUSH_WAIT(push, 2)))
0286         return ret;
0287 
0288     PUSH_MTHD(push, NV507D, HEAD_SET_BASE_LUT_LO(i),
0289           NVDEF(NV507D, HEAD_SET_BASE_LUT_LO, ENABLE, DISABLE));
0290     return 0;
0291 }
0292 
0293 static int
0294 head507d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
0295 {
0296     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0297     const int i = head->base.index;
0298     int ret;
0299 
0300     if ((ret = PUSH_WAIT(push, 3)))
0301         return ret;
0302 
0303     PUSH_MTHD(push, NV507D, HEAD_SET_BASE_LUT_LO(i),
0304           NVDEF(NV507D, HEAD_SET_BASE_LUT_LO, ENABLE, ENABLE) |
0305           NVVAL(NV507D, HEAD_SET_BASE_LUT_LO, MODE, asyh->olut.mode) |
0306           NVVAL(NV507D, HEAD_SET_BASE_LUT_LO, ORIGIN, 0),
0307 
0308                 HEAD_SET_BASE_LUT_HI(i),
0309           NVVAL(NV507D, HEAD_SET_BASE_LUT_HI, ORIGIN, asyh->olut.offset >> 8));
0310     return 0;
0311 }
0312 
0313 static void
0314 head507d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
0315 {
0316     for (; size--; in++, mem += 8) {
0317         writew(drm_color_lut_extract(in->  red, 11) << 3, mem + 0);
0318         writew(drm_color_lut_extract(in->green, 11) << 3, mem + 2);
0319         writew(drm_color_lut_extract(in-> blue, 11) << 3, mem + 4);
0320     }
0321 
0322     /* INTERPOLATE modes require a "next" entry to interpolate with,
0323      * so we replicate the last entry to deal with this for now.
0324      */
0325     writew(readw(mem - 8), mem + 0);
0326     writew(readw(mem - 6), mem + 2);
0327     writew(readw(mem - 4), mem + 4);
0328 }
0329 
0330 bool
0331 head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
0332 {
0333     if (size != 256)
0334         return false;
0335 
0336     if (asyh->base.cpp == 1)
0337         asyh->olut.mode = NV507D_HEAD_SET_BASE_LUT_LO_MODE_LORES;
0338     else
0339         asyh->olut.mode = NV507D_HEAD_SET_BASE_LUT_LO_MODE_HIRES;
0340 
0341     asyh->olut.load = head507d_olut_load;
0342     return true;
0343 }
0344 
0345 int
0346 head507d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
0347 {
0348     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0349     struct nv50_head_mode *m = &asyh->mode;
0350     const int i = head->base.index;
0351     int ret;
0352 
0353     if ((ret = PUSH_WAIT(push, 13)))
0354         return ret;
0355 
0356     PUSH_MTHD(push, NV507D, HEAD_SET_PIXEL_CLOCK(i),
0357           NVVAL(NV507D, HEAD_SET_PIXEL_CLOCK, FREQUENCY, m->clock) |
0358           NVDEF(NV507D, HEAD_SET_PIXEL_CLOCK, MODE, CLK_CUSTOM) |
0359           NVDEF(NV507D, HEAD_SET_PIXEL_CLOCK, ADJ1000DIV1001, FALSE) |
0360           NVDEF(NV507D, HEAD_SET_PIXEL_CLOCK, NOT_DRIVER, FALSE),
0361 
0362                 HEAD_SET_CONTROL(i),
0363           NVVAL(NV507D, HEAD_SET_CONTROL, STRUCTURE, m->interlace));
0364 
0365     PUSH_MTHD(push, NV507D, HEAD_SET_OVERSCAN_COLOR(i),
0366           NVVAL(NV507D, HEAD_SET_OVERSCAN_COLOR, RED, 0) |
0367           NVVAL(NV507D, HEAD_SET_OVERSCAN_COLOR, GRN, 0) |
0368           NVVAL(NV507D, HEAD_SET_OVERSCAN_COLOR, BLU, 0),
0369 
0370                 HEAD_SET_RASTER_SIZE(i),
0371           NVVAL(NV507D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) |
0372           NVVAL(NV507D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active),
0373 
0374                 HEAD_SET_RASTER_SYNC_END(i),
0375           NVVAL(NV507D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) |
0376           NVVAL(NV507D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce),
0377 
0378                 HEAD_SET_RASTER_BLANK_END(i),
0379           NVVAL(NV507D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) |
0380           NVVAL(NV507D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke),
0381 
0382                 HEAD_SET_RASTER_BLANK_START(i),
0383           NVVAL(NV507D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) |
0384           NVVAL(NV507D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks),
0385 
0386                 HEAD_SET_RASTER_VERT_BLANK2(i),
0387           NVVAL(NV507D, HEAD_SET_RASTER_VERT_BLANK2, YSTART, m->v.blank2s) |
0388           NVVAL(NV507D, HEAD_SET_RASTER_VERT_BLANK2, YEND, m->v.blank2e),
0389 
0390                 HEAD_SET_RASTER_VERT_BLANK_DMI(i),
0391           NVVAL(NV507D, HEAD_SET_RASTER_VERT_BLANK_DMI, DURATION, m->v.blankus));
0392 
0393     PUSH_MTHD(push, NV507D, HEAD_SET_DEFAULT_BASE_COLOR(i),
0394           NVVAL(NV507D, HEAD_SET_DEFAULT_BASE_COLOR, RED, 0) |
0395           NVVAL(NV507D, HEAD_SET_DEFAULT_BASE_COLOR, GREEN, 0) |
0396           NVVAL(NV507D, HEAD_SET_DEFAULT_BASE_COLOR, BLUE, 0));
0397     return 0;
0398 }
0399 
0400 int
0401 head507d_view(struct nv50_head *head, struct nv50_head_atom *asyh)
0402 {
0403     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0404     const int i = head->base.index;
0405     int ret;
0406 
0407     if ((ret = PUSH_WAIT(push, 7)))
0408         return ret;
0409 
0410     PUSH_MTHD(push, NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER(i),
0411           NVDEF(NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER, VERTICAL_TAPS, TAPS_1) |
0412           NVDEF(NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER, HORIZONTAL_TAPS, TAPS_1) |
0413           NVVAL(NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER, HRESPONSE_BIAS, 0) |
0414           NVVAL(NV507D, HEAD_SET_CONTROL_OUTPUT_SCALER, VRESPONSE_BIAS, 0));
0415 
0416     PUSH_MTHD(push, NV507D, HEAD_SET_VIEWPORT_SIZE_IN(i),
0417           NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_IN, WIDTH, asyh->view.iW) |
0418           NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_IN, HEIGHT, asyh->view.iH));
0419 
0420     PUSH_MTHD(push, NV507D, HEAD_SET_VIEWPORT_SIZE_OUT(i),
0421           NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_OUT, WIDTH, asyh->view.oW) |
0422           NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_OUT, HEIGHT, asyh->view.oH),
0423 
0424                 HEAD_SET_VIEWPORT_SIZE_OUT_MIN(i),
0425           NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, WIDTH, asyh->view.oW) |
0426           NVVAL(NV507D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, HEIGHT, asyh->view.oH));
0427     return 0;
0428 }
0429 
0430 const struct nv50_head_func
0431 head507d = {
0432     .view = head507d_view,
0433     .mode = head507d_mode,
0434     .olut = head507d_olut,
0435     .olut_size = 256,
0436     .olut_set = head507d_olut_set,
0437     .olut_clr = head507d_olut_clr,
0438     .core_calc = head507d_core_calc,
0439     .core_set = head507d_core_set,
0440     .core_clr = head507d_core_clr,
0441     .curs_layout = head507d_curs_layout,
0442     .curs_format = head507d_curs_format,
0443     .curs_set = head507d_curs_set,
0444     .curs_clr = head507d_curs_clr,
0445     .base = head507d_base,
0446     .ovly = head507d_ovly,
0447     .dither = head507d_dither,
0448     .procamp = head507d_procamp,
0449 };