cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

head907d.c (14587B)


      1/*
      2 * Copyright 2018 Red Hat Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 */
     22#include <drm/drm_connector.h>
     23#include <drm/drm_mode_config.h>
     24#include <drm/drm_vblank.h>
     25#include "nouveau_drv.h"
     26#include "nouveau_bios.h"
     27#include "nouveau_connector.h"
     28#include "head.h"
     29#include "core.h"
     30#include "crc.h"
     31
     32#include <nvif/push507c.h>
     33
     34#include <nvhw/class/cl907d.h>
     35
     36int
     37head907d_or(struct nv50_head *head, struct nv50_head_atom *asyh)
     38{
     39	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
     40	const int i = head->base.index;
     41	int ret;
     42
     43	if ((ret = PUSH_WAIT(push, 3)))
     44		return ret;
     45
     46	PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE(i),
     47		  NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, CRC_MODE, asyh->or.crc_raster) |
     48		  NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, HSYNC_POLARITY, asyh->or.nhsync) |
     49		  NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, VSYNC_POLARITY, asyh->or.nvsync) |
     50		  NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_RESOURCE, PIXEL_DEPTH, asyh->or.depth),
     51
     52				HEAD_SET_CONTROL(i), 0x31ec6000 | head->base.index << 25 |
     53		  NVVAL(NV907D, HEAD_SET_CONTROL, STRUCTURE, asyh->mode.interlace));
     54	return 0;
     55}
     56
     57int
     58head907d_procamp(struct nv50_head *head, struct nv50_head_atom *asyh)
     59{
     60	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
     61	const int i = head->base.index;
     62	int ret;
     63
     64	if ((ret = PUSH_WAIT(push, 2)))
     65		return ret;
     66
     67	PUSH_MTHD(push, NV907D, HEAD_SET_PROCAMP(i),
     68		  NVDEF(NV907D, HEAD_SET_PROCAMP, COLOR_SPACE, RGB) |
     69		  NVDEF(NV907D, HEAD_SET_PROCAMP, CHROMA_LPF, AUTO) |
     70		  NVVAL(NV907D, HEAD_SET_PROCAMP, SAT_COS, asyh->procamp.sat.cos) |
     71		  NVVAL(NV907D, HEAD_SET_PROCAMP, SAT_SINE, asyh->procamp.sat.sin) |
     72		  NVDEF(NV907D, HEAD_SET_PROCAMP, DYNAMIC_RANGE, VESA) |
     73		  NVDEF(NV907D, HEAD_SET_PROCAMP, RANGE_COMPRESSION, DISABLE));
     74	return 0;
     75}
     76
     77static int
     78head907d_dither(struct nv50_head *head, struct nv50_head_atom *asyh)
     79{
     80	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
     81	const int i = head->base.index;
     82	int ret;
     83
     84	if ((ret = PUSH_WAIT(push, 2)))
     85		return ret;
     86
     87	PUSH_MTHD(push, NV907D, HEAD_SET_DITHER_CONTROL(i),
     88		  NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, ENABLE, asyh->dither.enable) |
     89		  NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, BITS, asyh->dither.bits) |
     90		  NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, MODE, asyh->dither.mode) |
     91		  NVVAL(NV907D, HEAD_SET_DITHER_CONTROL, PHASE, 0));
     92	return 0;
     93}
     94
     95int
     96head907d_ovly(struct nv50_head *head, struct nv50_head_atom *asyh)
     97{
     98	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
     99	const int i = head->base.index;
    100	u32 bounds = 0;
    101	int ret;
    102
    103	if (asyh->ovly.cpp) {
    104		switch (asyh->ovly.cpp) {
    105		case 8: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break;
    106		case 4: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break;
    107		case 2: bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break;
    108		default:
    109			WARN_ON(1);
    110			break;
    111		}
    112		bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, USABLE, TRUE);
    113	} else {
    114		bounds |= NVDEF(NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16);
    115	}
    116
    117	if ((ret = PUSH_WAIT(push, 2)))
    118		return ret;
    119
    120	PUSH_MTHD(push, NV907D, HEAD_SET_OVERLAY_USAGE_BOUNDS(i), bounds);
    121	return 0;
    122}
    123
    124static int
    125head907d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
    126{
    127	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    128	const int i = head->base.index;
    129	u32 bounds = 0;
    130	int ret;
    131
    132	if (asyh->base.cpp) {
    133		switch (asyh->base.cpp) {
    134		case 8: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_64); break;
    135		case 4: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_32); break;
    136		case 2: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_16); break;
    137		case 1: bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, PIXEL_DEPTH, BPP_8); break;
    138		default:
    139			WARN_ON(1);
    140			break;
    141		}
    142		bounds |= NVDEF(NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS, USABLE, TRUE);
    143	}
    144
    145	if ((ret = PUSH_WAIT(push, 2)))
    146		return ret;
    147
    148	PUSH_MTHD(push, NV907D, HEAD_SET_BASE_CHANNEL_USAGE_BOUNDS(i), bounds);
    149	return 0;
    150}
    151
    152int
    153head907d_curs_clr(struct nv50_head *head)
    154{
    155	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    156	const int i = head->base.index;
    157	int ret;
    158
    159	if ((ret = PUSH_WAIT(push, 4)))
    160		return ret;
    161
    162	PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_CURSOR(i),
    163		  NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, ENABLE, DISABLE) |
    164		  NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, FORMAT, A8R8G8B8) |
    165		  NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, SIZE, W64_H64));
    166
    167	PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CURSOR(i), 0x00000000);
    168	return 0;
    169}
    170
    171int
    172head907d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
    173{
    174	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    175	const int i = head->base.index;
    176	int ret;
    177
    178	if ((ret = PUSH_WAIT(push, 5)))
    179		return ret;
    180
    181	PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_CURSOR(i),
    182		  NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, ENABLE, ENABLE) |
    183		  NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, FORMAT, asyh->curs.format) |
    184		  NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, SIZE, asyh->curs.layout) |
    185		  NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_X, 0) |
    186		  NVVAL(NV907D, HEAD_SET_CONTROL_CURSOR, HOT_SPOT_Y, 0) |
    187		  NVDEF(NV907D, HEAD_SET_CONTROL_CURSOR, COMPOSITION, ALPHA_BLEND),
    188
    189				HEAD_SET_OFFSET_CURSOR(i), asyh->curs.offset >> 8);
    190
    191	PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_CURSOR(i), asyh->curs.handle);
    192	return 0;
    193}
    194
    195int
    196head907d_core_clr(struct nv50_head *head)
    197{
    198	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    199	const int i = head->base.index;
    200	int ret;
    201
    202	if ((ret = PUSH_WAIT(push, 2)))
    203		return ret;
    204
    205	PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMAS_ISO(i), 0x00000000);
    206	return 0;
    207}
    208
    209int
    210head907d_core_set(struct nv50_head *head, struct nv50_head_atom *asyh)
    211{
    212	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    213	const int i = head->base.index;
    214	int ret;
    215
    216	if ((ret = PUSH_WAIT(push, 9)))
    217		return ret;
    218
    219	PUSH_MTHD(push, NV907D, HEAD_SET_OFFSET(i),
    220		  NVVAL(NV907D, HEAD_SET_OFFSET, ORIGIN, asyh->core.offset >> 8));
    221
    222	PUSH_MTHD(push, NV907D, HEAD_SET_SIZE(i),
    223		  NVVAL(NV907D, HEAD_SET_SIZE, WIDTH, asyh->core.w) |
    224		  NVVAL(NV907D, HEAD_SET_SIZE, HEIGHT, asyh->core.h),
    225
    226				HEAD_SET_STORAGE(i),
    227		  NVVAL(NV907D, HEAD_SET_STORAGE, BLOCK_HEIGHT, asyh->core.blockh) |
    228		  NVVAL(NV907D, HEAD_SET_STORAGE, PITCH, asyh->core.pitch >> 8) |
    229		  NVVAL(NV907D, HEAD_SET_STORAGE, PITCH, asyh->core.blocks) |
    230		  NVVAL(NV907D, HEAD_SET_STORAGE, MEMORY_LAYOUT, asyh->core.layout),
    231
    232				HEAD_SET_PARAMS(i),
    233		  NVVAL(NV907D, HEAD_SET_PARAMS, FORMAT, asyh->core.format) |
    234		  NVDEF(NV907D, HEAD_SET_PARAMS, SUPER_SAMPLE, X1_AA) |
    235		  NVDEF(NV907D, HEAD_SET_PARAMS, GAMMA, LINEAR),
    236
    237				HEAD_SET_CONTEXT_DMAS_ISO(i),
    238		  NVVAL(NV907D, HEAD_SET_CONTEXT_DMAS_ISO, HANDLE, asyh->core.handle));
    239
    240	PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_POINT_IN(i),
    241		  NVVAL(NV907D, HEAD_SET_VIEWPORT_POINT_IN, X, asyh->core.x) |
    242		  NVVAL(NV907D, HEAD_SET_VIEWPORT_POINT_IN, Y, asyh->core.y));
    243	return 0;
    244}
    245
    246int
    247head907d_olut_clr(struct nv50_head *head)
    248{
    249	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    250	const int i = head->base.index;
    251	int ret;
    252
    253	if ((ret = PUSH_WAIT(push, 4)))
    254		return ret;
    255
    256	PUSH_MTHD(push, NV907D, HEAD_SET_OUTPUT_LUT_LO(i),
    257		  NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, ENABLE, DISABLE));
    258
    259	PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_LUT(i), 0x00000000);
    260	return 0;
    261}
    262
    263int
    264head907d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
    265{
    266	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    267	const int i = head->base.index;
    268	int ret;
    269
    270	if ((ret = PUSH_WAIT(push, 5)))
    271		return ret;
    272
    273	PUSH_MTHD(push, NV907D, HEAD_SET_OUTPUT_LUT_LO(i),
    274		  NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, ENABLE, ENABLE) |
    275		  NVVAL(NV907D, HEAD_SET_OUTPUT_LUT_LO, MODE, asyh->olut.mode) |
    276		  NVDEF(NV907D, HEAD_SET_OUTPUT_LUT_LO, NEVER_YIELD_TO_BASE, DISABLE),
    277
    278				HEAD_SET_OUTPUT_LUT_HI(i),
    279		  NVVAL(NV907D, HEAD_SET_OUTPUT_LUT_HI, ORIGIN, asyh->olut.offset >> 8));
    280
    281	PUSH_MTHD(push, NV907D, HEAD_SET_CONTEXT_DMA_LUT(i), asyh->olut.handle);
    282	return 0;
    283}
    284
    285void
    286head907d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
    287{
    288	for (; size--; in++, mem += 8) {
    289		writew(drm_color_lut_extract(in->  red, 14) + 0x6000, mem + 0);
    290		writew(drm_color_lut_extract(in->green, 14) + 0x6000, mem + 2);
    291		writew(drm_color_lut_extract(in-> blue, 14) + 0x6000, mem + 4);
    292	}
    293
    294	/* INTERPOLATE modes require a "next" entry to interpolate with,
    295	 * so we replicate the last entry to deal with this for now.
    296	 */
    297	writew(readw(mem - 8), mem + 0);
    298	writew(readw(mem - 6), mem + 2);
    299	writew(readw(mem - 4), mem + 4);
    300}
    301
    302bool
    303head907d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
    304{
    305	if (size != 256 && size != 1024)
    306		return false;
    307
    308	if (size == 1024)
    309		asyh->olut.mode = NV907D_HEAD_SET_OUTPUT_LUT_LO_MODE_INTERPOLATE_1025_UNITY_RANGE;
    310	else
    311		asyh->olut.mode = NV907D_HEAD_SET_OUTPUT_LUT_LO_MODE_INTERPOLATE_257_UNITY_RANGE;
    312
    313	asyh->olut.load = head907d_olut_load;
    314	return true;
    315}
    316
    317bool head907d_ilut_check(int size)
    318{
    319	return size == 256 || size == 1024;
    320}
    321
    322int
    323head907d_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
    324{
    325	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    326	struct nv50_head_mode *m = &asyh->mode;
    327	const int i = head->base.index;
    328	int ret;
    329
    330	if ((ret = PUSH_WAIT(push, 13)))
    331		return ret;
    332
    333	PUSH_MTHD(push, NV907D, HEAD_SET_OVERSCAN_COLOR(i),
    334		  NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, RED, 0) |
    335		  NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, GRN, 0) |
    336		  NVVAL(NV907D, HEAD_SET_OVERSCAN_COLOR, BLU, 0),
    337
    338				HEAD_SET_RASTER_SIZE(i),
    339		  NVVAL(NV907D, HEAD_SET_RASTER_SIZE, WIDTH, m->h.active) |
    340		  NVVAL(NV907D, HEAD_SET_RASTER_SIZE, HEIGHT, m->v.active),
    341
    342				HEAD_SET_RASTER_SYNC_END(i),
    343		  NVVAL(NV907D, HEAD_SET_RASTER_SYNC_END, X, m->h.synce) |
    344		  NVVAL(NV907D, HEAD_SET_RASTER_SYNC_END, Y, m->v.synce),
    345
    346				HEAD_SET_RASTER_BLANK_END(i),
    347		  NVVAL(NV907D, HEAD_SET_RASTER_BLANK_END, X, m->h.blanke) |
    348		  NVVAL(NV907D, HEAD_SET_RASTER_BLANK_END, Y, m->v.blanke),
    349
    350				HEAD_SET_RASTER_BLANK_START(i),
    351		  NVVAL(NV907D, HEAD_SET_RASTER_BLANK_START, X, m->h.blanks) |
    352		  NVVAL(NV907D, HEAD_SET_RASTER_BLANK_START, Y, m->v.blanks),
    353
    354				HEAD_SET_RASTER_VERT_BLANK2(i),
    355		  NVVAL(NV907D, HEAD_SET_RASTER_VERT_BLANK2, YSTART, m->v.blank2s) |
    356		  NVVAL(NV907D, HEAD_SET_RASTER_VERT_BLANK2, YEND, m->v.blank2e));
    357
    358	PUSH_MTHD(push, NV907D, HEAD_SET_DEFAULT_BASE_COLOR(i),
    359		  NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, RED, 0) |
    360		  NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, GREEN, 0) |
    361		  NVVAL(NV907D, HEAD_SET_DEFAULT_BASE_COLOR, BLUE, 0));
    362
    363	PUSH_MTHD(push, NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY(i),
    364		  NVVAL(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, HERTZ, m->clock * 1000) |
    365		  NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY, ADJ1000DIV1001, FALSE),
    366
    367				HEAD_SET_PIXEL_CLOCK_CONFIGURATION(i),
    368		  NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, MODE, CLK_CUSTOM) |
    369		  NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, NOT_DRIVER, FALSE) |
    370		  NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_CONFIGURATION, ENABLE_HOPPING, FALSE),
    371
    372				HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX(i),
    373		  NVVAL(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, HERTZ, m->clock * 1000) |
    374		  NVDEF(NV907D, HEAD_SET_PIXEL_CLOCK_FREQUENCY_MAX, ADJ1000DIV1001, FALSE));
    375	return 0;
    376}
    377
    378int
    379head907d_view(struct nv50_head *head, struct nv50_head_atom *asyh)
    380{
    381	struct nvif_push *push = nv50_disp(head->base.base.dev)->core->chan.push;
    382	const int i = head->base.index;
    383	int ret;
    384
    385	if ((ret = PUSH_WAIT(push, 8)))
    386		return ret;
    387
    388	PUSH_MTHD(push, NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER(i),
    389		  NVDEF(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, VERTICAL_TAPS, TAPS_1) |
    390		  NVDEF(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, HORIZONTAL_TAPS, TAPS_1) |
    391		  NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, HRESPONSE_BIAS, 0) |
    392		  NVVAL(NV907D, HEAD_SET_CONTROL_OUTPUT_SCALER, VRESPONSE_BIAS, 0));
    393
    394	PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_SIZE_IN(i),
    395		  NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_IN, WIDTH, asyh->view.iW) |
    396		  NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_IN, HEIGHT, asyh->view.iH));
    397
    398	PUSH_MTHD(push, NV907D, HEAD_SET_VIEWPORT_SIZE_OUT(i),
    399		  NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT, WIDTH, asyh->view.oW) |
    400		  NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT, HEIGHT, asyh->view.oH),
    401
    402				HEAD_SET_VIEWPORT_SIZE_OUT_MIN(i),
    403		  NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, WIDTH, asyh->view.oW) |
    404		  NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MIN, HEIGHT, asyh->view.oH),
    405
    406				HEAD_SET_VIEWPORT_SIZE_OUT_MAX(i),
    407		  NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MAX, WIDTH, asyh->view.oW) |
    408		  NVVAL(NV907D, HEAD_SET_VIEWPORT_SIZE_OUT_MAX, HEIGHT, asyh->view.oH));
    409	return 0;
    410}
    411
    412const struct nv50_head_func
    413head907d = {
    414	.view = head907d_view,
    415	.mode = head907d_mode,
    416	.olut = head907d_olut,
    417	.ilut_check = head907d_ilut_check,
    418	.olut_size = 1024,
    419	.olut_set = head907d_olut_set,
    420	.olut_clr = head907d_olut_clr,
    421	.core_calc = head507d_core_calc,
    422	.core_set = head907d_core_set,
    423	.core_clr = head907d_core_clr,
    424	.curs_layout = head507d_curs_layout,
    425	.curs_format = head507d_curs_format,
    426	.curs_set = head907d_curs_set,
    427	.curs_clr = head907d_curs_clr,
    428	.base = head907d_base,
    429	.ovly = head907d_ovly,
    430	.dither = head907d_dither,
    431	.procamp = head907d_procamp,
    432	.or = head907d_or,
    433};