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: releng/10.1/sys/powerpc/wii/wii_fbvar.h 239478 2012-08-21 06:31:26Z adrian $
27 */
28
29 #ifndef _POWERPC_WII_WIIFB_H
30 #define _POWERPC_WII_WIIFB_H
31
32 #define WIIFB_FONT_HEIGHT 8
33
34 enum wiifb_format {
35 WIIFB_FORMAT_NTSC = 0,
36 WIIFB_FORMAT_PAL = 1,
37 WIIFB_FORMAT_MPAL = 2,
38 WIIFB_FORMAT_DEBUG = 3
39 };
40
41 enum 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
49 struct 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
59 struct 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
94 struct wiifb_vtiming {
95 uint8_t vt_eqpulse;
96 uint16_t vt_actvideo;
97 };
98
99 static __inline void
100 wiifb_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
109 static __inline void
110 wiifb_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
125 struct 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
135 static __inline void
136 wiifb_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
150 static __inline void
151 wiifb_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
171 struct wiifb_htiming0 {
172 uint16_t ht0_hlinew; /* half line width */
173 uint8_t ht0_hcolourend;
174 uint8_t ht0_hcolourstart;
175 };
176
177 static __inline void
178 wiifb_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
188 static __inline void
189 wiifb_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
204 struct wiifb_htiming1 {
205 uint8_t ht1_hsyncw;
206 uint16_t ht1_hblankend;
207 uint16_t ht1_hblankstart;
208 };
209
210 static __inline void
211 wiifb_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
221 static __inline void
222 wiifb_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
238 struct wiifb_vtimingodd {
239 uint16_t vto_preb; /* pre blanking */
240 uint16_t vto_postb; /* post blanking */
241 };
242
243 static __inline void
244 wiifb_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
253 static __inline void
254 wiifb_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
269 struct wiifb_vtimingeven {
270 uint16_t vte_preb; /* pre blanking */
271 uint16_t vte_postb; /* post blanking */
272 };
273
274 static __inline void
275 wiifb_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
284 static __inline void
285 wiifb_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
300 struct wiifb_burstblankodd {
301 uint8_t bbo_bs1;
302 uint16_t bbo_be1;
303 uint8_t bbo_bs3;
304 uint16_t bbo_be3;
305 };
306
307 static __inline void
308 wiifb_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
320 static __inline void
321 wiifb_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
339 struct wiifb_burstblankeven {
340 uint8_t bbe_bs2;
341 uint16_t bbe_be2;
342 uint8_t bbe_bs4;
343 uint16_t bbe_be4;
344 };
345
346 static __inline void
347 wiifb_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
359 static __inline void
360 wiifb_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
378 struct wiifb_topfieldbasel {
379 uint32_t tfbl_fbaddr;
380 uint8_t tfbl_xoffset;
381 uint8_t tfbl_pageoffbit;
382 };
383
384 static __inline void
385 wiifb_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
396 static __inline void
397 wiifb_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
414 struct wiifb_topfieldbaser {
415 uint32_t tfbr_fbaddr;
416 uint8_t tfbr_pageoffbit;
417 };
418
419 static __inline void
420 wiifb_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
430 static __inline void
431 wiifb_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
447 struct wiifb_bottomfieldbasel {
448 uint32_t bfbl_fbaddr;
449 uint8_t bfbl_xoffset;
450 uint8_t bfbl_pageoffbit;
451 };
452
453 static __inline void
454 wiifb_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
465 static __inline void
466 wiifb_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
483 struct wiifb_bottomfieldbaser {
484 uint32_t bfbr_fbaddr;
485 uint8_t bfbr_pageoffbit;
486 };
487
488 static __inline void
489 wiifb_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
499 static __inline void
500 wiifb_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
516 static __inline uint16_t
517 wiifb_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
525 static __inline void
526 wiifb_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
540 static __inline uint16_t
541 wiifb_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
549 static __inline void
550 wiifb_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
567 struct wiifb_dispint {
568 uint16_t di_htiming;
569 uint16_t di_vtiming;
570 uint8_t di_enable;
571 uint8_t di_irq;
572 };
573
574 static __inline void
575 wiifb_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
586 static __inline void
587 wiifb_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
616 struct wiifb_picconf {
617 uint8_t pc_strides; /* strides per line (words) */
618 uint8_t pc_reads; /* reads per line (words */
619 };
620
621 static __inline void
622 wiifb_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
631 static __inline void
632 wiifb_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
647 struct wiifb_hscaling {
648 uint16_t hs_step;
649 uint8_t hs_enable;
650 };
651
652 static __inline void
653 wiifb_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
662 static __inline void
663 wiifb_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
684 static __inline void
685 wiifb_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
700 static __inline void
701 wiifb_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
715 static __inline uint8_t
716 wiifb_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
724 static __inline void
725 wiifb_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
741 static __inline uint16_t
742 wiifb_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
750 static __inline uint16_t
751 wiifb_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
762 static __inline uint16_t
763 wiifb_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
771 static __inline void
772 wiifb_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
787 static __inline void
788 wiifb_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
802 static __inline void
803 wiifb_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
817 static __inline void
818 wiifb_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
832 static __inline void
833 wiifb_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
847 static __inline void
848 wiifb_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 */
Cache object: be248cca3c927fcec9f120c7a3525b79
|