1 1.14 thorpej /* $NetBSD: ibm561.c,v 1.14 2020/12/04 00:38:08 thorpej Exp $ */ 2 1.1 elric 3 1.1 elric /*- 4 1.1 elric * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 1.1 elric * All rights reserved. 6 1.1 elric * 7 1.1 elric * This code is derived from software contributed to The NetBSD Foundation 8 1.1 elric * by Roland C. Dowdeswell of Ponte, Inc. 9 1.1 elric * 10 1.1 elric * Redistribution and use in source and binary forms, with or without 11 1.1 elric * modification, are permitted provided that the following conditions 12 1.1 elric * are met: 13 1.1 elric * 1. Redistributions of source code must retain the above copyright 14 1.1 elric * notice, this list of conditions and the following disclaimer. 15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 elric * notice, this list of conditions and the following disclaimer in the 17 1.1 elric * documentation and/or other materials provided with the distribution. 18 1.1 elric * 19 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 elric * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 elric * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 elric * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 elric * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 elric * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 elric * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 elric * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 elric * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 elric * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 elric * POSSIBILITY OF SUCH DAMAGE. 30 1.1 elric */ 31 1.4 lukem 32 1.4 lukem #include <sys/cdefs.h> 33 1.14 thorpej __KERNEL_RCSID(0, "$NetBSD: ibm561.c,v 1.14 2020/12/04 00:38:08 thorpej Exp $"); 34 1.1 elric 35 1.1 elric #include <sys/param.h> 36 1.1 elric #include <sys/systm.h> 37 1.1 elric #include <sys/device.h> 38 1.1 elric #include <sys/buf.h> 39 1.1 elric #include <sys/kernel.h> 40 1.14 thorpej #include <sys/kmem.h> 41 1.1 elric 42 1.1 elric #include <dev/pci/pcivar.h> 43 1.1 elric #include <dev/ic/ibm561reg.h> 44 1.1 elric #include <dev/ic/ibm561var.h> 45 1.1 elric #include <dev/ic/ramdac.h> 46 1.1 elric 47 1.1 elric #include <dev/wscons/wsconsio.h> 48 1.1 elric 49 1.1 elric /* 50 1.1 elric * Functions exported via the RAMDAC configuration table. 51 1.1 elric */ 52 1.6 perry void ibm561_init(struct ramdac_cookie *); 53 1.6 perry int ibm561_set_cmap(struct ramdac_cookie *, struct wsdisplay_cmap *); 54 1.6 perry int ibm561_get_cmap(struct ramdac_cookie *, struct wsdisplay_cmap *); 55 1.6 perry int ibm561_set_cursor(struct ramdac_cookie *, struct wsdisplay_cursor *); 56 1.6 perry int ibm561_get_cursor(struct ramdac_cookie *, struct wsdisplay_cursor *); 57 1.6 perry int ibm561_set_curpos(struct ramdac_cookie *, struct wsdisplay_curpos *); 58 1.6 perry int ibm561_get_curpos(struct ramdac_cookie *, struct wsdisplay_curpos *); 59 1.6 perry int ibm561_get_curmax(struct ramdac_cookie *, struct wsdisplay_curpos *); 60 1.6 perry int ibm561_set_dotclock(struct ramdac_cookie *, unsigned); 61 1.1 elric 62 1.1 elric /* XXX const */ 63 1.1 elric struct ramdac_funcs ibm561_funcsstruct = { 64 1.1 elric "IBM561", 65 1.1 elric ibm561_register, 66 1.1 elric ibm561_init, 67 1.1 elric ibm561_set_cmap, 68 1.1 elric ibm561_get_cmap, 69 1.1 elric ibm561_set_cursor, 70 1.1 elric ibm561_get_cursor, 71 1.1 elric ibm561_set_curpos, 72 1.1 elric ibm561_get_curpos, 73 1.1 elric ibm561_get_curmax, 74 1.1 elric NULL, /* check_curcmap; not needed */ 75 1.1 elric NULL, /* set_curcmap; not needed */ 76 1.1 elric NULL, /* get_curcmap; not needed */ 77 1.1 elric ibm561_set_dotclock, 78 1.1 elric }; 79 1.1 elric 80 1.1 elric /* 81 1.1 elric * Private data. 82 1.1 elric */ 83 1.1 elric struct ibm561data { 84 1.1 elric void *cookie; 85 1.1 elric 86 1.6 perry int (*ramdac_sched_update)(void *, void (*)(void *)); 87 1.6 perry void (*ramdac_wr)(void *, u_int, u_int8_t); 88 1.6 perry u_int8_t (*ramdac_rd)(void *, u_int); 89 1.1 elric 90 1.1 elric #define CHANGED_CURCMAP 0x0001 /* cursor cmap */ 91 1.1 elric #define CHANGED_CMAP 0x0002 /* color map */ 92 1.1 elric #define CHANGED_WTYPE 0x0004 /* window types */ 93 1.1 elric #define CHANGED_DOTCLOCK 0x0008 /* dot clock */ 94 1.1 elric #define CHANGED_ALL 0x000f /* or of all above */ 95 1.1 elric u_int8_t changed; 96 1.1 elric 97 1.1 elric /* dotclock parameters */ 98 1.1 elric u_int8_t vco_div; 99 1.1 elric u_int8_t pll_ref; 100 1.1 elric u_int8_t div_dotclock; 101 1.1 elric 102 1.1 elric /* colormaps et al. */ 103 1.1 elric u_int8_t curcmap_r[2]; 104 1.1 elric u_int8_t curcmap_g[2]; 105 1.1 elric u_int8_t curcmap_b[2]; 106 1.1 elric 107 1.1 elric u_int8_t cmap_r[IBM561_NCMAP_ENTRIES]; 108 1.1 elric u_int8_t cmap_g[IBM561_NCMAP_ENTRIES]; 109 1.1 elric u_int8_t cmap_b[IBM561_NCMAP_ENTRIES]; 110 1.1 elric 111 1.1 elric u_int16_t gamma_r[IBM561_NGAMMA_ENTRIES]; 112 1.1 elric u_int16_t gamma_g[IBM561_NGAMMA_ENTRIES]; 113 1.1 elric u_int16_t gamma_b[IBM561_NGAMMA_ENTRIES]; 114 1.1 elric 115 1.1 elric u_int16_t wtype[IBM561_NWTYPES]; 116 1.1 elric }; 117 1.1 elric 118 1.1 elric /* 119 1.1 elric * private functions 120 1.1 elric */ 121 1.6 perry void ibm561_update(void *); 122 1.1 elric static void ibm561_load_cmap(struct ibm561data *); 123 1.1 elric static void ibm561_load_dotclock(struct ibm561data *); 124 1.1 elric static void ibm561_regbegin(struct ibm561data *, u_int16_t); 125 1.1 elric static void ibm561_regcont(struct ibm561data *, u_int16_t, u_int8_t); 126 1.1 elric static void ibm561_regcont10bit(struct ibm561data *, u_int16_t, u_int16_t); 127 1.1 elric static void ibm561_regwr(struct ibm561data *, u_int16_t, u_int8_t); 128 1.1 elric 129 1.1 elric struct ramdac_funcs * 130 1.1 elric ibm561_funcs(void) 131 1.1 elric { 132 1.1 elric return &ibm561_funcsstruct; 133 1.1 elric } 134 1.1 elric 135 1.1 elric struct ramdac_cookie * 136 1.11 matt ibm561_register( 137 1.11 matt void *v, 138 1.11 matt int (*sched_update)(void *, void (*)(void *)), 139 1.11 matt void (*wr)(void *, u_int, u_int8_t), 140 1.11 matt u_int8_t (*rd)(void *, u_int)) 141 1.1 elric { 142 1.1 elric struct ibm561data *data; 143 1.1 elric 144 1.14 thorpej data = kmem_zalloc(sizeof *data, KM_SLEEP); 145 1.1 elric data->cookie = v; 146 1.1 elric data->ramdac_sched_update = sched_update; 147 1.1 elric data->ramdac_wr = wr; 148 1.1 elric data->ramdac_rd = rd; 149 1.1 elric return (struct ramdac_cookie *)data; 150 1.1 elric } 151 1.1 elric 152 1.1 elric /* 153 1.1 elric * This function exists solely to provide a means to init 154 1.1 elric * the RAMDAC without first registering. It is useful for 155 1.1 elric * initializing the console early on. 156 1.1 elric */ 157 1.1 elric 158 1.12 jdolecek static struct ibm561data saved_console_data; 159 1.1 elric 160 1.1 elric void 161 1.11 matt ibm561_cninit( 162 1.11 matt void *v, 163 1.11 matt int (*sched_update)(void *, void (*)(void *)), 164 1.11 matt void (*wr)(void *, u_int, u_int8_t), 165 1.11 matt u_int8_t (*rd)(void *, u_int), 166 1.11 matt u_int dotclock) 167 1.1 elric { 168 1.13 jdolecek struct ibm561data *data = &saved_console_data; 169 1.1 elric memset(data, 0x0, sizeof *data); 170 1.1 elric data->cookie = v; 171 1.1 elric data->ramdac_sched_update = sched_update; 172 1.1 elric data->ramdac_wr = wr; 173 1.1 elric data->ramdac_rd = rd; 174 1.1 elric ibm561_set_dotclock((struct ramdac_cookie *)data, dotclock); 175 1.1 elric ibm561_init((struct ramdac_cookie *)data); 176 1.1 elric } 177 1.1 elric 178 1.1 elric void 179 1.9 dsl ibm561_init(struct ramdac_cookie *rc) 180 1.1 elric { 181 1.1 elric struct ibm561data *data = (struct ibm561data *)rc; 182 1.1 elric int i; 183 1.1 elric 184 1.1 elric /* XXX this is _essential_ */ 185 1.1 elric 186 1.1 elric ibm561_load_dotclock(data); 187 1.1 elric 188 1.1 elric /* XXXrcd: bunch of magic of which I have no current clue */ 189 1.1 elric ibm561_regwr(data, IBM561_CONFIG_REG1, 0x2a); 190 1.1 elric ibm561_regwr(data, IBM561_CONFIG_REG3, 0x41); 191 1.1 elric ibm561_regwr(data, IBM561_CONFIG_REG4, 0x20); 192 1.1 elric 193 1.1 elric /* initialize the card a bit */ 194 1.1 elric ibm561_regwr(data, IBM561_SYNC_CNTL, 0x1); 195 1.1 elric ibm561_regwr(data, IBM561_CONFIG_REG2, 0x19); 196 1.1 elric 197 1.1 elric ibm561_regwr(data, IBM561_CONFIG_REG1, 0x2a); 198 1.1 elric ibm561_regwr(data, IBM561_CONFIG_REG4, 0x20); 199 1.1 elric 200 1.1 elric ibm561_regbegin(data, IBM561_WAT_SEG_REG); 201 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 202 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 203 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 204 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 205 1.1 elric ibm561_regbegin(data, IBM561_CHROMAKEY0); 206 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 207 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 208 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 209 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 210 1.1 elric 211 1.1 elric ibm561_regwr(data, IBM561_CURS_CNTL_REG, 0x00); /* XXX off? */ 212 1.1 elric 213 1.1 elric /* cursor `hot spot' registers */ 214 1.1 elric ibm561_regbegin(data, IBM561_HOTSPOT_REG); 215 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 216 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 217 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 218 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 219 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 220 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x00); 221 1.1 elric 222 1.1 elric /* VRAM Mask Registers (diagnostics) */ 223 1.1 elric ibm561_regbegin(data, IBM561_VRAM_MASK_REG); 224 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 225 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 226 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 227 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 228 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 229 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 230 1.1 elric ibm561_regcont(data, IBM561_CMD, 0xff); 231 1.1 elric 232 1.1 elric /* let's set up some decent default colour maps and gammas */ 233 1.1 elric for (i=0; i < IBM561_NCMAP_ENTRIES; i++) 234 1.1 elric data->cmap_r[i] = data->cmap_g[i] = data->cmap_b[i] = 0xff; 235 1.1 elric data->cmap_r[0] = data->cmap_g[0] = data->cmap_b[0] = 0x00; 236 1.1 elric data->cmap_r[256] = data->cmap_g[256] = data->cmap_b[256] = 0x00; 237 1.1 elric data->cmap_r[512] = data->cmap_g[512] = data->cmap_b[512] = 0x00; 238 1.1 elric data->cmap_r[768] = data->cmap_g[768] = data->cmap_b[768] = 0x00; 239 1.1 elric 240 1.1 elric data->gamma_r[0] = data->gamma_g[0] = data->gamma_b[0] = 0x00; 241 1.1 elric for (i=0; i < IBM561_NGAMMA_ENTRIES; i++) 242 1.1 elric data->gamma_r[i] = data->gamma_g[i] = data->gamma_b[i] = 0xff; 243 1.1 elric 244 1.1 elric for (i=0; i < IBM561_NWTYPES; i++) 245 1.1 elric data->wtype[i] = 0x0036; 246 1.1 elric data->wtype[1] = 0x0028; 247 1.1 elric 248 1.1 elric /* the last step: */ 249 1.1 elric data->changed = CHANGED_ALL; 250 1.1 elric data->ramdac_sched_update(data->cookie, ibm561_update); 251 1.1 elric } 252 1.1 elric 253 1.1 elric int 254 1.9 dsl ibm561_set_cmap(struct ramdac_cookie *rc, struct wsdisplay_cmap *cmapp) 255 1.1 elric { 256 1.1 elric struct ibm561data *data = (struct ibm561data *)rc; 257 1.3 itojun u_int count, index; 258 1.14 thorpej uint8_t *cmap_entries, *r, *g, *b; 259 1.5 chs int s, error; 260 1.1 elric 261 1.3 itojun if (cmapp->index >= IBM561_NCMAP_ENTRIES || 262 1.3 itojun cmapp->count > IBM561_NCMAP_ENTRIES - cmapp->index) 263 1.1 elric return (EINVAL); 264 1.1 elric 265 1.14 thorpej cmap_entries = kmem_alloc(IBM561_NCMAP_ENTRIES * 3, KM_SLEEP); 266 1.14 thorpej r = &cmap_entries[0 * IBM561_NCMAP_ENTRIES]; 267 1.14 thorpej g = &cmap_entries[1 * IBM561_NCMAP_ENTRIES]; 268 1.14 thorpej b = &cmap_entries[2 * IBM561_NCMAP_ENTRIES]; 269 1.14 thorpej 270 1.1 elric index = cmapp->index; 271 1.1 elric count = cmapp->count; 272 1.5 chs error = copyin(cmapp->red, &r[index], count); 273 1.5 chs if (error) 274 1.14 thorpej goto out; 275 1.5 chs error = copyin(cmapp->green, &g[index], count); 276 1.5 chs if (error) 277 1.14 thorpej goto out; 278 1.5 chs error = copyin(cmapp->blue, &b[index], count); 279 1.5 chs if (error) 280 1.14 thorpej goto out; 281 1.14 thorpej 282 1.5 chs s = spltty(); 283 1.5 chs memcpy(&data->cmap_r[index], &r[index], count); 284 1.5 chs memcpy(&data->cmap_g[index], &g[index], count); 285 1.5 chs memcpy(&data->cmap_b[index], &b[index], count); 286 1.1 elric data->changed |= CHANGED_CMAP; 287 1.1 elric data->ramdac_sched_update(data->cookie, ibm561_update); 288 1.1 elric splx(s); 289 1.14 thorpej 290 1.14 thorpej out: 291 1.14 thorpej kmem_free(cmap_entries, IBM561_NCMAP_ENTRIES * 3); 292 1.14 thorpej return (error); 293 1.1 elric } 294 1.1 elric 295 1.1 elric int 296 1.9 dsl ibm561_get_cmap(struct ramdac_cookie *rc, struct wsdisplay_cmap *cmapp) 297 1.1 elric { 298 1.1 elric struct ibm561data *data = (struct ibm561data *)rc; 299 1.3 itojun u_int count, index; 300 1.1 elric int error; 301 1.1 elric 302 1.3 itojun if (cmapp->index >= IBM561_NCMAP_ENTRIES || 303 1.3 itojun cmapp->count > IBM561_NCMAP_ENTRIES - cmapp->index) 304 1.1 elric return (EINVAL); 305 1.1 elric count = cmapp->count; 306 1.1 elric index = cmapp->index; 307 1.1 elric error = copyout(&data->cmap_r[index], cmapp->red, count); 308 1.1 elric if (error) 309 1.1 elric return (error); 310 1.1 elric error = copyout(&data->cmap_g[index], cmapp->green, count); 311 1.1 elric if (error) 312 1.1 elric return (error); 313 1.1 elric error = copyout(&data->cmap_b[index], cmapp->blue, count); 314 1.1 elric return (error); 315 1.1 elric } 316 1.1 elric 317 1.1 elric /* 318 1.1 elric * XXX: 319 1.1 elric * I am leaving these functions returning EINVAL, as they are 320 1.1 elric * not strictly necessary for the correct functioning of the 321 1.1 elric * card and in fact are not used on the other TGA variants, except 322 1.1 elric * they are exported via ioctl(2) to userland, which does not in 323 1.1 elric * fact use them. 324 1.1 elric */ 325 1.1 elric 326 1.1 elric int 327 1.9 dsl ibm561_set_cursor(struct ramdac_cookie *rc, struct wsdisplay_cursor *cursorp) 328 1.1 elric { 329 1.1 elric return EINVAL; 330 1.1 elric } 331 1.1 elric 332 1.1 elric int 333 1.9 dsl ibm561_get_cursor(struct ramdac_cookie *rc, struct wsdisplay_cursor *cursorp) 334 1.1 elric { 335 1.1 elric return EINVAL; 336 1.1 elric } 337 1.1 elric 338 1.1 elric int 339 1.9 dsl ibm561_set_curpos(struct ramdac_cookie *rc, struct wsdisplay_curpos *curposp) 340 1.1 elric { 341 1.1 elric return EINVAL; 342 1.1 elric } 343 1.1 elric 344 1.1 elric int 345 1.9 dsl ibm561_get_curpos(struct ramdac_cookie *rc, struct wsdisplay_curpos *curposp) 346 1.1 elric { 347 1.1 elric return EINVAL; 348 1.1 elric } 349 1.1 elric 350 1.1 elric int 351 1.9 dsl ibm561_get_curmax(struct ramdac_cookie *rc, struct wsdisplay_curpos *curposp) 352 1.1 elric { 353 1.1 elric return EINVAL; 354 1.1 elric } 355 1.1 elric 356 1.1 elric int 357 1.9 dsl ibm561_set_dotclock(struct ramdac_cookie *rc, unsigned dotclock) 358 1.1 elric { 359 1.1 elric struct ibm561data *data = (struct ibm561data *)rc; 360 1.1 elric 361 1.1 elric /* XXXrcd: a couple of these are a little hazy, vis a vis 362 1.1 elric * check 175MHz and 202MHz, which are wrong... 363 1.1 elric */ 364 1.1 elric switch (dotclock) { 365 1.1 elric case 25175000: data->vco_div = 0x3e; data->pll_ref = 0x09; break; 366 1.1 elric case 31500000: data->vco_div = 0x17; data->pll_ref = 0x05; break; 367 1.1 elric case 40000000: data->vco_div = 0x42; data->pll_ref = 0x06; break; 368 1.1 elric case 50000000: data->vco_div = 0x45; data->pll_ref = 0x05; break; 369 1.1 elric case 65000000: data->vco_div = 0xac; data->pll_ref = 0x0c; break; 370 1.1 elric case 69000000: data->vco_div = 0xa9; data->pll_ref = 0x0b; break; 371 1.1 elric case 74000000: data->vco_div = 0x9c; data->pll_ref = 0x09; break; 372 1.1 elric case 75000000: data->vco_div = 0x93; data->pll_ref = 0x08; break; 373 1.1 elric case 103994000: data->vco_div = 0x96; data->pll_ref = 0x06; break; 374 1.1 elric case 108180000: data->vco_div = 0xb8; data->pll_ref = 0x08; break; 375 1.1 elric case 110000000: data->vco_div = 0xba; data->pll_ref = 0x08; break; 376 1.1 elric case 119840000: data->vco_div = 0x82; data->pll_ref = 0x04; break; 377 1.1 elric case 130808000: data->vco_div = 0xc8; data->pll_ref = 0x08; break; 378 1.1 elric case 135000000: data->vco_div = 0xc1; data->pll_ref = 0x07; break; 379 1.1 elric case 175000000: data->vco_div = 0xe2; data->pll_ref = 0x07; break; 380 1.1 elric case 202500000: data->vco_div = 0xe2; data->pll_ref = 0x07; break; 381 1.1 elric default: 382 1.1 elric return EINVAL; 383 1.1 elric } 384 1.1 elric 385 1.1 elric data->div_dotclock = 0xb0; 386 1.1 elric data->changed |= CHANGED_DOTCLOCK; 387 1.1 elric return 0; 388 1.1 elric } 389 1.1 elric 390 1.1 elric /* 391 1.1 elric * Internal Functions 392 1.1 elric */ 393 1.1 elric 394 1.1 elric void 395 1.9 dsl ibm561_update(void *vp) 396 1.1 elric { 397 1.1 elric struct ibm561data *data = (struct ibm561data *)vp; 398 1.1 elric int i; 399 1.1 elric 400 1.1 elric /* XXX see comment above ibm561_cninit() */ 401 1.1 elric if (!data) 402 1.12 jdolecek data = &saved_console_data; 403 1.1 elric 404 1.1 elric if (data->changed & CHANGED_WTYPE) { 405 1.1 elric ibm561_regbegin(data, IBM561_FB_WINTYPE); 406 1.1 elric for (i=0; i < IBM561_NWTYPES; i++) 407 1.1 elric ibm561_regcont10bit(data, IBM561_CMD_FB_WAT, data->wtype[i]); 408 1.1 elric 409 1.1 elric /* XXXrcd: quick hack here for AUX FB table */ 410 1.1 elric ibm561_regbegin(data, IBM561_AUXFB_WINTYPE); 411 1.1 elric for (i=0; i < IBM561_NWTYPES; i++) 412 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x04); 413 1.1 elric 414 1.1 elric /* XXXrcd: quick hack here for OL WAT table */ 415 1.1 elric ibm561_regbegin(data, IBM561_OL_WINTYPE); 416 1.1 elric for (i=0; i < IBM561_NWTYPES; i++) 417 1.1 elric ibm561_regcont10bit(data, IBM561_CMD_FB_WAT, 0x0231); 418 1.1 elric 419 1.1 elric /* XXXrcd: quick hack here for AUX OL WAT table */ 420 1.1 elric ibm561_regbegin(data, IBM561_AUXOL_WINTYPE); 421 1.1 elric for (i=0; i < IBM561_NWTYPES; i++) 422 1.1 elric ibm561_regcont(data, IBM561_CMD, 0x0c); 423 1.1 elric } 424 1.1 elric 425 1.1 elric if (data->changed & CHANGED_CMAP) 426 1.1 elric ibm561_load_cmap(data); 427 1.1 elric 428 1.1 elric /* XXX: I am not sure in what situations it is safe to 429 1.1 elric * change the dotclock---hope this is good. 430 1.1 elric */ 431 1.1 elric if (data->changed & CHANGED_DOTCLOCK) 432 1.1 elric ibm561_load_dotclock(data); 433 1.1 elric } 434 1.1 elric 435 1.1 elric static void 436 1.1 elric ibm561_load_cmap(struct ibm561data *data) 437 1.1 elric { 438 1.1 elric int i; 439 1.1 elric 440 1.1 elric ibm561_regbegin(data, IBM561_CMAP_TABLE); 441 1.1 elric for (i=0; i < IBM561_NCMAP_ENTRIES; i++) { 442 1.1 elric ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_r[i]); 443 1.1 elric ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_g[i]); 444 1.1 elric ibm561_regcont(data, IBM561_CMD_CMAP, data->cmap_b[i]); 445 1.1 elric } 446 1.1 elric 447 1.1 elric ibm561_regbegin(data, IBM561_RED_GAMMA_TABLE); 448 1.1 elric for (i=0; i < 256; i++) 449 1.1 elric ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_r[i]); 450 1.1 elric 451 1.1 elric ibm561_regbegin(data, IBM561_GREEN_GAMMA_TABLE); 452 1.1 elric for (i=1; i < 256; i++) 453 1.1 elric ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_g[i]); 454 1.1 elric 455 1.1 elric ibm561_regbegin(data, IBM561_BLUE_GAMMA_TABLE); 456 1.1 elric for (i=1; i < 256; i++) 457 1.1 elric ibm561_regcont10bit(data, IBM561_CMD_GAMMA, data->gamma_b[i]); 458 1.1 elric 459 1.1 elric } 460 1.1 elric 461 1.1 elric static void 462 1.1 elric ibm561_load_dotclock(struct ibm561data *data) 463 1.1 elric { 464 1.1 elric /* XXX 465 1.1 elric * we should probably be more pro-active here, but it shouldn't 466 1.1 elric * actually happen... 467 1.1 elric */ 468 1.1 elric if (!data->vco_div || !data->pll_ref || ! data->div_dotclock) { 469 1.1 elric panic("ibm561_load_dotclock: called uninitialized"); 470 1.1 elric } 471 1.1 elric 472 1.1 elric ibm561_regwr(data, IBM561_PLL_VCO_DIV, data->vco_div); 473 1.1 elric ibm561_regwr(data, IBM561_PLL_REF_REG, data->pll_ref); 474 1.1 elric ibm561_regwr(data, IBM561_DIV_DOTCLCK, data->div_dotclock); 475 1.1 elric } 476 1.1 elric 477 1.1 elric static void 478 1.1 elric ibm561_regcont10bit(struct ibm561data *data, u_int16_t reg, u_int16_t val) 479 1.1 elric { 480 1.1 elric data->ramdac_wr(data->cookie, IBM561_CMD_GAMMA, (val >> 2) & 0xff); 481 1.1 elric data->ramdac_wr(data->cookie, IBM561_CMD_GAMMA, (val & 0x3) << 6); 482 1.1 elric } 483 1.1 elric 484 1.1 elric static void 485 1.1 elric ibm561_regbegin(struct ibm561data *data, u_int16_t reg) 486 1.1 elric { 487 1.1 elric data->ramdac_wr(data->cookie, IBM561_ADDR_LOW, reg & 0xff); 488 1.1 elric data->ramdac_wr(data->cookie, IBM561_ADDR_HIGH, (reg >> 8) & 0xff); 489 1.1 elric } 490 1.1 elric 491 1.1 elric static void 492 1.1 elric ibm561_regcont(struct ibm561data *data, u_int16_t reg, u_int8_t val) 493 1.1 elric { 494 1.1 elric data->ramdac_wr(data->cookie, reg, val); 495 1.1 elric } 496 1.1 elric 497 1.1 elric static void 498 1.1 elric ibm561_regwr(struct ibm561data *data, u_int16_t reg, u_int8_t val) 499 1.1 elric { 500 1.1 elric ibm561_regbegin(data, reg); 501 1.1 elric ibm561_regcont(data, IBM561_CMD, val); 502 1.1 elric } 503