vxKernel/vxgos/bootloader/boards/raspi3b/src/framebuffer.c

194 lines
5.0 KiB
C

#include "raspi3b/framebuffer.h"
#include "raspi3b/mailbox.h"
#include "raspi3b/uart.h"
//---
// Internals
//---
/* frambuffer - internal framebuffer information */
static struct framebuffer framebuffer = {
.watermark = 0x00000000,
.vram = {
.gpu = (uintptr_t)NULL,
.cpu = (uintptr_t)NULL,
.size = 0,
.pitch = 0,
.align = 0,
},
.phys = {
.width = 0,
.height = 0,
},
.virt = {
.width = 0,
.height = 0,
},
};
/* framebuffer_setup_request() : perpare mailbox request */
static void framebuffer_setup_prepare(volatile uint32_t *mbox)
{
/* prepare mailbox request
* @note
* <> 1024x768
* <> 32bits per pixel (TODO: palette ?)
* <> start offset at x=0 and y=0
* */
mbox[0] = 35*4;
mbox[1] = MBOX_REQUEST_CODE;
/* set the physical screen size
* @note
* <> 1024x768
* <> mbox[5] = FrameBufferInfo.width
* <> mbox[6] = FrameBufferInfo.height
* */
mbox[2] = MBOX_TAG_SCREEN_SET_PHYS_SIZE;
mbox[3] = 8;
mbox[4] = 8;
mbox[5] = 1024;
mbox[6] = 768;
/* set the virtual screen size
* @note
* <> 1024x768
* <> mbox[10] = FrameBufferInfo.virtual_width
* <> mbox[11] = FrameBufferInfo.virtual_height
* */
mbox[7] = MBOX_TAG_SCREEN_SET_VIRT_SIZE;
mbox[8] = 8;
mbox[9] = 8;
mbox[10] = 1024;
mbox[11] = 768;
/* set the virtual X/Y offset
* @note
* <> x=0 and y=0
* <> mbox[14] = FrameBufferInfo.x_offset
* <> mbox[15] = FrameBufferInfo.y_offset
* */
mbox[12] = MBOX_TAG_SCREEN_SET_VIRTUAL_OFFSET;
mbox[13] = 8;
mbox[14] = 8;
mbox[15] = 0;
mbox[16] = 0;
/* set the pixel depth (bits per pixels)
* @note
* <> for now, use classic RGB(A?) 32bits encoding
* <> mbox[20] = FrameBufferInfo.depth
* */
mbox[17] = MBOX_TAG_SCREEN_SET_PHYS_DEPTH;
mbox[18] = 4;
mbox[19] = 4;
mbox[20] = 32;
/* set pixel order (BGR or RGB)
* <> use RGB
* <> mbox[24] = FrameBufferInfo.
* */
mbox[21] = MBOX_TAG_SCREEN_SET_PIXEL_ORDER;
mbox[22] = 4;
mbox[23] = 4;
mbox[24] = 1;
/* request a framebuffer
* @note
* <> mbox[28] = request buffer alignement to 4k
* <> mbox[28] = FrameBufferInfo.addr
* <> mbox[29] = FramebufferInfo.size
* */
mbox[25] = MBOX_TAG_SCREEN_BUFF_ALLOC;
mbox[26] = 8;
mbox[27] = 8;
mbox[28] = 4096;
mbox[29] = 0;
/* get pixel pitch (number of pixel per line)
* @note
* <> mbox[33] = FrameBufferInfo.pitch
* */
mbox[30] = MBOX_TAG_SCREEN_GET_PITCH;
mbox[31] = 4;
mbox[32] = 4;
mbox[33] = 0;
/* indicate the end of the request */
mbox[34] = MBOX_TAG_END;
}
/* framebuffer_setup_request() : perform mailbox request and fetch info */
static int framebuffer_setup_request(volatile uint32_t *mbox)
{
if (framebuffer.watermark == FRAMEBUFFER_WATERMARK)
return -1;
framebuffer_setup_prepare(mbox);
if (mailbox_send(MBOX_CHANNEL_PROP) == 0)
return -2;
framebuffer.vram.gpu = mbox[28];
framebuffer.vram.cpu = mbox[28] & 0x3fffffff;
framebuffer.vram.size = mbox[29];
framebuffer.vram.pitch = mbox[33];
framebuffer.vram.align = 4096;
framebuffer.phys.width = mbox[5];
framebuffer.phys.height = mbox[6];
framebuffer.virt.width = mbox[10];
framebuffer.virt.height = mbox[11];
if (framebuffer.vram.gpu == (uintptr_t)NULL)
return -3;
framebuffer.watermark = FRAMEBUFFER_WATERMARK;
return 0;
}
//---
// Public
//---
/* framebuffer_init() : initialize framebuffer */
int framebuffer_init(void)
{
volatile uint32_t *mbox;
if (mailbox_get(&mbox) != 0)
return -1;
if (framebuffer_setup_request(mbox) != 0)
return -2;
uart_puts("- OK\n");
return 0;
}
/* framebuffer_get() : fetch the framebuffer information if available */
int framebuffer_get(struct framebuffer **framebuffer_out)
{
if (framebuffer_out == NULL)
return -1;
if (framebuffer.watermark != FRAMEBUFFER_WATERMARK)
return -2;
*framebuffer_out = &framebuffer;
return 0;
}
/* framebuffer_debug() : display framebuffer information */
void framebuffer_debug(void)
{
uart_puts("[+] debug framebuffer information:\n");
if (framebuffer.watermark != FRAMEBUFFER_WATERMARK) {
uart_puts("- not initialized\n");
return;
}
uart_putf("- VRAM GPU address : %p\n", framebuffer.vram.gpu);
uart_putf("- VRAM CPU address : %p\n", framebuffer.vram.cpu);
uart_putf("- VRAM size : %d\n", framebuffer.vram.size);
uart_putf("- VRAM pitch : %d\n", framebuffer.vram.pitch);
uart_putf("- VRAM align : %d\n", framebuffer.vram.align);
uart_putf("- SCREEN phys. width : %d\n", framebuffer.phys.width);
uart_putf("- SCREEN phys. height : %d\n", framebuffer.phys.height);
uart_putf("- SCREEN virt. width : %d\n", framebuffer.virt.width);
uart_putf("- SCREEN virt. height : %d\n", framebuffer.virt.height);
}