- implemented video mode setting with the property tags, and once again it only
[rpikern] / src / video.c
1 #include "config.h"
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdint.h>
5 #include "rpi.h"
6 #include "video.h"
7 #include "mem.h"
8 #include "debug.h"
9
10 /* needs to by 16-byte aligned, because the address we send over the mailbox
11  * interface, will have its 4 least significant bits masked off and taken over
12  * by the mailbox id
13  */
14 static char propbuf[256] __attribute__((aligned(16)));
15
16 static void *fb_pixels;
17 static int fb_width, fb_height, fb_depth, fb_size;
18
19 int video_init(void)
20 {
21         int i;
22         struct rpi_prop_header *hdr = (struct rpi_prop_header*)propbuf;
23         struct rpi_prop *prop = (struct rpi_prop*)(hdr + 1);
24
25         hdr->size = sizeof propbuf;
26         hdr->res = 0;
27
28         fb_width = 1024;
29         fb_height = 600;
30         fb_depth = 32;
31
32         prop->id = RPI_TAG_SETFBPHYS;
33         prop->size = 8;
34         prop->res = 0;
35         prop->data[0] = fb_width;
36         prop->data[1] = fb_height;
37         prop = RPI_PROP_NEXT(prop);
38
39         prop->id = RPI_TAG_SETFBVIRT;
40         prop->size = 8;
41         prop->res = 0;
42         prop->data[0] = fb_width;
43         prop->data[1] = fb_height;
44         prop = RPI_PROP_NEXT(prop);
45
46         prop->id = RPI_TAG_SETFBDEPTH;
47         prop->size = 4;
48         prop->res = 0;
49         prop->data[0] = fb_depth;
50         prop = RPI_PROP_NEXT(prop);
51
52         prop->id = RPI_TAG_ALLOCFB;
53         prop->size = 4;
54         prop->res = 0;
55         prop->data[0] = 4;      /* alignment */
56         prop = RPI_PROP_NEXT(prop);
57
58         prop->id = 0;
59         prop->size = 0;
60         prop->res = 0;
61         prop = RPI_PROP_NEXT(prop);
62
63         printf("Requesting video mode: %dx%d (%d bpp)\n", fb_width, fb_height, fb_depth);
64
65         rpi_mbox_send(RPI_MBOX_PROP, RPI_MEM_BUS_COHERENT(propbuf));
66         while(rpi_mbox_recv(RPI_MBOX_PROP) != RPI_MEM_BUS_COHERENT(propbuf));
67
68         hexdump(propbuf, sizeof propbuf);
69
70         if(hdr->res != 0x80000000) {
71                 printf("Request failed, error: %x\n", hdr->res);
72                 return -1;
73         }
74
75         prop = (struct rpi_prop*)(hdr + 1);
76         while(prop->id) {
77                 prop->size = prop->res & 0x7fffffff;
78
79                 switch(prop->id) {
80                 case RPI_TAG_SETFBPHYS:
81                         printf("setfbphys");
82                         break;
83
84                 case RPI_TAG_SETFBVIRT:
85                         printf("setfbvirt");
86                         fb_width = prop->data[0];
87                         fb_height = prop->data[1];
88                         break;
89
90                 case RPI_TAG_SETFBDEPTH:
91                         printf("setfbdepth");
92                         fb_depth = prop->data[0];
93                         break;
94
95                 case RPI_TAG_ALLOCFB:
96                         printf("allocfb");
97                         fb_pixels = (void*)prop->data[0];
98                         fb_size = prop->data[1];
99                         break;
100
101                 default:
102                         printf("tag %x", prop->id);
103                         break;
104                 }
105
106                 printf(" %08x (%u bytes):", prop->res, prop->size);
107                 for(i=0; i<prop->size / 4; i++) {
108                         printf(" %u", prop->data[i]);
109                 }
110                 putchar('\n');
111                 prop = RPI_PROP_NEXT(prop);
112         }
113
114         printf("Got video mode: %dx%d (%d bpp) at %p (%d bytes)\n", fb_width, fb_height,
115                         fb_depth, fb_pixels, fb_size);
116
117         memset(fb_pixels, 0, fb_size);
118         return 0;
119 }