From: John Hodge Date: Tue, 10 Jan 2012 23:40:15 +0000 (+0800) Subject: Modules/Tegra2Vid - Got it compiling X-Git-Tag: rel0.14~16^2~4 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=bd89b9812ab14e47109fdcbf62b954a19e54da6a;p=tpg%2Facess2.git Modules/Tegra2Vid - Got it compiling --- diff --git a/Modules/Display/Tegra2/main.c b/Modules/Display/Tegra2/main.c index 9f64510b..493dd607 100644 --- a/Modules/Display/Tegra2/main.c +++ b/Modules/Display/Tegra2/main.c @@ -13,6 +13,7 @@ #include #include #include // ARM Arch +#include "tegra2.h" #define ABS(a) ((a)>0?(a):-(a)) @@ -26,10 +27,10 @@ Uint64 Tegra2Vid_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer); Uint64 Tegra2Vid_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer); int Tegra2Vid_IOCtl(tVFS_Node *node, int id, void *data); // -- Internals - int Tegra2Vid_int_SetResolution(int W, int H); + int Tegra2Vid_int_SetMode(int Mode); // === GLOBALS === -MODULE_DEFINE(0, VERSION, PL110, Tegra2Vid_Install, NULL, NULL); +MODULE_DEFINE(0, VERSION, Video_Tegra2, Tegra2Vid_Install, NULL, NULL); tDevFS_Driver gTegra2Vid_DriverStruct = { NULL, "PL110", { @@ -39,7 +40,7 @@ tDevFS_Driver gTegra2Vid_DriverStruct = { } }; // -- Options -tPAddr gTegra2Vid_PhysBase = Tegra2Vid_BASE; +tPAddr gTegra2Vid_PhysBase = TEGRA2VID_BASE; int gbTegra2Vid_IsVersatile = 1; // -- KeyVal parse rules const tKeyVal_ParseRules gTegra2Vid_KeyValueParser = { @@ -72,7 +73,7 @@ int Tegra2Vid_Install(char **Arguments) gpTegra2Vid_IOMem = (void*)MM_MapHWPages(gTegra2Vid_PhysBase, 1); - Tegra2Vid_int_SetResolution(caTegra2Vid_Modes[0].W, caTegra2Vid_Modes[0].H); + Tegra2Vid_int_SetMode(4); DevFS_AddDevice( &gTegra2Vid_DriverStruct ); @@ -141,7 +142,7 @@ int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data) if(newMode != giTegra2Vid_CurrentMode) { giTegra2Vid_CurrentMode = newMode; - Tegra2Vid_int_SetResolution( caTegra2Vid_Modes[newMode].W, caTegra2Vid_Modes[newMode].H ); + Tegra2Vid_int_SetMode( newMode ); } } ret = giTegra2Vid_CurrentMode; @@ -243,73 +244,41 @@ int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data) // // -/** - * \brief Set the LCD controller resolution - * \param W Width (aligned to 16 pixels, cipped to 1024) - * \param H Height (clipped to 768) - * \return Boolean failure - */ -int Tegra2Vid_int_SetResolution(int W, int H) +int Tegra2Vid_int_SetMode(int Mode) { - W = (W + 15) & ~0xF; - if(W <= 0 || H <= 0) { - Log_Warning("PL110", "Attempted to set invalid resolution (%ix%i)", W, H); - return 1; - } - if(W > 1024) W = 1920; - if(H > 768) H = 1080; - - gpTegra2Vid_IOMem->DCWinAPos = 0; - gpTegra2Vid_IOMem->DCWinASize = (H << 16) | W; - - if( gpTegra2Vid_Framebuffer ) { - MM_UnmapHWPages((tVAddr)gpTegra2Vid_Framebuffer, (giTegra2Vid_FramebufferSize+0xFFF)>>12); - } - giTegra2Vid_FramebufferSize = W*H*4; + const struct sTegra2_Disp_Mode *mode = &caTegra2Vid_Modes[Mode]; + int w = mode->W, h = mode->H; // Horizontal/Vertical Active + *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_FRONT_PORCH_0) = (mode->VFP << 16) | mode->HFP; + *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_SYNC_WIDTH_0) = (mode->HS << 16) | mode->HS; + *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_BACK_PORCH_0) = (mode->VBP << 16) | mode->HBP; + *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_ACTIVE_0) = (mode->H << 16) | mode->W; - gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA( (giTegra2Vid_FramebufferSize+0xFFF)>>12, 32, &gTegra2Vid_FramebufferPhys ); - gpTegra2Vid_IOMem->LCDUPBase = gTegra2Vid_FramebufferPhys; - gpTegra2Vid_IOMem->LCDLPBase = 0; + *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0; + *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (mode->H << 16) | mode->W; + *(Uint8*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12; // Could be 13 (BGR/RGB) + *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (mode->H << 16) | mode->W; - // Power on, BGR mode, ???, ???, enabled - Uint32 controlWord = (1 << 11)|(1 << 8)|(1 << 5)|(5 << 1)|1; - // According to qemu, the Versatile version has these two the wrong - // way around - if( gbTegra2Vid_IsVersatile ) - { - gpTegra2Vid_IOMem->LCDIMSC = controlWord; // Actually LCDControl - gpTegra2Vid_IOMem->LCDControl = 0; // Actually LCDIMSC - } - else + if( !gpTegra2Vid_Framebuffer || w*h*4 != giTegra2Vid_FramebufferSize ) { - gpTegra2Vid_IOMem->LCDIMSC = 0; - gpTegra2Vid_IOMem->LCDControl = controlWord; - } - - giTegra2Vid_Width = W; - giTegra2Vid_Height = H; + if( gpTegra2Vid_Framebuffer ) + { + // TODO: Free framebuffer for reallocation + } - // Update the DrvUtil buffer info - gTegra2Vid_DrvUtil_BufInfo.Framebuffer = gpTegra2Vid_Framebuffer; - gTegra2Vid_DrvUtil_BufInfo.Pitch = W * 4; - gTegra2Vid_DrvUtil_BufInfo.Width = W; - gTegra2Vid_DrvUtil_BufInfo.Height = H; - gTegra2Vid_DrvUtil_BufInfo.Depth = 32; - - return 0; -} + giTegra2Vid_FramebufferSize = w*h*4; -int Tegra2_int_SetMode(int Mode) -{ - *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_FRONT_PORTCH_0) = (gaTegra2Modes[Mode].VFP << 16) | gaTegra2Modes[Mode].HFP; - *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_SYNC_WIDTH_0) = (gaTegra2Modes[Mode].HS << 16) | gaTegra2Modes[Mode].HS; - *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_BACK_PORTCH_0) = (gaTegra2Modes[Mode].VBP << 16) | gaTegra2Modes[Mode].HBP; - *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_ACTIVE_0) = (gaTegra2Modes[Mode].VA << 16) | gaTegra2Modes[Mode].HA; - - *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0; - *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (gaTegra2Modes[Mode].VA << 16) | gaTegra2Modes[Mode].HA; - *(Uint8*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12; // Could be 13 (BGR/RGB) - *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (gaTegra2Modes[Mode].VA << 16) | gaTegra2Modes[Mode].HA; + gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA( + (giTegra2Vid_FramebufferSize + PAGE_SIZE-1) / PAGE_SIZE, + 32, + &gTegra2Vid_FramebufferPhys + ); + // TODO: Catch allocation failures + + // Tell hardware + *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_START_ADDR_0) = gTegra2Vid_FramebufferPhys; + *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_V_OFFSET_0) = 0; // Y offset + *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_H_OFFSET_0) = 0; // X offset + } return 0; } diff --git a/Modules/Display/Tegra2/tegra2.h b/Modules/Display/Tegra2/tegra2.h index 701ea7ee..b05ca8c1 100644 --- a/Modules/Display/Tegra2/tegra2.h +++ b/Modules/Display/Tegra2/tegra2.h @@ -8,6 +8,24 @@ #ifndef _TEGRA2_DISP_H_ #define _TEGRA2_DISP_H_ +#define TEGRA2VID_BASE 0x54200000 // 0x40000 Large (256 KB) + +const struct sTegra2_Disp_Mode +{ + Uint16 W, H; + Uint16 HFP, VFP; + Uint16 HS, VS; + Uint16 HBP, VBP; +} caTegra2Vid_Modes[] = { + // TODO: VESA timings + {720, 487, 16,33, 63, 33, 59, 133}, // NTSC 2 + {720, 576, 12,33, 63, 33, 69, 193}, // PAL 2 (VFP shown as 2/33, used 33) + {720, 483, 16, 6, 63, 6, 59, 30}, // 480p + {1280, 720, 70, 5, 804, 6, 220, 20}, // 720p + {1920,1080, 44, 4, 884, 5, 148, 36}, // 1080p + // TODO: Can all but HA/VA be constant and those select the resolution? +}; +const int ciTegra2Vid_ModeCount = sizeof(caTegra2Vid_Modes)/sizeof(caTegra2Vid_Modes[0]); enum eTegra2_Disp_Regs { @@ -16,7 +34,7 @@ enum eTegra2_Disp_Regs DC_DISP_DISP_WIN_OPTIONS_0, DC_DISP_MEM_HIGH_PRIORITY_0, DC_DISP_MEM_HIGH_PRIORITY_TIMER_0, - DC_DISP_DISP_TIMING_OPTIONS_0 + DC_DISP_DISP_TIMING_OPTIONS_0, DC_DISP_REF_TO_SYNC_0, DC_DISP_SYNC_WIDTH_0, DC_DISP_BACK_PORCH_0, @@ -24,7 +42,32 @@ enum eTegra2_Disp_Regs DC_DISP_FRONT_PORCH_0, DC_DISP_H_PULSE0_CONTROL_0, -} + + DC_WINC_A_COLOR_PALETTE_0 = 0x500, + DC_WINC_A_PALETTE_COLOR_EXT_0 = 0x600, + DC_WIN_A_WIN_OPTIONS_0 = 0x700, + DC_WIN_A_BYTE_SWAP_0, + DC_WIN_A_BUFFER_CONTROL_0, + DC_WIN_A_COLOR_DEPTH_0, + DC_WIN_A_POSITION_0, + DC_WIN_A_SIZE_0, + DC_WIN_A_PRESCALED_SIZE_0, + DC_WIN_A_H_INITIAL_DDA_0, + DC_WIN_A_V_INITIAL_DDA_0, + DC_WIN_A_DDA_INCREMENT_0, + DC_WIN_A_LINE_STRIDE_0, + DC_WIN_A_BUF_STRIDE_0, + DC_WIN_A_BUFFER_ADDR_MODE_0, + DC_WIN_A_DV_CONTROL_0, + DC_WIN_A_BLEND_NOKEY_0, + + DC_WINBUF_A_START_ADDR_0 = 0x800, + DC_WINBUF_A_START_ADDR_NS_0, + DC_WINBUF_A_ADDR_H_OFFSET_0, + DC_WINBUF_A_ADDR_H_OFFSET_NS_0, + DC_WINBUF_A_ADDR_V_OFFSET_0, + DC_WINBUF_A_ADDR_V_OFFSET_NS_0, +}; #endif