From 98a35452957d4339948b357cea1d339a107d5fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 14 Aug 2009 22:14:07 +0000 Subject: [PATCH] [ARM] Add support for boot splash, only for PXA. Disabled for now as it forces the framebuffer onto some useful data. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32399 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/boot/arch/arm/arch_video.cpp | 201 +++++++++++++++++++--- src/system/boot/arch/arm/arch_video.h | 18 +- src/system/boot/platform/u-boot/Jamfile | 14 +- src/system/boot/platform/u-boot/video.cpp | 40 ++++- 4 files changed, 230 insertions(+), 43 deletions(-) diff --git a/src/system/boot/arch/arm/arch_video.cpp b/src/system/boot/arch/arm/arch_video.cpp index ba6a5f6746..a0a553eb25 100644 --- a/src/system/boot/arch/arm/arch_video.cpp +++ b/src/system/boot/arch/arm/arch_video.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -20,7 +20,9 @@ #include #include -struct fb_description gFrameBuffer; +//XXX +extern "C" addr_t mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 flags); + #define TRACE_VIDEO #ifdef TRACE_VIDEO @@ -34,20 +36,109 @@ struct fb_description gFrameBuffer; #define dumpr(a) dprintf("LCC:%s:0x%lx\n", #a, read_io_32(a)) -// #pragma mark - #if BOARD_CPU_PXA270 +// #pragma mark - + + +extern void *gFrameBufferBase; static struct pxa27x_lcd_dma_descriptor sVideoDMADesc; static uint32 scratch[128] __attribute__((aligned(16))); + + status_t -arch_init_video(void) +arch_probe_video_mode(void) { + dprintf("%s()\n", __FUNCTION__); + uint32 bppCode, pixelFormat; + struct pxa27x_lcd_dma_descriptor *dma; + + // check if LCD controller is enabled + if (!(read_io_32(LCCR0) | 0x00000001)) + return B_NO_INIT; + + pixelFormat = bppCode = read_io_32(LCCR3); + bppCode = (bppCode >> 26) & 0x08 | (bppCode >> 24) & 0x07; + pixelFormat >>= 30; + + dma = (struct pxa27x_lcd_dma_descriptor *)(read_io_32(FDADR0) & ~0x0f); + if (!dma) + return B_ERROR; + + switch (bppCode) { + case 2: + gKernelArgs.frame_buffer.depth = 4; + break; + case 3: + gKernelArgs.frame_buffer.depth = 8; + break; + case 4: + gKernelArgs.frame_buffer.depth = 16; + break; + case 9: + case 10: + gKernelArgs.frame_buffer.depth = 32; // RGB888 + break; + defaut: + return B_ERROR; + } + + gKernelArgs.frame_buffer.physical_buffer.start = (dma->fdadr & ~0x0f); + gKernelArgs.frame_buffer.width = (read_io_32(LCCR1) & ((1 << 10) - 1)) + 1; + gKernelArgs.frame_buffer.height = (read_io_32(LCCR2) & ((1 << 10) - 1)) + 1; + gKernelArgs.frame_buffer.bytes_per_row = gKernelArgs.frame_buffer.width + * sizeof(uint32); + gKernelArgs.frame_buffer.physical_buffer.size = gKernelArgs.frame_buffer.width + * gKernelArgs.frame_buffer.height + * gKernelArgs.frame_buffer.depth / 8; + + dprintf("video mode: %ux%ux%u\n", gKernelArgs.frame_buffer.width, + gKernelArgs.frame_buffer.height, gKernelArgs.frame_buffer.depth); + + gKernelArgs.frame_buffer.enabled = true; + + + + return B_OK; +} + +status_t +arch_set_video_mode(int width, int height, int depth) +{ + dprintf("%s(%d, %d, %d)\n", __FUNCTION__, width, height, depth); + status_t err; void *fb; + uint32 fbSize = width * height * depth / 8; //fb = malloc(800*600*4 + 16 - 1); //fb = (void *)(((uint32)fb) & ~(0x0f)); + //fb = scratch - 800; //fb = (void *)0xa0000000; - fb = scratch - 800; + +// gFrameBufferBase = scratch - 800; + +#if 1 + gFrameBufferBase = (void *)0xa4000000; + gKernelArgs.frame_buffer.physical_buffer.start = (addr_t)gFrameBufferBase; +#endif +#if 0 + if (!gFrameBufferBase) { + //XXX: realloc if larger !!! + err = platform_allocate_region(&gFrameBufferBase, fbSize, 0, false); +dprintf("error %08x\n", err); + if (err < B_OK) + return err; + gKernelArgs.frame_buffer.physical_buffer.start = (addr_t)gFrameBufferBase; +/* + gFrameBufferBase = (void *)mmu_map_physical_memory( + 0xa8000000, fbSize, 0); + if (gFrameBufferBase == NULL) + return B_NO_MEMORY; + gKernelArgs.frame_buffer.physical_buffer.start = (addr_t)gFrameBufferBase;//0xa8000000; +*/ + } +#endif + fb = gFrameBufferBase; dprintf("fb @ %p\n", fb); @@ -55,52 +146,118 @@ arch_init_video(void) sVideoDMADesc.fdadr = ((uint32)&sVideoDMADesc & ~0x0f) | 0x01; sVideoDMADesc.fsadr = (uint32)(fb) & ~0x0f; sVideoDMADesc.fidr = 0; - sVideoDMADesc.ldcmd = (800*600*4); + sVideoDMADesc.ldcmd = fbSize; // if not already enabled, set a default mode if (!(read_io_32(LCCR0) & 0x00000001)) { - dprintf("Setting default video mode 800x600\n"); int bpp = 0x09; // 24 bpp int pdfor = 0x3; // Format 4: RGB888 (no alpha bit) - write_io_32(LCCR1, (0 << 0) | (800)); - write_io_32(LCCR2, (0 << 0) | (600-1)); + dprintf("Setting video mode\n"); + switch (depth) { + case 4: + bpp = 2; + break; + case 8: + bpp = 3; + break; + case 16: + bpp = 3; + break; + case 32: + bpp = 9; + pdfor = 0x3; + break; + default: + return EINVAL; + } + write_io_32(LCCR1, (0 << 0) | (width - 1)); + write_io_32(LCCR2, (0 << 0) | (height - 1)); write_io_32(LCCR3, (pdfor << 30) | ((bpp >> 3) << 29) | ((bpp & 0x07) << 24)); write_io_32(FDADR0, sVideoDMADesc.fdadr); write_io_32(LCCR0, read_io_32(LCCR0) | 0x01800001); // no ints +ENB write_io_32(FBR0, sVideoDMADesc.fdadr); - dumpr(LCCR0); - dumpr(LCCR1); - dumpr(LCCR2); - dumpr(LCCR3); - dumpr(LCCR4); + dumpr(LCCR0); + dumpr(LCCR1); + dumpr(LCCR2); + dumpr(LCCR3); + dumpr(LCCR4); + } else + return EALREADY; // for now - for (int i = 0; i < 128; i++) - //((uint32 *)fb)[i+16] = 0x000000ff << ((i%4) * 8); + // clear the video memory + memset((void *)fb, 0, fbSize); + + // XXX test pattern + for (int i = 0; i < 128; i++) { + ((uint32 *)fb)[i+16] = 0x000000ff << ((i%4) * 8); scratch[i] = 0x000000ff << ((i%4) * 8); } - return B_OK; + + // update framebuffer descriptor + return arch_probe_video_mode(); } + +status_t +arch_set_default_video_mode() +{ + dprintf("%s()\n", __FUNCTION__); + return arch_set_video_mode(800, 600, 32); +} + + #elif BOARD_CPU_OMAP3 +// #pragma mark - + status_t -arch_init_video(void) +arch_probe_video_mode(void) { - return B_OK; + return B_ERROR; } + +status_t +arch_set_video_mode(int width, int height, int depth) +{ + return B_ERROR; +} + + +status_t +arch_set_default_video_mode() +{ + return arch_set_video_mode(800, 600, 32); +} + + #else +// #pragma mark - status_t -arch_init_video(void) +arch_probe_video_mode(void) { - return B_OK; + return B_ERROR; } + +status_t +arch_set_video_mode(int width, int height, int depth) +{ + return B_ERROR; +} + + +status_t +arch_set_default_video_mode() +{ + return arch_set_video_mode(800, 600, 32); +} + + #endif -// #pragma mark - diff --git a/src/system/boot/arch/arm/arch_video.h b/src/system/boot/arch/arm/arch_video.h index 84be40676d..54813807de 100644 --- a/src/system/boot/arch/arm/arch_video.h +++ b/src/system/boot/arch/arm/arch_video.h @@ -7,19 +7,11 @@ #include -struct fb_description { - uint8 *base; - uint32 size; - uint32 bytes_per_row; - uint16 width; - uint16 height; - uint8 depth; - bool enabled; -}; - -extern struct fb_description gFrameBuffer; - -extern status_t arch_init_video(); +/* try to detect current video mode and set gFrameBuffer accordingly */ +extern status_t arch_probe_video_mode(); +/* try to set a video mode */ +extern status_t arch_set_video_mode(int width, int height, int depth); +extern status_t arch_set_default_video_mode(); #endif /* _ARCH_VIDEO_H */ diff --git a/src/system/boot/platform/u-boot/Jamfile b/src/system/boot/platform/u-boot/Jamfile index bfe1c1b25b..7f19a9fab6 100644 --- a/src/system/boot/platform/u-boot/Jamfile +++ b/src/system/boot/platform/u-boot/Jamfile @@ -23,6 +23,13 @@ local uImageFakeOS = "netbsd" ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; +local genericPlatformSources = + text_menu.cpp + video_blit.cpp + video_splash.cpp + video_rle.cpp +; + KernelMergeObject boot_platform_u-boot.o : shell.S start2.c @@ -35,9 +42,8 @@ KernelMergeObject boot_platform_u-boot.o : cpu.cpp uimage.cpp video.cpp - mmu.cpp - # generic - text_menu.cpp + mmu.cpp + $(genericPlatformSources) : -fno-pic @@ -199,7 +205,7 @@ BuildUBootSDImage haiku.mmc : $(HAIKU_BOARD_SDIMAGE_FILES) ; SEARCH on [ FGristFiles shell.S ] = [ FDirName $(HAIKU_TOP) src system boot platform $(TARGET_BOOT_PLATFORM) arch $(TARGET_ARCH) ] ; -SEARCH on [ FGristFiles text_menu.cpp ] +SEARCH on [ FGristFiles $(genericPlatformSources) ] = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ; # Tell the build system to where stage1.bin can be found, so it can be used diff --git a/src/system/boot/platform/u-boot/video.cpp b/src/system/boot/platform/u-boot/video.cpp index 1bbb406106..4db887db3f 100644 --- a/src/system/boot/platform/u-boot/video.cpp +++ b/src/system/boot/platform/u-boot/video.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -28,6 +28,7 @@ # define TRACE(x) ; #endif +void *gFrameBufferBase = NULL; // #pragma mark - @@ -65,19 +66,47 @@ video_mode_menu() // #pragma mark - + +extern "C" void +platform_set_palette(const uint8 *palette) +{ +} + + +extern "C" void +platform_blit4(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, + uint16 imageWidth, uint16 left, uint16 top) +{ +} + extern "C" void platform_switch_to_logo(void) { + TRACE(("%s()\n", __FUNCTION__)); // in debug mode, we'll never show the logo if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) != 0) return; - #warning ARM:TODO + + //XXX: not yet, DISABLED + return; + + status_t err; + + err = arch_set_default_video_mode(); + dprintf("set video mode: 0x%08x\n", err); + if (err < B_OK) + return; + + err = video_display_splash((addr_t)gFrameBufferBase); + dprintf("video_display_splash: 0x%08x\n", err); + #warning ARM:TODO } extern "C" void platform_switch_to_text_mode(void) { + TRACE(("%s()\n", __FUNCTION__)); #warning ARM:TODO } @@ -85,9 +114,12 @@ platform_switch_to_text_mode(void) extern "C" status_t platform_init_video(void) { + TRACE(("%s()\n", __FUNCTION__)); #warning ARM:TODO -dprintf("init_video\n"); - return arch_init_video(); + arch_probe_video_mode(); + //XXX for testing + //platform_switch_to_logo(); + //return arch_probe_video_mode(); //return B_OK; }