Modules/Tegra2Vid - Got it compiling
authorJohn Hodge <[email protected]>
Tue, 10 Jan 2012 23:40:15 +0000 (07:40 +0800)
committerJohn Hodge <[email protected]>
Tue, 10 Jan 2012 23:40:15 +0000 (07:40 +0800)
Modules/Display/Tegra2/main.c
Modules/Display/Tegra2/tegra2.h

index 9f64510..493dd60 100644 (file)
@@ -13,6 +13,7 @@
 #include <api_drv_video.h>\r
 #include <lib/keyvalue.h>\r
 #include <options.h>   // ARM Arch\r
+#include "tegra2.h"\r
 \r
 #define ABS(a) ((a)>0?(a):-(a))\r
 \r
@@ -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);\r
  int   Tegra2Vid_IOCtl(tVFS_Node *node, int id, void *data);\r
 // -- Internals\r
- int   Tegra2Vid_int_SetResolution(int W, int H);\r
+ int   Tegra2Vid_int_SetMode(int Mode);\r
 \r
 // === GLOBALS ===\r
-MODULE_DEFINE(0, VERSION, PL110, Tegra2Vid_Install, NULL, NULL);\r
+MODULE_DEFINE(0, VERSION, Video_Tegra2, Tegra2Vid_Install, NULL, NULL);\r
 tDevFS_Driver  gTegra2Vid_DriverStruct = {\r
        NULL, "PL110",\r
        {\r
@@ -39,7 +40,7 @@ tDevFS_Driver gTegra2Vid_DriverStruct = {
        }\r
 };\r
 // -- Options\r
-tPAddr gTegra2Vid_PhysBase = Tegra2Vid_BASE;\r
+tPAddr gTegra2Vid_PhysBase = TEGRA2VID_BASE;\r
  int   gbTegra2Vid_IsVersatile = 1;\r
 // -- KeyVal parse rules\r
 const tKeyVal_ParseRules       gTegra2Vid_KeyValueParser = {\r
@@ -72,7 +73,7 @@ int Tegra2Vid_Install(char **Arguments)
        \r
        gpTegra2Vid_IOMem = (void*)MM_MapHWPages(gTegra2Vid_PhysBase, 1);\r
 \r
-       Tegra2Vid_int_SetResolution(caTegra2Vid_Modes[0].W, caTegra2Vid_Modes[0].H);\r
+       Tegra2Vid_int_SetMode(4);\r
 \r
        DevFS_AddDevice( &gTegra2Vid_DriverStruct );\r
 \r
@@ -141,7 +142,7 @@ int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        if(newMode != giTegra2Vid_CurrentMode)\r
                        {\r
                                giTegra2Vid_CurrentMode = newMode;\r
-                               Tegra2Vid_int_SetResolution( caTegra2Vid_Modes[newMode].W, caTegra2Vid_Modes[newMode].H );\r
+                               Tegra2Vid_int_SetMode( newMode );\r
                        }\r
                }\r
                ret = giTegra2Vid_CurrentMode;\r
@@ -243,73 +244,41 @@ int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data)
 //\r
 //\r
 \r
-/**\r
- * \brief Set the LCD controller resolution\r
- * \param W    Width (aligned to 16 pixels, cipped to 1024)\r
- * \param H    Height (clipped to 768)\r
- * \return Boolean failure\r
- */\r
-int Tegra2Vid_int_SetResolution(int W, int H)\r
+int Tegra2Vid_int_SetMode(int Mode)\r
 {\r
-       W = (W + 15) & ~0xF;\r
-       if(W <= 0 || H <= 0) {\r
-               Log_Warning("PL110", "Attempted to set invalid resolution (%ix%i)", W, H);\r
-               return 1;\r
-       }\r
-       if(W > 1024)    W = 1920;\r
-       if(H > 768)     H = 1080;\r
-\r
-       gpTegra2Vid_IOMem->DCWinAPos = 0;\r
-       gpTegra2Vid_IOMem->DCWinASize = (H << 16) | W;\r
-\r
-       if( gpTegra2Vid_Framebuffer ) {\r
-               MM_UnmapHWPages((tVAddr)gpTegra2Vid_Framebuffer, (giTegra2Vid_FramebufferSize+0xFFF)>>12);\r
-       }\r
-       giTegra2Vid_FramebufferSize = W*H*4;\r
+       const struct sTegra2_Disp_Mode  *mode = &caTegra2Vid_Modes[Mode];\r
+        int    w = mode->W, h = mode->H;       // Horizontal/Vertical Active\r
+       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_FRONT_PORCH_0) = (mode->VFP << 16) | mode->HFP; \r
+       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_SYNC_WIDTH_0)  = (mode->HS << 16)  | mode->HS;\r
+       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_BACK_PORCH_0)  = (mode->VBP << 16) | mode->HBP;\r
+       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_ACTIVE_0) = (mode->H << 16)   | mode->W;\r
 \r
