igsfb_subr.c revision 1.1
1/* $NetBSD: igsfb_subr.c,v 1.1 2002/09/24 18:17:25 uwe Exp $ */ 2 3/* 4 * Copyright (c) 2002 Valeriy E. Ushakov 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30/* 31 * Integraphics Systems IGA 168x and CyberPro series. 32 */ 33#include <sys/cdefs.h> 34__KERNEL_RCSID(0, "$NetBSD: igsfb_subr.c,v 1.1 2002/09/24 18:17:25 uwe Exp $"); 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/kernel.h> 39#include <sys/device.h> 40 41#include <machine/bus.h> 42 43#include <dev/wscons/wsconsio.h> 44 45#include <dev/ic/igsfbreg.h> 46#include <dev/ic/igsfbvar.h> 47 48 49static void igsfb_init_seq(struct igsfb_softc *); 50static void igsfb_init_crtc(struct igsfb_softc *); 51static void igsfb_init_grfx(struct igsfb_softc *); 52static void igsfb_init_attr(struct igsfb_softc *); 53static void igsfb_init_ext(struct igsfb_softc *); 54static void igsfb_init_dac(struct igsfb_softc *); 55 56static void igsfb_freq_latch(struct igsfb_softc *); 57static void igsfb_video_on(struct igsfb_softc *); 58 59 60 61/* 62 * Enable chip. 63 */ 64int 65igsfb_enable(iot) 66 bus_space_tag_t iot; 67{ 68 bus_space_handle_t vdoh; 69 bus_space_handle_t vseh; 70 bus_space_handle_t regh; 71 int ret; 72 73 ret = bus_space_map(iot, IGS_VDO, 1, 0, &vdoh); 74 if (ret != 0) { 75 printf("unable to map VDO register\n"); 76 goto out0; 77 } 78 79 ret = bus_space_map(iot, IGS_VSE, 1, 0, &vseh); 80 if (ret != 0) { 81 printf("unable to map VSE register\n"); 82 goto out1; 83 } 84 85 ret = bus_space_map(iot, IGS_REG_BASE, IGS_REG_SIZE, 0, ®h); 86 if (ret != 0) { 87 printf("unable to map I/O registers\n"); 88 goto out2; 89 } 90 91 /* 92 * Start decoding i/o space accesses. 93 */ 94 bus_space_write_1(iot, vdoh, 0, IGS_VDO_ENABLE | IGS_VDO_SETUP); 95 bus_space_write_1(iot, vseh, 0, IGS_VSE_ENABLE); 96 bus_space_write_1(iot, vdoh, 0, IGS_VDO_ENABLE); 97 98 /* 99 * Start decoding memory space accesses (XXX: move out of here? 100 * we program this register in igsfb_init_ext). 101 * While here, enable coprocessor and select IGS_COP_BASE_B. 102 */ 103 igs_ext_write(iot, regh, IGS_EXT_BIU_MISC_CTL, 104 (IGS_EXT_BIU_LINEAREN 105 | IGS_EXT_BIU_COPREN | IGS_EXT_BIU_COPASELB)); 106 107 bus_space_unmap(iot, regh, IGS_REG_SIZE); 108 out2: bus_space_unmap(iot, vseh, 1); 109 out1: bus_space_unmap(iot, vdoh, 1); 110 out0: return (ret); 111} 112 113 114/* 115 * Init sequencer. 116 * This is common for all video modes. 117 */ 118static void 119igsfb_init_seq(sc) 120 struct igsfb_softc *sc; 121{ 122 bus_space_tag_t iot = sc->sc_iot; 123 bus_space_handle_t ioh = sc->sc_ioh; 124 125 /* start messing with sequencer */ 126 igs_seq_write(iot, ioh, IGS_SEQ_RESET, 0); 127 128 igs_seq_write(iot, ioh, 1, 0x01); /* 8 dot clock */ 129 igs_seq_write(iot, ioh, 2, 0x0f); /* enable all maps */ 130 igs_seq_write(iot, ioh, 3, 0x00); /* character generator */ 131 igs_seq_write(iot, ioh, 4, 0x0e); /* memory mode */ 132 133 /* this selects color mode among other things */ 134 bus_space_write_1(iot, ioh, IGS_MISC_OUTPUT_W, 0xef); 135 136 /* normal sequencer operation */ 137 igs_seq_write(iot, ioh, IGS_SEQ_RESET, 138 IGS_SEQ_RESET_SYNC | IGS_SEQ_RESET_ASYNC); 139} 140 141/* 142 * Init CRTC to 640x480 8bpp at 60Hz 143 */ 144static void 145igsfb_init_crtc(sc) 146 struct igsfb_softc *sc; 147{ 148 bus_space_tag_t iot = sc->sc_iot; 149 bus_space_handle_t ioh = sc->sc_ioh; 150 151 igs_crtc_write(iot, ioh, 0x00, 0x5f); 152 igs_crtc_write(iot, ioh, 0x01, 0x4f); 153 igs_crtc_write(iot, ioh, 0x02, 0x50); 154 igs_crtc_write(iot, ioh, 0x03, 0x80); 155 igs_crtc_write(iot, ioh, 0x04, 0x52); 156 igs_crtc_write(iot, ioh, 0x05, 0x9d); 157 igs_crtc_write(iot, ioh, 0x06, 0x0b); 158 igs_crtc_write(iot, ioh, 0x07, 0x3e); 159 160 /* next block is almost constant, only bit 6 in reg 9 differs */ 161 igs_crtc_write(iot, ioh, 0x08, 0x00); 162 igs_crtc_write(iot, ioh, 0x09, 0x40); /* <- either 0x40 or 0x60 */ 163 igs_crtc_write(iot, ioh, 0x0a, 0x00); 164 igs_crtc_write(iot, ioh, 0x0b, 0x00); 165 igs_crtc_write(iot, ioh, 0x0c, 0x00); 166 igs_crtc_write(iot, ioh, 0x0d, 0x00); 167 igs_crtc_write(iot, ioh, 0x0e, 0x00); 168 igs_crtc_write(iot, ioh, 0x0f, 0x00); 169 170 igs_crtc_write(iot, ioh, 0x10, 0xe9); 171 igs_crtc_write(iot, ioh, 0x11, 0x8b); 172 igs_crtc_write(iot, ioh, 0x12, 0xdf); 173 igs_crtc_write(iot, ioh, 0x13, 0x50); 174 igs_crtc_write(iot, ioh, 0x14, 0x00); 175 igs_crtc_write(iot, ioh, 0x15, 0xe6); 176 igs_crtc_write(iot, ioh, 0x16, 0x04); 177 igs_crtc_write(iot, ioh, 0x17, 0xc3); 178 179 igs_crtc_write(iot, ioh, 0x18, 0xff); 180} 181 182 183/* 184 * Init graphics controller. 185 * This is common for all video modes. 186 */ 187static void 188igsfb_init_grfx(sc) 189 struct igsfb_softc *sc; 190{ 191 bus_space_tag_t iot = sc->sc_iot; 192 bus_space_handle_t ioh = sc->sc_ioh; 193 194 igs_grfx_write(iot, ioh, 0, 0x00); 195 igs_grfx_write(iot, ioh, 1, 0x00); 196 igs_grfx_write(iot, ioh, 2, 0x00); 197 igs_grfx_write(iot, ioh, 3, 0x00); 198 igs_grfx_write(iot, ioh, 4, 0x00); 199 igs_grfx_write(iot, ioh, 5, 0x60); /* SRMODE, MODE256 */ 200 igs_grfx_write(iot, ioh, 6, 0x05); /* 64k @ a0000, GRAPHICS */ 201 igs_grfx_write(iot, ioh, 7, 0x0f); /* color compare all */ 202 igs_grfx_write(iot, ioh, 8, 0xff); /* bitmask = all bits mutable */ 203} 204 205 206/* 207 * Init attribute controller. 208 * This is common for all video modes. 209 */ 210static void 211igsfb_init_attr(sc) 212 struct igsfb_softc *sc; 213{ 214 bus_space_tag_t iot = sc->sc_iot; 215 bus_space_handle_t ioh = sc->sc_ioh; 216 int i; 217 218 igs_attr_flip_flop(iot, ioh); /* reset attr flip-flop to address */ 219 220 for (i = 0; i < 16; ++i) /* crt palette */ 221 igs_attr_write(iot, ioh, i, i); 222 223 igs_attr_write(iot, ioh, 0x10, 0x01); /* select graphic mode */ 224 igs_attr_write(iot, ioh, 0x11, 0x00); /* crt overscan color */ 225 igs_attr_write(iot, ioh, 0x12, 0x0f); /* color plane enable */ 226 igs_attr_write(iot, ioh, 0x13, 0x00); 227 igs_attr_write(iot, ioh, 0x14, 0x00); 228} 229 230 231/* 232 * When done with ATTR controller, call this to unblank the screen. 233 */ 234static void 235igsfb_video_on(sc) 236 struct igsfb_softc *sc; 237{ 238 bus_space_tag_t iot = sc->sc_iot; 239 bus_space_handle_t ioh = sc->sc_ioh; 240 241 igs_attr_flip_flop(iot, ioh); 242 bus_space_write_1(iot, ioh, IGS_ATTR_IDX, 0x20); 243 bus_space_write_1(iot, ioh, IGS_ATTR_IDX, 0x20); 244} 245 246 247/* 248 * Latch VCLK (b0/b1) and MCLK (b2/b3) values. 249 */ 250static void 251igsfb_freq_latch(sc) 252 struct igsfb_softc *sc; 253{ 254 bus_space_tag_t iot = sc->sc_iot; 255 bus_space_handle_t ioh = sc->sc_ioh; 256 257 bus_space_write_1(iot, ioh, IGS_EXT_IDX, 0xb9); 258 bus_space_write_1(iot, ioh, IGS_EXT_PORT, 0x80); 259 bus_space_write_1(iot, ioh, IGS_EXT_PORT, 0x00); 260} 261 262 263static void 264igsfb_init_ext(sc) 265 struct igsfb_softc *sc; 266{ 267 bus_space_tag_t iot = sc->sc_iot; 268 bus_space_handle_t ioh = sc->sc_ioh; 269 270 igs_ext_write(iot, ioh, 0x10, 0x10); /* IGS_EXT_START_ADDR enable */ 271 igs_ext_write(iot, ioh, 0x12, 0x00); /* IGS_EXT_IRQ_CTL disable */ 272 igs_ext_write(iot, ioh, 0x13, 0x00); /* MBZ for normal operation */ 273 274 igs_ext_write(iot, ioh, 0x31, 0x00); /* segment write ptr */ 275 igs_ext_write(iot, ioh, 0x32, 0x00); /* segment read ptr */ 276 277 /* IGS_EXT_BIU_MISC_CTL: linear, segon */ 278 igs_ext_write(iot, ioh, 0x33, 0x11); 279 280 /* sprite location */ 281 igs_ext_write(iot, ioh, 0x50, 0x00); 282 igs_ext_write(iot, ioh, 0x51, 0x00); 283 igs_ext_write(iot, ioh, 0x52, 0x00); 284 igs_ext_write(iot, ioh, 0x53, 0x00); 285 igs_ext_write(iot, ioh, 0x54, 0x00); 286 igs_ext_write(iot, ioh, 0x55, 0x00); 287 igs_ext_write(iot, ioh, 0x56, 0x00); /* sprite control */ 288 289 /* IGS_EXT_GRFX_MODE */ 290 igs_ext_write(iot, ioh, 0x57, 0x01); /* raster fb */ 291 292 /* overscan R/G/B */ 293 igs_ext_write(iot, ioh, 0x58, 0x00); 294 igs_ext_write(iot, ioh, 0x59, 0x00); 295 igs_ext_write(iot, ioh, 0x5A, 0x00); 296 297 /* 298 * Video memory size &c. We rely on firmware to program 299 * BUS_CTL(30), MEM_CTL1(71), MEM_CTL2(72) appropriately. 300 */ 301 302 /* ext memory ctl0 */ 303 igs_ext_write(iot, ioh, 0x70, 0x0B); /* enable fifo, seq */ 304 305 /* ext hidden ctl1 */ 306 igs_ext_write(iot, ioh, 0x73, 0x30); /* XXX: krups: 0x20 */ 307 308 /* ext fifo control */ 309 igs_ext_write(iot, ioh, 0x74, 0x10); /* XXX: krups: 0x1b */ 310 igs_ext_write(iot, ioh, 0x75, 0x10); /* XXX: krups: 0x1e */ 311 312 igs_ext_write(iot, ioh, 0x76, 0x00); /* ext seq. */ 313 igs_ext_write(iot, ioh, 0x7A, 0xC8); /* ext. hidden ctl */ 314 315 /* ext graphics ctl: GCEXTPATH. krups 1, nettrom 1, docs 3 */ 316 igs_ext_write(iot, ioh, 0x90, 0x01); 317 318 if (sc->sc_is2k) /* select normal vclk/mclk registers */ 319 igs_ext_write(iot, ioh, 0xBF, 0x00); 320 321 igs_ext_write(iot, ioh, 0xB0, 0xD2); /* VCLK = 25.175MHz */ 322 igs_ext_write(iot, ioh, 0xB1, 0xD3); 323 igs_ext_write(iot, ioh, 0xB2, 0xDB); /* MCLK = 75MHz*/ 324 igs_ext_write(iot, ioh, 0xB3, 0x54); 325 igsfb_freq_latch(sc); 326 327 if (sc->sc_is2k) 328 igs_ext_write(iot, ioh, 0xF8, 0x04); /* XXX: ??? */ 329 330 /* 640x480 8bpp at 60Hz */ 331 igs_ext_write(iot, ioh, 0x11, 0x00); 332 igs_ext_write(iot, ioh, 0x77, 0x01); /* 8bpp, indexed */ 333 igs_ext_write(iot, ioh, 0x14, 0x51); 334 igs_ext_write(iot, ioh, 0x15, 0x00); 335} 336 337 338static void 339igsfb_init_dac(sc) 340 struct igsfb_softc *sc; 341{ 342 bus_space_tag_t iot = sc->sc_iot; 343 bus_space_handle_t ioh = sc->sc_ioh; 344 u_int8_t reg; 345 346 /* RAMDAC address 2 select */ 347 reg = igs_ext_read(iot, ioh, IGS_EXT_SPRITE_CTL); 348 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, 349 reg | IGS_EXT_SPRITE_DAC_PEL); 350 351 /* VREFEN, DAC8 */ 352 bus_space_write_1(iot, ioh, IGS_DAC_CMD, 0x06); 353 354 /* restore */ 355 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, reg); 356 357 bus_space_write_1(iot, ioh, IGS_PEL_MASK, 0xff); 358} 359 360 361void 362igsfb_1024x768_8bpp_60Hz(sc) 363 struct igsfb_softc *sc; 364{ 365 bus_space_tag_t iot = sc->sc_iot; 366 bus_space_handle_t ioh = sc->sc_ioh; 367 368 igs_crtc_write(iot, ioh, 0x11, 0x00); /* write enable CRTC 0..7 */ 369 370 igs_crtc_write(iot, ioh, 0x00, 0xa3); 371 igs_crtc_write(iot, ioh, 0x01, 0x7f); 372 igs_crtc_write(iot, ioh, 0x02, 0x7f); /* krups: 80 */ 373 igs_crtc_write(iot, ioh, 0x03, 0x85); /* krups: 84 */ 374 igs_crtc_write(iot, ioh, 0x04, 0x84); /* krups: 88 */ 375 igs_crtc_write(iot, ioh, 0x05, 0x95); /* krups: 99 */ 376 igs_crtc_write(iot, ioh, 0x06, 0x24); 377 igs_crtc_write(iot, ioh, 0x07, 0xfd); 378 379 /* next block is almost constant, only bit 6 in reg 9 differs */ 380 igs_crtc_write(iot, ioh, 0x08, 0x00); 381 igs_crtc_write(iot, ioh, 0x09, 0x60); /* <- either 0x40 or 0x60 */ 382 igs_crtc_write(iot, ioh, 0x0a, 0x00); 383 igs_crtc_write(iot, ioh, 0x0b, 0x00); 384 igs_crtc_write(iot, ioh, 0x0c, 0x00); 385 igs_crtc_write(iot, ioh, 0x0d, 0x00); 386 igs_crtc_write(iot, ioh, 0x0e, 0x00); 387 igs_crtc_write(iot, ioh, 0x0f, 0x00); 388 389 igs_crtc_write(iot, ioh, 0x10, 0x06); 390 igs_crtc_write(iot, ioh, 0x11, 0x8c); 391 igs_crtc_write(iot, ioh, 0x12, 0xff); 392 igs_crtc_write(iot, ioh, 0x13, 0x80); /* depends on BPP */ 393 igs_crtc_write(iot, ioh, 0x14, 0x0f); 394 igs_crtc_write(iot, ioh, 0x15, 0x02); 395 igs_crtc_write(iot, ioh, 0x16, 0x21); 396 igs_crtc_write(iot, ioh, 0x17, 0xe3); 397 igs_crtc_write(iot, ioh, 0x18, 0xff); 398 399 igs_ext_write(iot, ioh, 0xB0, 0xE2); /* VCLK */ 400 igs_ext_write(iot, ioh, 0xB1, 0x58); 401#if 1 402 /* XXX: hmm, krups does this */ 403 igs_ext_write(iot, ioh, 0xB2, 0xE2); /* MCLK */ 404 igs_ext_write(iot, ioh, 0xB3, 0x58); 405#endif 406 igsfb_freq_latch(sc); 407 408 igs_ext_write(iot, ioh, 0x11, 0x00); 409 igs_ext_write(iot, ioh, 0x77, 0x01); /* 8bpp, indexed */ 410 igs_ext_write(iot, ioh, 0x14, 0x81); 411 igs_ext_write(iot, ioh, 0x15, 0x00); 412} 413 414 415static void igsfb_xxx_snoop(struct igsfb_softc *); /* XXX: debugging */ 416 417static void 418igsfb_xxx_snoop(sc) 419 struct igsfb_softc *sc; 420{ 421 bus_space_tag_t iot = sc->sc_iot; 422 bus_space_handle_t ioh = sc->sc_ioh; 423 u_int8_t reg; 424 425 /* Memory size */ 426 reg = igs_ext_read(iot, ioh, IGS_EXT_BUS_CTL); 427 printf(">>> EXT.30 = 0x%02x\n", reg); 428 429 /* 430 * Memory type &c. 431 * netwinder = 0x63 -> serial DRAM 1Mx16 chips 432 * krups = 0x03 -> serial DRAM 256Kx?? chips 433 */ 434 reg = igs_ext_read(iot, ioh, IGS_EXT_MEM_CTL1); 435 printf(">>> EXT.71 = 0x%02x\n", reg); 436 437 /* 438 * netwinder = 0x02 -> 4Mb, 32bit bus 439 * krups = 0x05 -> 2Mb, 64bit bus 440 */ 441 reg = igs_ext_read(iot, ioh, IGS_EXT_MEM_CTL2); 442 printf(">>> EXT.72 = 0x%02x\n", reg); 443} 444 445 446/* 447 * igs-video-init from krups prom 448 */ 449void 450igsfb_hw_setup(sc) 451 struct igsfb_softc *sc; 452{ 453 igsfb_xxx_snoop(sc); /* misc debugging printfs */ 454 455 igsfb_init_seq(sc); 456 igsfb_init_crtc(sc); 457 igsfb_init_attr(sc); 458 igsfb_init_grfx(sc); 459 igsfb_init_ext(sc); 460 igsfb_init_dac(sc); 461 462 igsfb_1024x768_8bpp_60Hz(sc); 463 igsfb_video_on(sc); 464} 465