1/*- 2 * Copyright (C) 2012 Margarida Gouveia 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29#ifndef _POWERPC_WII_WIIFB_H 30#define _POWERPC_WII_WIIFB_H 31 32#define WIIFB_FONT_HEIGHT 8 33 34enum wiifb_format { 35 WIIFB_FORMAT_NTSC = 0, 36 WIIFB_FORMAT_PAL = 1, 37 WIIFB_FORMAT_MPAL = 2, 38 WIIFB_FORMAT_DEBUG = 3 39}; 40 41enum wiifb_mode { 42 WIIFB_MODE_NTSC_480i = 0, 43 WIIFB_MODE_NTSC_480p = 1, 44 WIIFB_MODE_PAL_576i = 2, 45 WIIFB_MODE_PAL_480i = 3, 46 WIIFB_MODE_PAL_480p = 4 47}; 48 49struct wiifb_mode_desc { 50 const char *fd_name; 51 unsigned int fd_width; 52 unsigned int fd_height; 53 unsigned int fd_lines; 54 uint8_t fd_flags; 55#define WIIFB_MODE_FLAG_PROGRESSIVE 0x00 56#define WIIFB_MODE_FLAG_INTERLACED 0x01 57}; 58 59struct wiifb_softc { 60 video_adapter_t sc_va; 61 struct cdev *sc_si; 62 int sc_console; 63 64 intptr_t sc_reg_addr; 65 unsigned int sc_reg_size; 66 67 intptr_t sc_fb_addr; 68 unsigned int sc_fb_size; 69 70 unsigned int sc_height; 71 unsigned int sc_width; 72 unsigned int sc_stride; 73 74 unsigned int sc_xmargin; 75 unsigned int sc_ymargin; 76 77 boolean_t sc_component; 78 enum wiifb_format sc_format; 79 struct wiifb_mode_desc *sc_mode; 80 81 unsigned int sc_vtiming; 82 unsigned int sc_htiming; 83 84 unsigned char *sc_font; 85 int sc_initialized; 86 int sc_rrid; 87}; 88 89/* 90 * Vertical timing 91 * 16 bit 92 */ 93#define WIIFB_REG_VTIMING 0x00 94struct wiifb_vtiming { 95 uint8_t vt_eqpulse; 96 uint16_t vt_actvideo; 97}; 98 99static __inline void 100wiifb_vtiming_read(struct wiifb_softc *sc, struct wiifb_vtiming *vt) 101{ 102 volatile uint16_t *reg = 103 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMING); 104 105 vt->vt_eqpulse = *reg & 0xf; 106 vt->vt_actvideo = (*reg >> 4) & 0x3ff; 107} 108 109static __inline void 110wiifb_vtiming_write(struct wiifb_softc *sc, struct wiifb_vtiming *vt) 111{ 112 volatile uint16_t *reg = 113 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMING); 114 115 *reg = ((vt->vt_actvideo & 0x3ff) << 4) | 116 (vt->vt_eqpulse & 0xf); 117 powerpc_sync(); 118} 119 120/* 121 * Display configuration 122 * 16 bit 123 */ 124#define WIIFB_REG_DISPCFG 0x02 125struct wiifb_dispcfg { 126 uint8_t dc_enable; 127 uint8_t dc_reset; 128 uint8_t dc_noninterlaced; 129 uint8_t dc_3dmode; 130 uint8_t dc_latchenb0; 131 uint8_t dc_latchenb1; 132 enum wiifb_format dc_format; 133}; 134 135static __inline void 136wiifb_dispcfg_read(struct wiifb_softc *sc, struct wiifb_dispcfg *dc) 137{ 138 volatile uint16_t *reg = 139 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DISPCFG); 140 141 dc->dc_enable = *reg & 0x1; 142 dc->dc_reset = (*reg >> 1) & 0x1; 143 dc->dc_noninterlaced = (*reg >> 2) & 0x1; 144 dc->dc_3dmode = (*reg >> 3) & 0x1; 145 dc->dc_latchenb0 = (*reg >> 4) & 0x3; 146 dc->dc_latchenb1 = (*reg >> 6) & 0x3; 147 dc->dc_format = (*reg >> 8) & 0x3; 148} 149 150static __inline void 151wiifb_dispcfg_write(struct wiifb_softc *sc, struct wiifb_dispcfg *dc) 152{ 153 volatile uint16_t *reg = 154 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DISPCFG); 155 156 *reg = ((dc->dc_format & 0x3) << 8) | 157 ((dc->dc_latchenb1 & 0x3) << 6) | 158 ((dc->dc_latchenb0 & 0x3) << 4) | 159 ((dc->dc_3dmode & 0x1) << 3) | 160 ((dc->dc_noninterlaced & 0x1) << 2) | 161 ((dc->dc_reset & 0x1) << 1) | 162 (dc->dc_enable & 0x1); 163 powerpc_sync(); 164} 165 166/* 167 * Horizontal Timing 0 168 * 32 bit 169 */ 170#define WIIFB_REG_HTIMING0 0x04 171struct wiifb_htiming0 { 172 uint16_t ht0_hlinew; /* half line width */ 173 uint8_t ht0_hcolourend; 174 uint8_t ht0_hcolourstart; 175}; 176 177static __inline void 178wiifb_htiming0_read(struct wiifb_softc *sc, struct wiifb_htiming0 *ht0) 179{ 180 volatile uint32_t *reg = 181 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING0); 182 183 ht0->ht0_hlinew = *reg & 0x1ff; 184 ht0->ht0_hcolourend = (*reg >> 16) & 0x7f; 185 ht0->ht0_hcolourstart = (*reg >> 24) & 0x7f; 186} 187 188static __inline void 189wiifb_htiming0_write(struct wiifb_softc *sc, struct wiifb_htiming0 *ht0) 190{ 191 volatile uint32_t *reg = 192 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING0); 193 194 *reg = ((ht0->ht0_hcolourstart & 0x7f) << 24) | 195 ((ht0->ht0_hcolourend & 0x7f) << 16) | 196 (ht0->ht0_hlinew & 0x1ff); 197 powerpc_sync(); 198} 199/* 200 * Horizontal Timing 1 201 * 32 bit 202 */ 203#define WIIFB_REG_HTIMING1 0x08 204struct wiifb_htiming1 { 205 uint8_t ht1_hsyncw; 206 uint16_t ht1_hblankend; 207 uint16_t ht1_hblankstart; 208}; 209 210static __inline void 211wiifb_htiming1_read(struct wiifb_softc *sc, struct wiifb_htiming1 *ht1) 212{ 213 volatile uint32_t *reg = 214 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING1); 215 216 ht1->ht1_hsyncw = *reg & 0x7f; 217 ht1->ht1_hblankend = (*reg >> 7) & 0x3ff; 218 ht1->ht1_hblankstart = (*reg >> 17) & 0x3ff; 219} 220 221static __inline void 222wiifb_htiming1_write(struct wiifb_softc *sc, struct wiifb_htiming1 *ht1) 223{ 224 volatile uint32_t *reg = 225 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_HTIMING1); 226 227 *reg = ((ht1->ht1_hblankstart & 0x3ff) << 17) | 228 ((ht1->ht1_hblankend & 0x3ff) << 7) | 229 (ht1->ht1_hsyncw & 0x7f); 230 powerpc_sync(); 231} 232 233/* 234 * Vertical Timing Odd 235 * 32 bit 236 */ 237#define WIIFB_REG_VTIMINGODD 0x0c 238struct wiifb_vtimingodd { 239 uint16_t vto_preb; /* pre blanking */ 240 uint16_t vto_postb; /* post blanking */ 241}; 242 243static __inline void 244wiifb_vtimingodd_read(struct wiifb_softc *sc, struct wiifb_vtimingodd *vto) 245{ 246 volatile uint32_t *reg = 247 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGODD); 248 249 vto->vto_preb = *reg & 0x3ff; 250 vto->vto_postb = (*reg >> 16) & 0x3ff; 251} 252 253static __inline void 254wiifb_vtimingodd_write(struct wiifb_softc *sc, struct wiifb_vtimingodd *vto) 255{ 256 volatile uint32_t *reg = 257 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGODD); 258 259 *reg = ((vto->vto_postb & 0x3ff) << 16) | 260 (vto->vto_preb & 0x3ff); 261 powerpc_sync(); 262} 263 264/* 265 * Vertical Timing Even 266 * 32 bit 267 */ 268#define WIIFB_REG_VTIMINGEVEN 0x10 269struct wiifb_vtimingeven { 270 uint16_t vte_preb; /* pre blanking */ 271 uint16_t vte_postb; /* post blanking */ 272}; 273 274static __inline void 275wiifb_vtimingeven_read(struct wiifb_softc *sc, struct wiifb_vtimingeven *vte) 276{ 277 volatile uint32_t *reg = 278 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGEVEN); 279 280 vte->vte_preb = *reg & 0x3ff; 281 vte->vte_postb = (*reg >> 16) & 0x3ff; 282} 283 284static __inline void 285wiifb_vtimingeven_write(struct wiifb_softc *sc, struct wiifb_vtimingeven *vte) 286{ 287 volatile uint32_t *reg = 288 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_VTIMINGEVEN); 289 290 *reg = ((vte->vte_postb & 0x3ff) << 16) | 291 (vte->vte_preb & 0x3ff); 292 powerpc_sync(); 293} 294 295/* 296 * Burst Blanking Odd Interval 297 * 32 bit 298 */ 299#define WIIFB_REG_BURSTBLANKODD 0x14 300struct wiifb_burstblankodd { 301 uint8_t bbo_bs1; 302 uint16_t bbo_be1; 303 uint8_t bbo_bs3; 304 uint16_t bbo_be3; 305}; 306 307static __inline void 308wiifb_burstblankodd_read(struct wiifb_softc *sc, 309 struct wiifb_burstblankodd *bbo) 310{ 311 volatile uint32_t *reg = 312 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKODD); 313 314 bbo->bbo_bs1 = *reg & 0x1f; 315 bbo->bbo_be1 = (*reg >> 5) & 0x7ff; 316 bbo->bbo_bs3 = (*reg >> 16) & 0x1f; 317 bbo->bbo_be3 = (*reg >> 21) & 0x7ff; 318} 319 320static __inline void 321wiifb_burstblankodd_write(struct wiifb_softc *sc, 322 struct wiifb_burstblankodd *bbo) 323{ 324 volatile uint32_t *reg = 325 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKODD); 326 327 *reg = ((bbo->bbo_be3 & 0x7ff) << 21) | 328 ((bbo->bbo_bs3 & 0x1f) << 16) | 329 ((bbo->bbo_be1 & 0x7ff) << 5) | 330 (bbo->bbo_bs1 & 0x1f); 331 powerpc_sync(); 332} 333 334/* 335 * Burst Blanking Even Interval 336 * 32 bit 337 */ 338#define WIIFB_REG_BURSTBLANKEVEN 0x18 339struct wiifb_burstblankeven { 340 uint8_t bbe_bs2; 341 uint16_t bbe_be2; 342 uint8_t bbe_bs4; 343 uint16_t bbe_be4; 344}; 345 346static __inline void 347wiifb_burstblankeven_read(struct wiifb_softc *sc, 348 struct wiifb_burstblankeven *bbe) 349{ 350 volatile uint32_t *reg = 351 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKEVEN); 352 353 bbe->bbe_bs2 = *reg & 0x1f; 354 bbe->bbe_be2 = (*reg >> 5) & 0x7ff; 355 bbe->bbe_bs4 = (*reg >> 16) & 0x1f; 356 bbe->bbe_be4 = (*reg >> 21) & 0x7ff; 357} 358 359static __inline void 360wiifb_burstblankeven_write(struct wiifb_softc *sc, 361 struct wiifb_burstblankeven *bbe) 362{ 363 volatile uint32_t *reg = 364 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BURSTBLANKEVEN); 365 366 *reg = ((bbe->bbe_be4 & 0x7ff) << 21) | 367 ((bbe->bbe_bs4 & 0x1f) << 16) | 368 ((bbe->bbe_be2 & 0x7ff) << 5) | 369 (bbe->bbe_bs2 & 0x1f); 370 powerpc_sync(); 371} 372 373/* 374 * Top Field Base Left 375 * 32 bit 376 */ 377#define WIIFB_REG_TOPFIELDBASEL 0x1c 378struct wiifb_topfieldbasel { 379 uint32_t tfbl_fbaddr; 380 uint8_t tfbl_xoffset; 381 uint8_t tfbl_pageoffbit; 382}; 383 384static __inline void 385wiifb_topfieldbasel_read(struct wiifb_softc *sc, 386 struct wiifb_topfieldbasel *tfbl) 387{ 388 volatile uint32_t *reg = 389 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASEL); 390 391 tfbl->tfbl_fbaddr = *reg & 0xffffff; 392 tfbl->tfbl_xoffset = (*reg >> 24) & 0xf; 393 tfbl->tfbl_pageoffbit = (*reg >> 28) & 0x1; 394} 395 396static __inline void 397wiifb_topfieldbasel_write(struct wiifb_softc *sc, 398 struct wiifb_topfieldbasel *tfbl) 399{ 400 volatile uint32_t *reg = 401 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASEL); 402 403 *reg = ((tfbl->tfbl_pageoffbit & 0x1) << 28) | 404 ((tfbl->tfbl_xoffset & 0xf) << 24) | 405 (tfbl->tfbl_fbaddr & 0xffffff); 406 powerpc_sync(); 407} 408 409/* 410 * Top Field Base Right 411 * 32 bit 412 */ 413#define WIIFB_REG_TOPFIELDBASER 0x20 414struct wiifb_topfieldbaser { 415 uint32_t tfbr_fbaddr; 416 uint8_t tfbr_pageoffbit; 417}; 418 419static __inline void 420wiifb_topfieldbaser_read(struct wiifb_softc *sc, 421 struct wiifb_topfieldbaser *tfbr) 422{ 423 volatile uint32_t *reg = 424 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASER); 425 426 tfbr->tfbr_fbaddr = *reg & 0xffffff; 427 tfbr->tfbr_pageoffbit = (*reg >> 28) & 0x1; 428} 429 430static __inline void 431wiifb_topfieldbaser_write(struct wiifb_softc *sc, 432 struct wiifb_topfieldbaser *tfbr) 433{ 434 volatile uint32_t *reg = 435 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_TOPFIELDBASER); 436 437 *reg = ((tfbr->tfbr_pageoffbit & 0x1) << 28) | 438 (tfbr->tfbr_fbaddr & 0xffffff); 439 powerpc_sync(); 440} 441 442/* 443 * Bottom Field Base Left 444 * 32 bit 445 */ 446#define WIIFB_REG_BOTTOMFIELDBASEL 0x24 447struct wiifb_bottomfieldbasel { 448 uint32_t bfbl_fbaddr; 449 uint8_t bfbl_xoffset; 450 uint8_t bfbl_pageoffbit; 451}; 452 453static __inline void 454wiifb_bottomfieldbasel_read(struct wiifb_softc *sc, 455 struct wiifb_bottomfieldbasel *bfbl) 456{ 457 volatile uint32_t *reg = 458 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASEL); 459 460 bfbl->bfbl_fbaddr = *reg & 0xffffff; 461 bfbl->bfbl_xoffset = (*reg >> 24) & 0xf; 462 bfbl->bfbl_pageoffbit = (*reg >> 28) & 0x1; 463} 464 465static __inline void 466wiifb_bottomfieldbasel_write(struct wiifb_softc *sc, 467 struct wiifb_bottomfieldbasel *bfbl) 468{ 469 volatile uint32_t *reg = 470 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASEL); 471 472 *reg = ((bfbl->bfbl_pageoffbit & 0x1) << 28) | 473 ((bfbl->bfbl_xoffset & 0xf) << 24) | 474 (bfbl->bfbl_fbaddr & 0xffffff); 475 powerpc_sync(); 476} 477 478/* 479 * Bottom Field Base Right 480 * 32 bit 481 */ 482#define WIIFB_REG_BOTTOMFIELDBASER 0x28 483struct wiifb_bottomfieldbaser { 484 uint32_t bfbr_fbaddr; 485 uint8_t bfbr_pageoffbit; 486}; 487 488static __inline void 489wiifb_bottomfieldbaser_read(struct wiifb_softc *sc, 490 struct wiifb_bottomfieldbaser *bfbr) 491{ 492 volatile uint32_t *reg = 493 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASER); 494 495 bfbr->bfbr_fbaddr = *reg & 0xffffff; 496 bfbr->bfbr_pageoffbit = (*reg >> 28) & 0x1; 497} 498 499static __inline void 500wiifb_bottomfieldbaser_write(struct wiifb_softc *sc, 501 struct wiifb_bottomfieldbaser *bfbr) 502{ 503 volatile uint32_t *reg = 504 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_BOTTOMFIELDBASER); 505 506 *reg = ((bfbr->bfbr_pageoffbit & 0x1) << 28) | 507 (bfbr->bfbr_fbaddr & 0xffffff); 508 powerpc_sync(); 509} 510 511/* 512 * Display Position Vertical 513 * 16 bit 514 */ 515#define WIIFB_REG_DISPPOSV 0x2c 516static __inline uint16_t 517wiifb_dispposv_read(struct wiifb_softc *sc) 518{ 519 volatile uint32_t *reg = 520 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSV); 521 522 return (*reg & 0x7ff); 523} 524 525static __inline void 526wiifb_dispposv_write(struct wiifb_softc *sc, uint16_t val) 527{ 528 volatile uint32_t *reg = 529 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSV); 530 531 *reg = val & 0x7ff; 532 powerpc_sync(); 533} 534 535/* 536 * Display Position Horizontal 537 * 16 bit 538 */ 539#define WIIFB_REG_DISPPOSH 0x2e 540static __inline uint16_t 541wiifb_dispposh_read(struct wiifb_softc *sc) 542{ 543 volatile uint32_t *reg = 544 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSH); 545 546 return (*reg & 0x7ff); 547} 548 549static __inline void 550wiifb_dispposh_write(struct wiifb_softc *sc, uint16_t val) 551{ 552 volatile uint32_t *reg = 553 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_DISPPOSH); 554 555 *reg = val & 0x7ff; 556 powerpc_sync(); 557} 558 559/* 560 * Display Interrupts. 561 * There are 4 display interrupt registers, all 32 bit. 562 */ 563#define WIIFB_REG_DISPINT0 0x30 564#define WIIFB_REG_DISPINT1 0x34 565#define WIIFB_REG_DISPINT2 0x38 566#define WIIFB_REG_DISPINT3 0x3c 567struct wiifb_dispint { 568 uint16_t di_htiming; 569 uint16_t di_vtiming; 570 uint8_t di_enable; 571 uint8_t di_irq; 572}; 573 574static __inline void 575wiifb_dispint_read(struct wiifb_softc *sc, int regno, struct wiifb_dispint *di) 576{ 577 volatile uint32_t *reg = (uint32_t *)(sc->sc_reg_addr + 578 WIIFB_REG_DISPINT0 + regno * 4); 579 580 di->di_htiming = *reg & 0x3ff; 581 di->di_vtiming = (*reg >> 16) & 0x3ff; 582 di->di_enable = (*reg >> 28) & 0x1; 583 di->di_irq = (*reg >> 31) & 0x1; 584} 585 586static __inline void 587wiifb_dispint_write(struct wiifb_softc *sc, int regno, struct wiifb_dispint *di) 588{ 589 volatile uint32_t *reg = (uint32_t *)(sc->sc_reg_addr + 590 WIIFB_REG_DISPINT0 + regno * 4); 591 592 *reg = ((di->di_irq & 0x1) << 31) | 593 ((di->di_enable & 0x1) << 28) | 594 ((di->di_vtiming & 0x3ff) << 16) | 595 (di->di_htiming & 0x3ff); 596 powerpc_sync(); 597} 598 599/* 600 * Display Latch 0 601 * 32 bit 602 */ 603#define WIIFB_REG_DISPLAYTCH0 0x40 604 605/* 606 * Display Latch 1 607 * 32 bit 608 */ 609#define WIIFB_REG_DISPLAYTCH1 0x44 610 611/* 612 * Picture Configuration 613 * 16 bit 614 */ 615#define WIIFB_REG_PICCONF 0x48 616struct wiifb_picconf { 617 uint8_t pc_strides; /* strides per line (words) */ 618 uint8_t pc_reads; /* reads per line (words */ 619}; 620 621static __inline void 622wiifb_picconf_read(struct wiifb_softc *sc, struct wiifb_picconf *pc) 623{ 624 volatile uint16_t *reg = 625 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_PICCONF); 626 627 pc->pc_strides = *reg & 0xff; 628 pc->pc_reads = (*reg >> 8) & 0xff; 629} 630 631static __inline void 632wiifb_picconf_write(struct wiifb_softc *sc, struct wiifb_picconf *pc) 633{ 634 volatile uint16_t *reg = 635 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_PICCONF); 636 637 *reg = ((pc->pc_reads & 0xff) << 8) | 638 (pc->pc_strides & 0xff); 639 powerpc_sync(); 640} 641 642/* 643 * Horizontal Scaling 644 * 16 bit 645 */ 646#define WIIFB_REG_HSCALING 0x4a 647struct wiifb_hscaling { 648 uint16_t hs_step; 649 uint8_t hs_enable; 650}; 651 652static __inline void 653wiifb_hscaling_read(struct wiifb_softc *sc, struct wiifb_hscaling *hs) 654{ 655 volatile uint16_t *reg = 656 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALING); 657 658 hs->hs_step = *reg & 0x1ff; 659 hs->hs_enable = (*reg >> 12) & 0x1; 660} 661 662static __inline void 663wiifb_hscaling_write(struct wiifb_softc *sc, struct wiifb_hscaling *hs) 664{ 665 volatile uint16_t *reg = 666 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALING); 667 668 *reg = ((hs->hs_step & 0x1ff) << 12) | 669 (hs->hs_enable & 0x1); 670 powerpc_sync(); 671} 672 673/* 674 * Filter Coeficient Table 0-6 675 * 32 bit 676 */ 677#define WIIFB_REG_FILTCOEFT0 0x4c 678#define WIIFB_REG_FILTCOEFT1 0x50 679#define WIIFB_REG_FILTCOEFT2 0x54 680#define WIIFB_REG_FILTCOEFT3 0x58 681#define WIIFB_REG_FILTCOEFT4 0x5c 682#define WIIFB_REG_FILTCOEFT5 0x60 683#define WIIFB_REG_FILTCOEFT6 0x64 684static __inline void 685wiifb_filtcoeft_write(struct wiifb_softc *sc, unsigned int regno, 686 uint32_t coeft) 687{ 688 volatile uint32_t *reg = 689 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_FILTCOEFT0 + 4 * regno); 690 691 *reg = coeft; 692 powerpc_sync(); 693} 694 695/* 696 * Anti-aliasing 697 * 32 bit 698 */ 699#define WIIFB_REG_ANTIALIAS 0x68 700static __inline void 701wiifb_antialias_write(struct wiifb_softc *sc, uint32_t antialias) 702{ 703 volatile uint32_t *reg = 704 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_ANTIALIAS); 705 706 *reg = antialias; 707 powerpc_sync(); 708} 709 710/* 711 * Video Clock 712 * 16 bit 713 */ 714#define WIIFB_REG_VIDEOCLK 0x6c 715static __inline uint8_t 716wiifb_videoclk_read(struct wiifb_softc *sc) 717{ 718 volatile uint16_t *reg = 719 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VIDEOCLK); 720 721 return (*reg & 0x1); 722} 723 724static __inline void 725wiifb_videoclk_write(struct wiifb_softc *sc, uint16_t clk54mhz) 726{ 727 volatile uint16_t *reg = 728 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_VIDEOCLK); 729 730 *reg = clk54mhz & 0x1; 731 powerpc_sync(); 732} 733 734/* 735 * DTV Status 736 * 16 bit 737 * 738 * DTV is another name for the Component Cable output. 739 */ 740#define WIIFB_REG_DTVSTATUS 0x6e 741static __inline uint16_t 742wiifb_dtvstatus_read(struct wiifb_softc *sc) 743{ 744 volatile uint16_t *reg = 745 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_DTVSTATUS); 746 747 return (*reg & 0x1); 748} 749 750static __inline uint16_t 751wiifb_component_enabled(struct wiifb_softc *sc) 752{ 753 754 return wiifb_dtvstatus_read(sc); 755} 756 757/* 758 * Horizontal Scaling Width 759 * 16 bit 760 */ 761#define WIIFB_REG_HSCALINGW 0x70 762static __inline uint16_t 763wiifb_hscalingw_read(struct wiifb_softc *sc) 764{ 765 volatile uint16_t *reg = 766 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALINGW); 767 768 return (*reg & 0x3ff); 769} 770 771static __inline void 772wiifb_hscalingw_write(struct wiifb_softc *sc, uint16_t width) 773{ 774 volatile uint16_t *reg = 775 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HSCALINGW); 776 777 *reg = width & 0x3ff; 778 powerpc_sync(); 779} 780 781/* 782 * Horizontal Border End 783 * For debug mode only. Not used by this driver. 784 * 16 bit 785 */ 786#define WIIFB_REG_HBORDEREND 0x72 787static __inline void 788wiifb_hborderend_write(struct wiifb_softc *sc, uint16_t border) 789{ 790 volatile uint16_t *reg = 791 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HBORDEREND); 792 793 *reg = border; 794 powerpc_sync(); 795} 796 797/* 798 * Horizontal Border Start 799 * 16 bit 800 */ 801#define WIIFB_REG_HBORDERSTART 0x74 802static __inline void 803wiifb_hborderstart_write(struct wiifb_softc *sc, uint16_t border) 804{ 805 volatile uint16_t *reg = 806 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_HBORDERSTART); 807 808 *reg = border; 809 powerpc_sync(); 810} 811 812/* 813 * Unknown register 814 * 16 bit 815 */ 816#define WIIFB_REG_UNKNOWN1 0x76 817static __inline void 818wiifb_unknown1_write(struct wiifb_softc *sc, uint16_t unknown) 819{ 820 volatile uint16_t *reg = 821 (uint16_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN1); 822 823 *reg = unknown; 824 powerpc_sync(); 825} 826 827/* 828 * Unknown register 829 * 32 bit 830 */ 831#define WIIFB_REG_UNKNOWN2 0x78 832static __inline void 833wiifb_unknown2_write(struct wiifb_softc *sc, uint32_t unknown) 834{ 835 volatile uint32_t *reg = 836 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN2); 837 838 *reg = unknown; 839 powerpc_sync(); 840} 841 842/* 843 * Unknown register 844 * 32 bit 845 */ 846#define WIIFB_REG_UNKNOWN3 0x7c 847static __inline void 848wiifb_unknown3_write(struct wiifb_softc *sc, uint32_t unknown) 849{ 850 volatile uint32_t *reg = 851 (uint32_t *)(sc->sc_reg_addr + WIIFB_REG_UNKNOWN3); 852 853 *reg = unknown; 854 powerpc_sync(); 855} 856 857#endif /* _POWERPC_WII_WIIFB_H */ 858