2 Copyright © 2013-2019, The AROS Development Team. All rights reserved.
5 Desc: VideoCore framebuffer routines
9 #include <aros/macros.h>
11 #include <hardware/bcm2708.h>
12 #include <hardware/bcm2708_boot.h>
15 #include <hardware/videocore.h>
17 #include "bootconsole.h"
23 #define ARM_PERIIOBASE (__arm_periiobase)
24 extern uint32_t __arm_periiobase
;
30 unsigned int fb_width
, fb_height
, fb_depth
, fb_pitch
;
32 volatile unsigned int *vcmb_msg
= (unsigned int *)BOOTMEMADDR(bm_mboxmsg
);
35 D(kprintf("[VCFB] vcfb_init()\n"));
37 scr_Type
= SCR_UNKNOWN
;
39 /* query the display dimensions */
41 vcmb_msg
[0] = AROS_LONG2LE(8 * 4);
42 vcmb_msg
[1] = AROS_LONG2LE(VCTAG_REQ
);
43 vcmb_msg
[2] = AROS_LONG2LE(VCTAG_GETRES
);
44 vcmb_msg
[3] = AROS_LONG2LE(8);
48 vcmb_msg
[7] = 0; // terminate tag
50 vcmb_write(VCMB_BASE
, VCMB_PROPCHAN
, (void *)vcmb_msg
);
51 vcmb_msg
= vcmb_read(VCMB_BASE
, VCMB_PROPCHAN
);
53 if (!vcmb_msg
|| (vcmb_msg
[1] != AROS_LONG2LE(VCTAG_RESP
)))
56 if (((fb_width
= AROS_LE2LONG(vcmb_msg
[5])) == 0) || ((fb_height
= AROS_LE2LONG(vcmb_msg
[6])) == 0))
62 D(kprintf("[VCFB] fb_width=%d, fb_height=%d\n", fb_width
, fb_height
));
65 /* fill in our framebuffer configuration/allocation request */
68 vcmb_msg
[c
++] = AROS_LONG2LE(VCTAG_REQ
);
70 vcmb_msg
[c
++] = AROS_LONG2LE(VCTAG_SETRES
);
71 vcmb_msg
[c
++] = AROS_LONG2LE(8);
72 vcmb_msg
[c
++] = AROS_LONG2LE(0);
73 vcmb_msg
[c
++] = AROS_LONG2LE(fb_width
);
74 vcmb_msg
[c
++] = AROS_LONG2LE(fb_height
);
76 vcmb_msg
[c
++] = AROS_LONG2LE(VCTAG_SETVRES
); // duplicate physical size...
77 vcmb_msg
[c
++] = AROS_LONG2LE(8);
78 vcmb_msg
[c
++] = AROS_LONG2LE(0);
79 vcmb_msg
[c
++] = AROS_LONG2LE(fb_width
);
80 vcmb_msg
[c
++] = AROS_LONG2LE(fb_height
);
82 vcmb_msg
[c
++] = AROS_LONG2LE(VCTAG_SETDEPTH
);
83 vcmb_msg
[c
++] = AROS_LONG2LE(4);
84 vcmb_msg
[c
++] = AROS_LONG2LE(0);
88 vcmb_msg
[c
++] = AROS_LONG2LE(fb_depth
);
90 vcmb_msg
[c
++] = AROS_LONG2LE(VCTAG_FBALLOC
);
91 vcmb_msg
[c
++] = AROS_LONG2LE(8);
92 vcmb_msg
[c
++] = AROS_LONG2LE(0);
93 vcmb_msg
[c
++] = AROS_LONG2LE(64);
94 vcmb_msg
[c
++] = AROS_LONG2LE(0);
96 vcmb_msg
[c
++] = AROS_LONG2LE(0); // terminate tags
98 vcmb_msg
[0] = AROS_LONG2LE((c
<< 2)); // fill in request size
100 vcmb_write(VCMB_BASE
, VCMB_PROPCHAN
, (void *)vcmb_msg
);
101 vcmb_msg
= vcmb_read(VCMB_BASE
, VCMB_PROPCHAN
);
103 if (!vcmb_msg
|| (vcmb_msg
[1] != AROS_LONG2LE(VCTAG_RESP
)))
106 count
= 2; // locate the allocation request
107 while((AROS_LE2LONG(vcmb_msg
[count
])))
109 if (vcmb_msg
[count
] == AROS_LONG2LE(VCTAG_FBALLOC
))
112 count
+= 3 + (AROS_LE2LONG(vcmb_msg
[count
+ 1]) >> 2);
118 if (AROS_LE2LONG(vcmb_msg
[count
+ 2]) != (VCTAG_RESP
+ 8))
121 D(kprintf("%p, %p, %p, %p, %p\n", AROS_LE2LONG(vcmb_msg
[count
]), AROS_LE2LONG(vcmb_msg
[count
+1]), AROS_LE2LONG(vcmb_msg
[count
+2]),
122 AROS_LE2LONG(vcmb_msg
[count
+3]),AROS_LE2LONG(vcmb_msg
[count
+4])));
124 if (((scr_FrameBuffer
= (void *)(AROS_LE2LONG(vcmb_msg
[count
+ 3]))) == 0) || (AROS_LE2LONG(vcmb_msg
[count
+ 4]) == 0))
127 D(kprintf("[VCFB] scr_Framebuffer=%p, %p\n", scr_FrameBuffer
, (intptr_t)scr_FrameBuffer
& 0xc0000000));
129 if (((intptr_t)scr_FrameBuffer
& 0xc0000000) == 0x40000000)
131 D(kprintf("[VCFB] Buffer in L2 cache\n"));
133 else if (((intptr_t)scr_FrameBuffer
& 0xc0000000) == 0xc0000000)
135 D(kprintf("[VCFB] Buffer uncached\n"));
137 scr_FrameBuffer
= (void*)((intptr_t)scr_FrameBuffer
& ~0xc0000000);
140 /* query the framebuffer pitch */
142 vcmb_msg
[0] = AROS_LONG2LE(7 * 4);
143 vcmb_msg
[1] = AROS_LONG2LE(VCTAG_REQ
);
144 vcmb_msg
[2] = AROS_LONG2LE(VCTAG_GETPITCH
);
145 vcmb_msg
[3] = AROS_LONG2LE(4);
148 vcmb_msg
[6] = 0; // terminate tag
150 vcmb_write(VCMB_BASE
, VCMB_PROPCHAN
, (void *)vcmb_msg
);
151 vcmb_msg
= vcmb_read(VCMB_BASE
, VCMB_PROPCHAN
);
153 if (!vcmb_msg
|| (vcmb_msg
[4] != AROS_LONG2LE(VCTAG_RESP
+ 4)))
156 if ((fb_pitch
= AROS_LE2LONG(vcmb_msg
[5])) == 0)
159 D(kprintf("[VCFB] fb_pitch=%d\n", fb_pitch
));
164 fb_Init(fb_width
, fb_height
, fb_depth
, fb_pitch
);