detect if the compiler supports -fno-builtin and -fno-builtin-vsnprintf. (NicJA)
[AROS.git] / arch / armeb-raspi / boot / vc_fb.c
blob143bf73c6352fd507123887c5eca7107c70dfde2
1 /*
2 Copyright � 2013-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: VideoCore framebuffer routines
6 Lang: english
7 */
9 #include <aros/macros.h>
11 #include <hardware/bcm2708.h>
12 #include <hardware/bcm2708_boot.h>
13 #undef ARM_PERIIOBASE
15 #include <hardware/videocore.h>
17 #include "bootconsole.h"
18 #include "vc_mb.h"
19 #include "vc_fb.h"
20 #include "boot.h"
22 #undef ARM_PERIIOBASE
23 #define ARM_PERIIOBASE (__arm_periiobase)
24 extern uint32_t __arm_periiobase;
26 #define D(x) /* x */
28 int vcfb_init(void)
30 unsigned int fb_width, fb_height, fb_depth, fb_pitch;
31 unsigned int count;
32 volatile unsigned int *vcmb_msg = (unsigned int *)BOOTMEMADDR(bm_mboxmsg);
33 scr_FrameBuffer = 0;
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);
45 vcmb_msg[4] = 0;
46 vcmb_msg[5] = 0;
47 vcmb_msg[6] = 0;
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)))
54 return 0;
56 if (((fb_width = AROS_LE2LONG(vcmb_msg[5])) == 0) || ((fb_height = AROS_LE2LONG(vcmb_msg[6])) == 0))
58 fb_width = 1024;
59 fb_height = 768;
62 D(kprintf("[VCFB] fb_width=%d, fb_height=%d\n", fb_width, fb_height));
65 /* fill in our framebuffer configuration/allocation request */
67 unsigned int c = 1;
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);
86 fb_depth = 16;
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)))
104 return 0;
106 count = 2; // locate the allocation request
107 while((AROS_LE2LONG(vcmb_msg[count])))
109 if (vcmb_msg[count] == AROS_LONG2LE(VCTAG_FBALLOC))
110 break;
112 count += 3 + (AROS_LE2LONG(vcmb_msg[count + 1]) >> 2);
114 if (count > c)
115 return 0;
118 if (AROS_LE2LONG(vcmb_msg[count + 2]) != (VCTAG_RESP + 8))
119 return 0;
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))
125 return 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);
146 vcmb_msg[4] = 0;
147 vcmb_msg[5] = 0;
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)))
154 return 0;
156 if ((fb_pitch = AROS_LE2LONG(vcmb_msg[5])) == 0)
157 return 0;
159 D(kprintf("[VCFB] fb_pitch=%d\n", fb_pitch));
162 scr_Type = SCR_GFX;
164 fb_Init(fb_width, fb_height, fb_depth, fb_pitch);
166 return 1;