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 <drm/drm_connector.h>
0023 #include <drm/drm_mode_config.h>
0024 #include <drm/drm_vblank.h>
0025 #include "nouveau_drv.h"
0026 #include "nouveau_bios.h"
0027 #include "nouveau_connector.h"
0028 #include "head.h"
0029 #include "core.h"
0030 #include "crc.h"
0031 
0032 #include <nvif/push507c.h>
0033 
0034 #include <nvhw/class/cl907d.h>
0035 
0036 int
0037 head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh)
0038 {
0039     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0040     const int i = head->base.index;
0041     int ret;
0042 
0043     if ((ret = PUSH_WAIT(push, 3)))
0044         return ret;
0045 
0046     PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE(i),
0047           NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, CRC_MODE, asyh->or.crc_raster) |
0048           NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, HSYNC_POLARITY, asyh->or.nhsync) |
0049           NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, VSYNC_POLARITY, asyh->or.nvsync) |
0050           NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, PIXEL_DEPTH, asyh->or.depth),
0051 
0052                 HEAD_SET_CONTROL(i), 0x31ec6000 | head->base.index << 25 |
0053           NVVAL(NV907D, HEAD_SET_CONTROL, STRUCTURE, asyh->mode.interlace));
0054     return 0;
0055 }
0056 
0057 int
0058 head907d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
0059 {
0060     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0061     const int i = head->base.index;
0062     int ret;
0063 
0064     if ((ret = PUSH_WAIT(push, 2)))
0065         return ret;
0066 
0067     PUSH_MTHD(push, NV907D, HEAD_SET_PROCAMP(i),
0068           NVDEF(NV907D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) |
0069           NVDEF(NV907D, HEAD_SET_PROCAMP, CHROMA_LPF, AUTO) |
0070           NVVAL(NV907D, HEAD_SET_PROCAMP, SAT_COS, asyh->procamp.sat.cos) |
0071           NVVAL(NV907D, HEAD_SET_PROCAMP, SAT_SINE, asyh->procamp.sat.sin) |
0072           NVDEF(NV907D, HEAD_SET_PROCAMP, DYNAMIC_RANGE, VESA) |
0073           NVDEF(NV907D, HEAD_SET_PROCAMP, RANGE_COMPRESSION, DISABLE));
0074     return 0;
0075 }
0076 
0077 static int
0078 head907d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
0079 {
0080     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0081     const int i = head->base.index;
0082     int ret;
0083 
0084     if ((ret = PUSH_WAIT(push, 2)))
0085         return ret;
0086 
0087     PUSH_MTHD(push, NV907D, HEAD_SET_DITHER_CONTROL(i),
0088           NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) |
0089           NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) |
0090           NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) |
0091           NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, PHASE, 0));
0092     return 0;
0093 }
0094 
0095 int
0096 head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
0097 {
0098     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0099     const int i = head->base.index;
0100     u32 bounds = 0;
0101     int ret;
0102 
0103     if (asyh->ovly.cpp) {
0104         switch (asyh->ovly.cpp) {
0105         case 8: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break;
0106         case 4: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break;
0107         case 2: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break;
0108         default:
0109             WARN_ON(1);
0110             break;
0111         }
0112         bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, USABLE, TRUE);
0113     } else {
0114         bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16);
0115     }
0116 
0117     if ((ret = PUSH_WAIT(push, 2)))
0118         return ret;
0119 
0120     PUSH_MTHD(push, NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS(i), bounds);
0121     return 0;
0122 }
0123 
0124 static int
0125 head907d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
0126 {
0127     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0128     const int i = head->base.index;
0129     u32 bounds = 0;
0130     int ret;
0131 
0132     if (asyh->base.cpp) {
0133         switch (asyh->base.cpp) {
0134         case 8: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break;
0135         case 4: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break;
0136         case 2: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break;
0137         case 1: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_8); break;
0138         default:
0139             WARN_ON(1);
0140             break;
0141         }
0142         bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE);
0143     }
0144 
0145     if ((ret = PUSH_WAIT(push, 2)))
0146         return ret;
0147 
0148     PUSH_MTHD(push, NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds);
0149     return 0;
0150 }
0151 
0152 int
0153 head907d_curs_clr(struct nv50_head *head)
0154 {
0155     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0156     const int i = head->base.index;
0157     int ret;
0158 
0159     if ((ret = PUSH_WAIT(push, 4)))
0160         return ret;
0161 
0162     PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_CURSOR(i),
0163           NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) |
0164           NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8) |
0165           NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, SIZE, W64_H64));
0166 
0167     PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CURSOR(i), 0x00000000);
0168     return 0;
0169 }
0170 
0171 int
0172 head907d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
0173 {
0174     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0175     const int i = head->base.index;
0176     int ret;
0177 
0178     if ((ret = PUSH_WAIT(push, 5)))
0179         return ret;
0180 
0181     PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_CURSOR(i),
0182           NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) |
0183           NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) |
0184           NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) |
0185           NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) |
0186           NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) |
0187           NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND),
0188 
0189                 HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8);
0190 
0191     PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle);
0192     return 0;
0193 }
0194 
0195 int
0196 head907d_core_clr(struct nv50_head *head)
0197 {
0198     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0199     const int i = head->base.index;
0200     int ret;
0201 
0202     if ((ret = PUSH_WAIT(push, 2)))
0203         return ret;
0204 
0205     PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMAS_ISO(i), 0x00000000);
0206     return 0;
0207 }
0208 
0209 int
0210 head907d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh)
0211 {
0212     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0213     const int i = head->base.index;
0214     int ret;
0215 
0216     if ((ret = PUSH_WAIT(push, 9)))
0217         return ret;
0218 
0219     PUSH_MTHD(push, NV907D, HEAD_SET_OFFSET(i),
0220           NVVAL(NV907D, HEAD_SET_OFFSET, ORIGIN, asyh->core.offset >> 8));
0221 
0222     PUSH_MTHD(push, NV907D, HEAD_SET_SIZE(i),
0223           NVVAL(NV907D, HEAD_SET_SIZE, WIDTH, asyh->core.w) |
0224           NVVAL(NV907D, HEAD_SET_SIZE, HEIGHT, asyh->core.h),
0225 
0226                 HEAD_SET_STORAGE(i),
0227           NVVAL(NV907D, HEAD_SET_STORAGE, BLOCK_HEIGHT, asyh->core.blockh) |
0228           NVVAL(NV907D, HEAD_SET_STORAGE, PITCH, asyh->core.pitch >> 8) |
0229           NVVAL(NV907D, HEAD_SET_STORAGE, PITCH, asyh->core.blocks) |
0230           NVVAL(NV907D, HEAD_SET_STORAGE, MEMORY_LAYOUT, asyh->core.layout),
0231 
0232                 HEAD_SET_PARAMS(i),
0233           NVVAL(NV907D, HEAD_SET_PARAMS, FORMAT, asyh->core.format) |
0234           NVDEF(NV907D, HEAD_SET_PARAMS, SUPER_SAMPLE, X1_AA) |
0235           NVDEF(NV907D, HEAD_SET_PARAMS, GAMMA, LINEAR),
0236 
0237                 HEAD_SET_CONTEXT_DMAS_ISO(i),
0238           NVVAL(NV907D, HEAD_SET_CONTEXT_DMAS_ISO, HANDLE, asyh->core.handle));
0239 
0240     PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_POINT_IN(i),
0241           NVVAL(NV907D, HEAD_SET_VIEWPORT_POINT_IN, X, asyh->core.x) |
0242           NVVAL(NV907D, HEAD_SET_VIEWPORT_POINT_IN, Y, asyh->core.y));
0243     return 0;
0244 }
0245 
0246 int
0247 head907d_olut_clr(struct nv50_head *head)
0248 {
0249     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0250     const int i = head->base.index;
0251     int ret;
0252 
0253     if ((ret = PUSH_WAIT(push, 4)))
0254         return ret;
0255 
0256     PUSH_MTHD(push, NV907D, HEAD_SET_OUTPUT_LUT_LO(i),
0257           NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, ENABLE, DISABLE));
0258 
0259     PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_LUT(i), 0x00000000);
0260     return 0;
0261 }
0262 
0263 int
0264 head907d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
0265 {
0266     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0267     const int i = head->base.index;
0268     int ret;
0269 
0270     if ((ret = PUSH_WAIT(push, 5)))
0271         return ret;
0272 
0273     PUSH_MTHD(push, NV907D, HEAD_SET_OUTPUT_LUT_LO(i),
0274           NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, ENABLE, ENABLE) |
0275           NVVAL(NV907D, HEAD_SET_OUTPUT_LUT_LO, MODE, asyh->olut.mode) |
0276           NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, NEVER_YIELD_TO_BASE, DISABLE),
0277 
0278                 HEAD_SET_OUTPUT_LUT_HI(i),
0279           NVVAL(NV907D, HEAD_SET_OUTPUT_LUT_HI, ORIGIN, asyh->olut.offset >> 8));
0280 
0281     PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_LUT(i), asyh->olut.handle);
0282     return 0;
0283 }
0284 
0285 void
0286 head907d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
0287 {
0288     for (; size--; in++, mem += 8) {
0289         writew(drm_color_lut_extract(in->  red, 14) + 0x6000, mem + 0);
0290         writew(drm_color_lut_extract(in->green, 14) + 0x6000, mem + 2);
0291         writew(drm_color_lut_extract(in-> blue, 14) + 0x6000, mem + 4);
0292     }
0293 
0294     /* INTERPOLATE modes require a "next" entry to interpolate with,
0295      * so we replicate the last entry to deal with this for now.
0296      */
0297     writew(readw(mem - 8), mem + 0);
0298     writew(readw(mem - 6), mem + 2);
0299     writew(readw(mem - 4), mem + 4);
0300 }
0301 
0302 bool
0303 head907d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
0304 {
0305     if (size != 256 && size != 1024)
0306         return false;
0307 
0308     if (size == 1024)
0309         asyh->olut.mode = NV907D_HEAD_SET_OUTPUT_LUT_LO_MODE_INTERPOLATE_1025_UNITY_RANGE;
0310     else
0311         asyh->olut.mode = NV907D_HEAD_SET_OUTPUT_LUT_LO_MODE_INTERPOLATE_257_UNITY_RANGE;
0312 
0313     asyh->olut.load = head907d_olut_load;
0314     return true;
0315 }
0316 
0317 bool head907d_ilut_check(int size)
0318 {
0319     return size == 256 || size == 1024;
0320 }
0321 
0322 int
0323 head907d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
0324 {
0325     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0326     struct nv50_head_mode *m = &asyh->mode;
0327     const int i = head->base.index;
0328     int ret;
0329 
0330     if ((ret = PUSH_WAIT(push, 13)))
0331         return ret;
0332 
0333     PUSH_MTHD(push, NV907D, HEAD_SET_OVERSCAN_COLOR(i),
0334           NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, RED, 0) |
0335           NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, GRN, 0) |
0336           NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, BLU, 0),
0337 
0338                 HEAD_SET_RASTER_SIZE(i),
0339           NVVAL(NV907D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) |
0340           NVVAL(NV907D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active),
0341 
0342                 HEAD_SET_RASTER_SYNC_END(i),
0343           NVVAL(NV907D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) |
0344           NVVAL(NV907D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce),
0345 
0346                 HEAD_SET_RASTER_BLANK_END(i),
0347           NVVAL(NV907D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) |
0348           NVVAL(NV907D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke),
0349 
0350                 HEAD_SET_RASTER_BLANK_START(i),
0351           NVVAL(NV907D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) |
0352           NVVAL(NV907D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks),
0353 
0354                 HEAD_SET_RASTER_VERT_BLANK2(i),
0355           NVVAL(NV907D, HEAD_SET_RASTER_VERT_BLANK2, YSTART, m->v.blank2s) |
0356           NVVAL(NV907D, HEAD_SET_RASTER_VERT_BLANK2, YEND, m->v.blank2e));
0357 
0358     PUSH_MTHD(push, NV907D, HEAD_SET_DEFAULT_BASE_COLOR(i),
0359           NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, RED, 0) |
0360           NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, GREEN, 0) |
0361           NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, BLUE, 0));
0362 
0363     PUSH_MTHD(push, NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY(i),
0364           NVVAL(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, m->clock * 1000) |
0365           NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, ADJ1000DIV1001, FALSE),
0366 
0367                 HEAD_SET_PIXEL_CLOCK_CONFIGURATION(i),
0368           NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, MODE, CLK_CUSTOM) |
0369           NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, NOT_DRIVER, FALSE) |
0370           NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, ENABLE_HOPPING, FALSE),
0371 
0372                 HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i),
0373           NVVAL(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, m->clock * 1000) |
0374           NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, ADJ1000DIV1001, FALSE));
0375     return 0;
0376 }
0377 
0378 int
0379 head907d_view(struct nv50_head *head, struct nv50_head_atom *asyh)
0380 {
0381     struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
0382     const int i = head->base.index;
0383     int ret;
0384 
0385     if ((ret = PUSH_WAIT(push, 8)))
0386         return ret;
0387 
0388     PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER(i),
0389           NVDEF(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, VERTICAL_TAPS, TAPS_1) |
0390           NVDEF(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, HORIZONTAL_TAPS, TAPS_1) |
0391           NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, HRESPONSE_BIAS, 0) |
0392           NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, VRESPONSE_BIAS, 0));
0393 
0394     PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_SIZE_IN(i),
0395           NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_IN, WIDTH, asyh->view.iW) |
0396           NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_IN, HEIGHT, asyh->view.iH));
0397 
0398     PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_SIZE_OUT(i),
0399           NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT, WIDTH, asyh->view.oW) |
0400           NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT, HEIGHT, asyh->view.oH),
0401 
0402                 HEAD_SET_VIEWPORT_SIZE_OUT_MIN(i),
0403           NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, WIDTH, asyh->view.oW) |
0404           NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, HEIGHT, asyh->view.oH),
0405 
0406                 HEAD_SET_VIEWPORT_SIZE_OUT_MAX(i),
0407           NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MAX, WIDTH, asyh->view.oW) |
0408           NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MAX, HEIGHT, asyh->view.oH));
0409     return 0;
0410 }
0411 
0412 const struct nv50_head_func
0413 head907d = {
0414     .view = head907d_view,
0415     .mode = head907d_mode,
0416     .olut = head907d_olut,
0417     .ilut_check = head907d_ilut_check,
0418     .olut_size = 1024,
0419     .olut_set = head907d_olut_set,
0420     .olut_clr = head907d_olut_clr,
0421     .core_calc = head507d_core_calc,
0422     .core_set = head907d_core_set,
0423     .core_clr = head907d_core_clr,
0424     .curs_layout = head507d_curs_layout,
0425     .curs_format = head507d_curs_format,
0426     .curs_set = head907d_curs_set,
0427     .curs_clr = head907d_curs_clr,
0428     .base = head907d_base,
0429     .ovly = head907d_ovly,
0430     .dither = head907d_dither,
0431     .procamp = head907d_procamp,
0432     .or = head907d_or,
0433 };