video initialization seems to work, further testing needed
[rpikern] / src / video.c
1 #include "config.h"
2 #include <string.h>
3 #include <stdint.h>
4 #include "video.h"
5 #include "serial.h"
6 #include "mem.h"
7
8 #define MBOX_READ_REG   (*(volatile uint32_t*)(IO_BASE | 0xb880))
9 #define MBOX_POLL_REG   (*(volatile uint32_t*)(IO_BASE | 0xb890))
10 #define MBOX_SENDER_REG (*(volatile uint32_t*)(IO_BASE | 0xb894))
11 #define MBOX_STATUS_REG (*(volatile uint32_t*)(IO_BASE | 0xb898))
12 #define MBOX_CFG_REG    (*(volatile uint32_t*)(IO_BASE | 0xb89c))
13 #define MBOX_WRITE_REG  (*(volatile uint32_t*)(IO_BASE | 0xb8a0))
14
15 #define MBOX_STAT_WRBUSY        0x80000000
16 #define MBOX_STAT_RDBUSY        0x40000000
17
18 struct vc_fbinfo {
19         uint32_t phys_width, phys_height;
20         uint32_t virt_width, virt_height;
21         uint32_t pitch;                 /* filled by videocore */
22         uint32_t depth;
23         uint32_t x, y;
24         void *addr;             /* filled by videocore */
25         uint32_t size;  /* filled by videocore */
26 };
27
28 void mbox_write(int mbox, uint32_t msg);
29 uint32_t mbox_read(int mbox);
30
31 static struct vc_fbinfo fbinf __attribute__((aligned(16)));
32
33 int video_init(void)
34 {
35         memset(&fbinf, 0, sizeof fbinf);
36         fbinf.phys_width = fbinf.virt_width = 1024;
37         fbinf.phys_height = fbinf.virt_height = 600;
38         fbinf.depth = 32;
39         fbinf.x = fbinf.y = 0;
40
41         mbox_write(1, MEM_BUS_COHERENT(&fbinf));
42         if(mbox_read(1) != 0) {
43                 ser_printstr("Failed to initialize display\n");
44                 return -1;
45         }
46
47         ser_printstr("Video init successful\n");
48         memset(fbinf.addr, 0, fbinf.size);
49         return 0;
50 }
51
52 void mbox_write(int mbox, uint32_t msg)
53 {
54         while(MBOX_STATUS_REG & MBOX_STAT_WRBUSY);
55         MBOX_WRITE_REG = (msg & 0xfffffff0) | mbox;
56 }
57
58 uint32_t mbox_read(int mbox)
59 {
60         uint32_t msg;
61
62         do {
63                 while(MBOX_STATUS_REG & MBOX_STAT_RDBUSY);
64                 msg = MBOX_READ_REG;
65         } while((msg & 0xf) != mbox);
66
67         return msg & 0xfffffff0;
68 }