]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/powerpc/wii/wii_fbvar.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / powerpc / wii / wii_fbvar.h
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
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 */