-       gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA( (giTegra2Vid_FramebufferSize+0xFFF)>>12, 32, &gTegra2Vid_FramebufferPhys );\r
-       gpTegra2Vid_IOMem->LCDUPBase = gTegra2Vid_FramebufferPhys;\r
-       gpTegra2Vid_IOMem->LCDLPBase = 0;\r
+       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0;\r
+       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (mode->H << 16) | mode->W;\r
+       *(Uint8*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12;     // Could be 13 (BGR/RGB)\r
+       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (mode->H << 16) | mode->W;\r
 \r
-       // Power on, BGR mode, ???, ???, enabled\r
-       Uint32  controlWord = (1 << 11)|(1 << 8)|(1 << 5)|(5 << 1)|1;\r
-       // According to qemu, the Versatile version has these two the wrong\r
-       // way around\r
-       if( gbTegra2Vid_IsVersatile )\r
-       {\r
-               gpTegra2Vid_IOMem->LCDIMSC = controlWord;       // Actually LCDControl\r
-               gpTegra2Vid_IOMem->LCDControl = 0;      // Actually LCDIMSC\r
-       }\r
-       else\r
+       if( !gpTegra2Vid_Framebuffer || w*h*4 != giTegra2Vid_FramebufferSize )\r
        {\r
-               gpTegra2Vid_IOMem->LCDIMSC = 0;\r
-               gpTegra2Vid_IOMem->LCDControl = controlWord;\r
-       }\r
-\r
-       giTegra2Vid_Width = W;\r
-       giTegra2Vid_Height = H;\r
+               if( gpTegra2Vid_Framebuffer )\r
+               {\r
+                       // TODO: Free framebuffer for reallocation\r
+               }\r
 \r
-       // Update the DrvUtil buffer info\r
-       gTegra2Vid_DrvUtil_BufInfo.Framebuffer = gpTegra2Vid_Framebuffer;\r
-       gTegra2Vid_DrvUtil_BufInfo.Pitch = W * 4;\r
-       gTegra2Vid_DrvUtil_BufInfo.Width = W;\r
-       gTegra2Vid_DrvUtil_BufInfo.Height = H;\r
-       gTegra2Vid_DrvUtil_BufInfo.Depth = 32;\r
-       \r
-       return 0;\r
-}\r
+               giTegra2Vid_FramebufferSize = w*h*4;            \r
 \r
-int Tegra2_int_SetMode(int Mode)\r
-{\r
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_FRONT_PORTCH_0) = (gaTegra2Modes[Mode].VFP << 16) | gaTegra2Modes[Mode].HFP; \r
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_SYNC_WIDTH_0) = (gaTegra2Modes[Mode].HS << 16) | gaTegra2Modes[Mode].HS;\r
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_BACK_PORTCH_0) = (gaTegra2Modes[Mode].VBP << 16) | gaTegra2Modes[Mode].HBP;\r
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_ACTIVE_0) = (gaTegra2Modes[Mode].VA << 16) | gaTegra2Modes[Mode].HA;\r
-\r
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0;\r
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (gaTegra2Modes[Mode].VA << 16) | gaTegra2Modes[Mode].HA;\r
-       *(Uint8*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12;     // Could be 13 (BGR/RGB)\r
-       *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (gaTegra2Modes[Mode].VA << 16) | gaTegra2Modes[Mode].HA;\r
+               gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA(\r
+                       (giTegra2Vid_FramebufferSize + PAGE_SIZE-1) / PAGE_SIZE,\r
+                       32,\r
+                       &gTegra2Vid_FramebufferPhys\r
+                       );\r
+               // TODO: Catch allocation failures\r
+               \r
+               // Tell hardware\r
+               *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_START_ADDR_0) = gTegra2Vid_FramebufferPhys;\r
+               *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_V_OFFSET_0) = 0;        // Y offset\r
+               *(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_H_OFFSET_0) = 0;        // X offset\r
+       }\r
 \r
        return 0;\r
 }\r
index 701ea7e..b05ca8c 100644 (file)
@@ -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
 

UCC git Repository :: git.ucc.asn.au