1 /* mailbox registers (MB 0: input 1: output)
2 * function | MB 0 | MB 1
3 * rd/wr | 00 | 20 ( upper 28: data, lower 4: channel )
9 * channel 1: framebuffer
12 * read: read status reg loop while empty flag is set
13 * write: read status loop while full flag is set
19 #define IOBASEADDR 0x20000000
21 #define IOBASEADDR 0x3f000000
24 #define phys2bus(addr) ((addr) | 0x40000000)
25 #define bus2phys(addr) ((addr) & 0x3fffffff)
27 #define IOREG_ADDR(x) (IOBASEADDR | (x))
28 #define REG_MB_READ *((volatile uint32_t*)IOREG_ADDR(0xb880))
29 #define REG_MB_STAT *((volatile uint32_t*)IOREG_ADDR(0xb898))
30 #define REG_MB_WRITE *((volatile uint32_t*)IOREG_ADDR(0xb8a0))
32 #define MB_STAT_FULL 0x80000000
33 #define MB_STAT_EMPTY 0x40000000
35 #define MB_CHAN_FRAMEBUF 1
36 #define MB_CHAN_PROP 8
38 #define PROP_CODE_REQ 0
39 #define PROP_RESP_OK 0x80000000
42 #define PROP_TAG_END 0
44 #define PROP_TAG_SET 0x08000
45 #define PROP_TAG_TEST 0x04000
46 #define PROP_TAG_GET 0
48 #define PROP_TAG_ALLOCBUF 0x40001
49 #define PROP_TAG_BLANKSCR 0x40002
50 #define PROP_TAG_PHYSRES 0x40003
51 #define PROP_TAG_VIRTRES 0x40004
52 #define PROP_TAG_DEPTH 0x40005
53 #define PROP_TAG_PIXEL_ORDER 0x40006
54 #define PROP_TAG_ALPHA_MODE 0x40007
55 #define PROP_TAG_PITCH 0x40008
56 #define PROP_TAG_VOFFS 0x40009
57 #define PROP_TAG_OVERSCAN 0x4000a
58 #define PROP_TAG_PALETTE 0x4000b
59 #define PROP_TAG_CUR_INFO 0x00010
60 #define PROP_TAG_CUR_STATE 0x00011
64 int prop_blankscr(int onoff);
65 int prop_setres(int xsz, int ysz);
66 int prop_getres(int *xsz, int *ysz);
67 int prop_setvres(int xsz, int ysz);
68 int prop_getvres(int *xsz, int *ysz);
69 int prop_setdepth(int bpp);
70 int prop_getdepth(void);
71 int prop_getpitch(void);
72 void *prop_allocbuf(int *size);
74 uint32_t mb_read(int chan);
75 void mb_write(int chan, uint32_t val);
82 int i, j, bpp, fbsize, pitch;
85 if(prop_setres(640, 480) == -1) panic();
86 if(prop_setvres(640, 480) == -1) panic();
87 if(prop_setdepth(16) == -1) panic();
88 if(!(fb = prop_allocbuf(&fbsize))) panic();
89 bpp = prop_getdepth();
90 pitch = prop_getpitch();
92 if(bpp != 16) panic();
94 for(i=0; i<480; i++) {
95 for(j=0; j<640; j++) {
97 int r = (xor >> 1) & 0xff;
99 int b = (xor << 1) & 0xff;
101 *fb++ = ((r << 8) & 0xf800) | ((g << 3) & 0x7e0) | ((b >> 3) & 0x1f);
104 //fb += pitch / 2 - 640;
116 static uint32_t propbuf[64] __attribute__((aligned(16)));
118 static int send_prop(uint32_t *buf)
120 mb_write(MB_CHAN_PROP, (uint32_t)buf >> 4);
121 mb_read(MB_CHAN_PROP);
122 return propbuf[1] == PROP_RESP_OK ? 0 : -1;
125 int prop_blankscr(int onoff)
127 uint32_t *pb = propbuf;
131 *pb++ = PROP_TAG_BLANKSCR;
132 *pb++ = 4; /* data size */
133 *pb++ = PROP_CODE_REQ;
134 *pb++ = onoff ? 1 : 0;
135 *pb++ = PROP_TAG_END;
136 *pb++ = 0; /* padding */
138 return send_prop(propbuf);
141 int prop_setres(int xsz, int ysz)
143 uint32_t *pb = propbuf;
147 *pb++ = PROP_TAG_PHYSRES | PROP_TAG_SET;
148 *pb++ = 8; /* data size */
149 *pb++ = PROP_CODE_REQ;
152 *pb++ = PROP_TAG_END;
154 return send_prop(propbuf);
157 int prop_getres(int *xsz, int *ysz)
159 uint32_t *pb = propbuf;
164 *pb++ = PROP_TAG_PHYSRES;
166 *pb++ = PROP_CODE_REQ;
170 *pb++ = PROP_TAG_END;
172 if(send_prop(propbuf) == -1) {
180 int prop_setvres(int xsz, int ysz)
182 uint32_t *pb = propbuf;
186 *pb++ = PROP_TAG_VIRTRES | PROP_TAG_SET;
187 *pb++ = 8; /* data size */
188 *pb++ = PROP_CODE_REQ;
191 *pb++ = PROP_TAG_END;
193 return send_prop(propbuf);
196 int prop_getvres(int *xsz, int *ysz)
198 uint32_t *pb = propbuf;
203 *pb++ = PROP_TAG_VIRTRES;
205 *pb++ = PROP_CODE_REQ;
209 *pb++ = PROP_TAG_END;
211 if(send_prop(propbuf) == -1) {
219 int prop_setdepth(int bpp)
221 uint32_t *pb = propbuf;
225 *pb++ = PROP_TAG_DEPTH | PROP_TAG_SET;
227 *pb++ = PROP_CODE_REQ;
229 *pb++ = PROP_TAG_END;
230 *pb++ = 0; /* padding */
232 return send_prop(propbuf);
235 int prop_getdepth(void)
237 uint32_t *pb = propbuf;
242 *pb++ = PROP_TAG_DEPTH;
243 *pb++ = 4; /* data size */
244 *pb++ = PROP_CODE_REQ;
247 *pb++ = PROP_TAG_END;
248 *pb++ = 0; /* padding */
250 if(send_prop(propbuf) == -1) {
256 int prop_getpitch(void)
258 uint32_t *pb = propbuf;
263 *pb++ = PROP_TAG_PITCH;
264 *pb++ = 4; /* data size */
265 *pb++ = PROP_CODE_REQ;
268 *pb++ = PROP_TAG_END;
269 *pb++ = 0; /* padding */
271 if(send_prop(propbuf) == -1) {
277 void *prop_allocbuf(int *size)
279 uint32_t *pb = propbuf;
284 *pb++ = PROP_TAG_ALLOCBUF;
285 *pb++ = 8; /* data size */
286 *pb++ = PROP_CODE_REQ;
288 *pb++ = 16; /* alignment */
290 *pb++ = PROP_TAG_END;
292 if(send_prop(propbuf) == -1) {
296 return (void*)bus2phys(data[0]);
299 uint32_t mb_read(int chan)
303 while(REG_MB_STAT & MB_STAT_EMPTY);
305 } while((val & 0xf) != chan);
309 void mb_write(int chan, uint32_t val)
311 while(REG_MB_STAT & MB_STAT_FULL);
312 REG_MB_WRITE = (val << 4) | chan;