-/**\r
- * main.c\r
- * - Driver core\r
- */\r
-#define DEBUG 0\r
-#define VERSION ((0<<8)|10)\r
-#include <acess.h>\r
-#include <errno.h>\r
-#include <modules.h>\r
-#include <vfs.h>\r
-#include <fs_devfs.h>\r
-#include <drv_pci.h>\r
-#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
-// === PROTOTYPES ===\r
-// Driver\r
- int Tegra2Vid_Install(char **Arguments);\r
-void Tegra2Vid_Uninstall();\r
-// Internal\r
-// Filesystem\r
-size_t Tegra2Vid_Read(tVFS_Node *node, off_t off, size_t len, void *buffer);\r
-size_t Tegra2Vid_Write(tVFS_Node *node, off_t off, size_t len, const void *buffer);\r
- int Tegra2Vid_IOCtl(tVFS_Node *node, int id, void *data);\r
-// -- Internals\r
- int Tegra2Vid_int_SetMode(int Mode);\r
-\r
-// === GLOBALS ===\r
-MODULE_DEFINE(0, VERSION, Tegra2Vid, Tegra2Vid_Install, NULL, NULL);\r
-tVFS_NodeType gTegra2Vid_NodeType = {\r
- .Read = Tegra2Vid_Read,\r
- .Write = Tegra2Vid_Write,\r
- .IOCtl = Tegra2Vid_IOCtl\r
- };\r
-tDevFS_Driver gTegra2Vid_DriverStruct = {\r
- NULL, "Tegra2Vid",\r
- {.Type = &gTegra2Vid_NodeType}\r
-};\r
-// -- Options\r
-tPAddr gTegra2Vid_PhysBase = TEGRA2VID_BASE;\r
- int gbTegra2Vid_IsVersatile = 1;\r
-// -- KeyVal parse rules\r
-const tKeyVal_ParseRules gTegra2Vid_KeyValueParser = {\r
- NULL,\r
- {\r
- {"Base", "P", &gTegra2Vid_PhysBase},\r
- {NULL, NULL, NULL}\r
- }\r
-};\r
-// -- Driver state\r
- int giTegra2Vid_CurrentMode = 0;\r
- int giTegra2Vid_BufferMode;\r
-size_t giTegra2Vid_FramebufferSize;\r
-Uint32 *gpTegra2Vid_IOMem;\r
-tPAddr gTegra2Vid_FramebufferPhys;\r
-void *gpTegra2Vid_Framebuffer;\r
-// -- Misc\r
-tDrvUtil_Video_BufInfo gTegra2Vid_DrvUtil_BufInfo;\r
-tVideo_IOCtl_Pos gTegra2Vid_CursorPos;\r
-\r
-// === CODE ===\r
-/**\r
- */\r
-int Tegra2Vid_Install(char **Arguments)\r
-{\r
- return MODULE_ERR_NOTNEEDED;\r
-// KeyVal_Parse(&gTegra2Vid_KeyValueParser, Arguments);\r
-\r
- gpTegra2Vid_IOMem = (void*)MM_MapHWPages(gTegra2Vid_PhysBase, 256/4);\r
- {\r
- Log_Debug("Tegra2Vid", "Display CMD Registers");\r
- for( int i = 0x000; i <= 0x01A; i ++ )\r
- Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);\r
- for( int i = 0x028; i <= 0x043; i ++ )\r
- Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);\r
- Log_Debug("Tegra2Vid", "Display COM Registers");\r
- for( int i = 0x300; i <= 0x329; i ++ )\r
- Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);\r
- Log_Debug("Tegra2Vid", "Display DISP Registers");\r
- for( int i = 0x400; i <= 0x446; i ++ )\r
- Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);\r
- for( int i = 0x480; i <= 0x484; i ++ )\r
- Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);\r
- for( int i = 0x4C0; i <= 0x4C1; i ++ )\r
- Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);\r
-\r
- Log_Debug("Tegra2Vid", "WINC_A Registers");\r
- for( int i = 0x700; i <= 0x714; i ++ )\r
- Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);\r
- Log_Debug("Tegra2Vid", "WINBUF_A");\r
- for( int i = 0x800; i <= 0x80A; i ++ )\r
- Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);\r
- }\r
-// return 1;\r
-\r
- // HACK!!!\r
-#if 0\r
- {\r
- int w = 1680, h = 1050;\r
- gpTegra2Vid_IOMem[DC_DISP_DISP_ACTIVE_0] = (h << 16) | w;\r
- gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0] = (h << 16) | w;\r
- gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = (h << 16) | w;\r
- }\r
-#endif\r
-\r
- giTegra2Vid_FramebufferSize =\r
- (gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0]&0xFFFF)\r
- *(gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0]>>16)*4;\r
-\r
- Log_Debug("Tegra2Vid", "giTegra2Vid_FramebufferSize = 0x%x", giTegra2Vid_FramebufferSize);\r
- gpTegra2Vid_Framebuffer = (void*)MM_MapHWPages(\r
- gpTegra2Vid_IOMem[DC_WINBUF_A_START_ADDR_0],\r
- (giTegra2Vid_FramebufferSize+PAGE_SIZE-1)/PAGE_SIZE\r
- );\r
- memset(gpTegra2Vid_Framebuffer, 0xFF, 0x1000);\r
-\r
-// gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] &= ~0x40;\r
-// gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)\r
- gTegra2Vid_DrvUtil_BufInfo.Width = 1024;\r
- gTegra2Vid_DrvUtil_BufInfo.Height = 768;\r
- gTegra2Vid_DrvUtil_BufInfo.Pitch = 1024*4;\r
- gTegra2Vid_DrvUtil_BufInfo.Depth = 32;\r
- gTegra2Vid_DrvUtil_BufInfo.Framebuffer = gpTegra2Vid_Framebuffer;\r
-\r
-\r
-// Tegra2Vid_int_SetMode(4);\r
-\r
- DevFS_AddDevice( &gTegra2Vid_DriverStruct );\r
-\r
- return 0;\r
-}\r
-\r
-/**\r
- * \brief Clean up resources for driver unloading\r
- */\r
-void Tegra2Vid_Uninstall()\r
-{\r
-}\r
-\r
-/**\r
- * \brief Read from the framebuffer\r
- */\r
-size_t Tegra2Vid_Read(tVFS_Node *node, off_t off, size_t len, void *buffer)\r
-{\r
- return 0;\r
-}\r
-\r
-/**\r
- * \brief Write to the framebuffer\r
- */\r
-size_t Tegra2Vid_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)\r
-{\r
- gTegra2Vid_DrvUtil_BufInfo.BufferFormat = giTegra2Vid_BufferMode;\r
- return DrvUtil_Video_WriteLFB(&gTegra2Vid_DrvUtil_BufInfo, Offset, Length, Buffer);\r
-}\r
-\r
-const char *csaTegra2Vid_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};\r
-\r
-/**\r
- * \brief Handle messages to the device\r
- */\r
-int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
-{\r
- int ret = -2;\r
- ENTER("pNode iID pData", Node, ID, Data);\r
- \r
- switch(ID)\r
- {\r
- BASE_IOCTLS(DRV_TYPE_VIDEO, "PL110", VERSION, csaTegra2Vid_IOCtls);\r
-\r
- case VIDEO_IOCTL_SETBUFFORMAT:\r
- DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );\r
- ret = giTegra2Vid_BufferMode;\r
- if(Data) giTegra2Vid_BufferMode = *(int*)Data;\r
- if(gTegra2Vid_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)\r
- DrvUtil_Video_SetCursor( &gTegra2Vid_DrvUtil_BufInfo, &gDrvUtil_TextModeCursor );\r
- break;\r
- \r
- case VIDEO_IOCTL_GETSETMODE:\r
- if(Data)\r
- {\r
- int newMode;\r
- \r
- if( !CheckMem(Data, sizeof(int)) )\r
- LEAVE_RET('i', -1);\r
- \r
- newMode = *(int*)Data;\r
- \r
- if(newMode < 0 || newMode >= ciTegra2Vid_ModeCount)\r
- LEAVE_RET('i', -1);\r
-\r
- if(newMode != giTegra2Vid_CurrentMode)\r
- {\r
- giTegra2Vid_CurrentMode = newMode;\r
- Tegra2Vid_int_SetMode( newMode );\r
- }\r
- }\r
- ret = giTegra2Vid_CurrentMode;\r
- break;\r
- \r
- case VIDEO_IOCTL_FINDMODE:\r
- {\r
- tVideo_IOCtl_Mode *mode = Data;\r
- int closest=0, closestArea, reqArea = 0;\r
- if(!Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Mode)))\r
- LEAVE_RET('i', -1);\r
- if( mode->bpp != 32 )\r
- LEAVE_RET('i', 0);\r
- if( mode->flags != 0 )\r
- LEAVE_RET('i', 0);\r
-\r
- ret = 0;\r
-\r
- for( int i = 0; i < ciTegra2Vid_ModeCount; i ++ )\r
- {\r
- int area;\r
- if(mode->width == caTegra2Vid_Modes[i].W && mode->height == caTegra2Vid_Modes[i].H) {\r
- mode->id = i;\r
- ret = 1;\r
- break;\r
- }\r
- \r
- area = caTegra2Vid_Modes[i].W * caTegra2Vid_Modes[i].H;\r
- if(!reqArea) {\r
- reqArea = mode->width * mode->height;\r
- closest = i;\r
- closestArea = area;\r
- }\r
- else if( ABS(area - reqArea) < ABS(closestArea - reqArea) ) {\r
- closest = i;\r
- closestArea = area;\r
- }\r
- }\r
- \r
- if( ret == 0 )\r
- {\r
- mode->id = closest;\r
- ret = 1;\r
- }\r
- mode->width = caTegra2Vid_Modes[mode->id].W;\r
- mode->height = caTegra2Vid_Modes[mode->id].H;\r
- break;\r
- }\r
- \r
- case VIDEO_IOCTL_MODEINFO:\r
- {\r
- tVideo_IOCtl_Mode *mode = Data;\r
- if(!Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Mode)))\r
- LEAVE_RET('i', -1);\r
- if(mode->id < 0 || mode->id >= ciTegra2Vid_ModeCount)\r
- LEAVE_RET('i', 0);\r
- \r
-\r
- mode->bpp = 32;\r
- mode->flags = 0;\r
- mode->width = caTegra2Vid_Modes[mode->id].W;\r
- mode->height = caTegra2Vid_Modes[mode->id].H;\r
-\r
- ret = 1;\r
- break;\r
- }\r
- \r
- case VIDEO_IOCTL_SETCURSOR:\r
- if( !Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Pos)) )\r
- LEAVE_RET('i', -1);\r
-\r
- DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );\r
- \r
- gTegra2Vid_CursorPos = *(tVideo_IOCtl_Pos*)Data;\r
- if(gTegra2Vid_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)\r
- DrvUtil_Video_DrawCursor(\r
- &gTegra2Vid_DrvUtil_BufInfo,\r
- gTegra2Vid_CursorPos.x*giVT_CharWidth,\r
- gTegra2Vid_CursorPos.y*giVT_CharHeight\r
- );\r
- else\r
- DrvUtil_Video_DrawCursor(\r
- &gTegra2Vid_DrvUtil_BufInfo,\r
- gTegra2Vid_CursorPos.x,\r
- gTegra2Vid_CursorPos.y\r
- );\r
- break;\r
- \r
- default:\r
- LEAVE('i', -2);\r
- return -2;\r
- }\r
- \r
- LEAVE('i', ret);\r
- return ret;\r
-}\r
-\r
-//\r
-//\r
-//\r
-\r
-int Tegra2Vid_int_SetMode(int Mode)\r
-{\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
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0;\r
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (h << 16) | w;\r
- *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_COLOR_CONTROL_0) = 0x8; // BASE888\r
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12; // Could be 13 (BGR/RGB)\r
- *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (h << 16) | w;\r
-\r
- Log_Debug("Tegra2Vid", "Mode %i (%ix%i) selected", Mode, w, h);\r
-\r
- if( !gpTegra2Vid_Framebuffer || w*h*4 != giTegra2Vid_FramebufferSize )\r
- {\r
- if( gpTegra2Vid_Framebuffer )\r
- {\r
- // TODO: Free framebuffer for reallocation\r
- }\r
-\r
- giTegra2Vid_FramebufferSize = w*h*4; \r
-\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
- Log_Debug("Tegra2Vid", "0x%x byte framebuffer at %p (%P phys)",\r
- giTegra2Vid_FramebufferSize,\r
- gpTegra2Vid_Framebuffer,\r
- gTegra2Vid_FramebufferPhys\r
- );\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
+/**
+ * main.c
+ * - Driver core
+ */
+#define DEBUG 0
+#define VERSION ((0<<8)|10)
+#include <acess.h>
+#include <errno.h>
+#include <modules.h>
+#include <vfs.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include <api_drv_video.h>
+#include <lib/keyvalue.h>
+#include <options.h> // ARM Arch
+#include "tegra2.h"
+
+#define ABS(a) ((a)>0?(a):-(a))
+
+// === PROTOTYPES ===
+// Driver
+ int Tegra2Vid_Install(char **Arguments);
+void Tegra2Vid_Uninstall();
+// Internal
+// Filesystem
+size_t Tegra2Vid_Read(tVFS_Node *node, off_t off, size_t len, void *buffer);
+size_t Tegra2Vid_Write(tVFS_Node *node, off_t off, size_t len, const void *buffer);
+ int Tegra2Vid_IOCtl(tVFS_Node *node, int id, void *data);
+// -- Internals
+ int Tegra2Vid_int_SetMode(int Mode);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, Tegra2Vid, Tegra2Vid_Install, NULL, NULL);
+tVFS_NodeType gTegra2Vid_NodeType = {
+ .Read = Tegra2Vid_Read,
+ .Write = Tegra2Vid_Write,
+ .IOCtl = Tegra2Vid_IOCtl
+ };
+tDevFS_Driver gTegra2Vid_DriverStruct = {
+ NULL, "Tegra2Vid",
+ {.Type = &gTegra2Vid_NodeType}
+};
+// -- Options
+tPAddr gTegra2Vid_PhysBase = TEGRA2VID_BASE;
+ int gbTegra2Vid_IsVersatile = 1;
+// -- KeyVal parse rules
+const tKeyVal_ParseRules gTegra2Vid_KeyValueParser = {
+ NULL,
+ {
+ {"Base", "P", &gTegra2Vid_PhysBase},
+ {NULL, NULL, NULL}
+ }
+};
+// -- Driver state
+ int giTegra2Vid_CurrentMode = 0;
+ int giTegra2Vid_BufferMode;
+size_t giTegra2Vid_FramebufferSize;
+Uint32 *gpTegra2Vid_IOMem;
+tPAddr gTegra2Vid_FramebufferPhys;
+void *gpTegra2Vid_Framebuffer;
+// -- Misc
+tDrvUtil_Video_BufInfo gTegra2Vid_DrvUtil_BufInfo;
+tVideo_IOCtl_Pos gTegra2Vid_CursorPos;
+
+// === CODE ===
+/**
+ */
+int Tegra2Vid_Install(char **Arguments)
+{
+// return MODULE_ERR_NOTNEEDED;
+// KeyVal_Parse(&gTegra2Vid_KeyValueParser, Arguments);
+
+ gpTegra2Vid_IOMem = (void*)MM_MapHWPages(gTegra2Vid_PhysBase, 256/4);
+ #if 0
+ {
+ Log_Debug("Tegra2Vid", "Display CMD Registers");
+ for( int i = 0x000; i <= 0x01A; i ++ )
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+ for( int i = 0x028; i <= 0x043; i ++ )
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+ Log_Debug("Tegra2Vid", "Display COM Registers");
+ for( int i = 0x300; i <= 0x329; i ++ )
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+ Log_Debug("Tegra2Vid", "Display DISP Registers");
+ for( int i = 0x400; i <= 0x446; i ++ )
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+ for( int i = 0x480; i <= 0x484; i ++ )
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+ for( int i = 0x4C0; i <= 0x4C1; i ++ )
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+
+ Log_Debug("Tegra2Vid", "WINC_A Registers");
+ for( int i = 0x700; i <= 0x714; i ++ )
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+ Log_Debug("Tegra2Vid", "WINBUF_A");
+ for( int i = 0x800; i <= 0x80A; i ++ )
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x", i, gpTegra2Vid_IOMem[i]);
+ }
+ #endif
+// return 1;
+
+ // HACK!!!
+#if 0
+ {
+ int w = 1680, h = 1050;
+ gpTegra2Vid_IOMem[DC_DISP_DISP_ACTIVE_0] = (h << 16) | w;
+ gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0] = (h << 16) | w;
+ gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = (h << 16) | w;
+ }
+#endif
+
+ giTegra2Vid_FramebufferSize =
+ (gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0]&0xFFFF)
+ *(gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0]>>16)*4;
+
+ Log_Debug("Tegra2Vid", "giTegra2Vid_FramebufferSize = 0x%x", giTegra2Vid_FramebufferSize);
+ gpTegra2Vid_Framebuffer = (void*)MM_MapHWPages(
+ gpTegra2Vid_IOMem[DC_WINBUF_A_START_ADDR_0],
+ (giTegra2Vid_FramebufferSize+PAGE_SIZE-1)/PAGE_SIZE
+ );
+ memset(gpTegra2Vid_Framebuffer, 0xFF, 0x1000);
+
+// gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] &= ~0x40;
+ gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)
+ gTegra2Vid_DrvUtil_BufInfo.Width = 1024;
+ gTegra2Vid_DrvUtil_BufInfo.Height = 768;
+ gTegra2Vid_DrvUtil_BufInfo.Pitch = 1024*4;
+ gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
+ gTegra2Vid_DrvUtil_BufInfo.Framebuffer = gpTegra2Vid_Framebuffer;
+
+
+// Tegra2Vid_int_SetMode(4);
+
+ DevFS_AddDevice( &gTegra2Vid_DriverStruct );
+
+ return 0;
+}
+
+/**
+ * \brief Clean up resources for driver unloading
+ */
+void Tegra2Vid_Uninstall()
+{
+}
+
+/**
+ * \brief Read from the framebuffer
+ */
+size_t Tegra2Vid_Read(tVFS_Node *node, off_t off, size_t len, void *buffer)
+{
+ return 0;
+}
+
+/**
+ * \brief Write to the framebuffer
+ */
+size_t Tegra2Vid_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+{
+ gTegra2Vid_DrvUtil_BufInfo.BufferFormat = giTegra2Vid_BufferMode;
+ return DrvUtil_Video_WriteLFB(&gTegra2Vid_DrvUtil_BufInfo, Offset, Length, Buffer);
+}
+
+const char *csaTegra2Vid_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
+
+/**
+ * \brief Handle messages to the device
+ */
+int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+ int ret = -2;
+ ENTER("pNode iID pData", Node, ID, Data);
+
+ switch(ID)
+ {
+ BASE_IOCTLS(DRV_TYPE_VIDEO, "PL110", VERSION, csaTegra2Vid_IOCtls);
+
+ case VIDEO_IOCTL_SETBUFFORMAT:
+ DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );
+ ret = giTegra2Vid_BufferMode;
+ if(Data) giTegra2Vid_BufferMode = *(int*)Data;
+ if(gTegra2Vid_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)
+ DrvUtil_Video_SetCursor( &gTegra2Vid_DrvUtil_BufInfo, &gDrvUtil_TextModeCursor );
+ break;
+
+ case VIDEO_IOCTL_GETSETMODE:
+ if(Data)
+ {
+ int newMode;
+
+ if( !CheckMem(Data, sizeof(int)) )
+ LEAVE_RET('i', -1);
+
+ newMode = *(int*)Data;
+
+ if(newMode < 0 || newMode >= ciTegra2Vid_ModeCount)
+ LEAVE_RET('i', -1);
+
+ if(newMode != giTegra2Vid_CurrentMode)
+ {
+ giTegra2Vid_CurrentMode = newMode;
+ Tegra2Vid_int_SetMode( newMode );
+ }
+ }
+ ret = giTegra2Vid_CurrentMode;
+ break;
+
+ case VIDEO_IOCTL_FINDMODE:
+ {
+ tVideo_IOCtl_Mode *mode = Data;
+ int closest=0, closestArea, reqArea = 0;
+ if(!Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Mode)))
+ LEAVE_RET('i', -1);
+ if( mode->bpp != 32 )
+ LEAVE_RET('i', 0);
+ if( mode->flags != 0 )
+ LEAVE_RET('i', 0);
+
+ // DEBUG!!!
+ mode->width = 1024;
+ mode->height = 768;
+ break;
+
+ ret = 0;
+
+ for( int i = 0; i < ciTegra2Vid_ModeCount; i ++ )
+ {
+ int area;
+ if(mode->width == caTegra2Vid_Modes[i].W && mode->height == caTegra2Vid_Modes[i].H) {
+ mode->id = i;
+ ret = 1;
+ break;
+ }
+
+ area = caTegra2Vid_Modes[i].W * caTegra2Vid_Modes[i].H;
+ if(!reqArea) {
+ reqArea = mode->width * mode->height;
+ closest = i;
+ closestArea = area;
+ }
+ else if( ABS(area - reqArea) < ABS(closestArea - reqArea) ) {
+ closest = i;
+ closestArea = area;
+ }
+ }
+
+ if( ret == 0 )
+ {
+ mode->id = closest;
+ ret = 1;
+ }
+ mode->width = caTegra2Vid_Modes[mode->id].W;
+ mode->height = caTegra2Vid_Modes[mode->id].H;
+ break;
+ }
+
+ case VIDEO_IOCTL_MODEINFO:
+ {
+ tVideo_IOCtl_Mode *mode = Data;
+ if(!Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Mode)))
+ LEAVE_RET('i', -1);
+ if(mode->id < 0 || mode->id >= ciTegra2Vid_ModeCount)
+ LEAVE_RET('i', 0);
+
+
+ mode->bpp = 32;
+ mode->flags = 0;
+ mode->width = caTegra2Vid_Modes[mode->id].W;
+ mode->height = caTegra2Vid_Modes[mode->id].H;
+
+ ret = 1;
+ break;
+ }
+
+ case VIDEO_IOCTL_SETCURSOR:
+ if( !Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Pos)) )
+ LEAVE_RET('i', -1);
+
+ DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );
+
+ gTegra2Vid_CursorPos = *(tVideo_IOCtl_Pos*)Data;
+ if(gTegra2Vid_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)
+ DrvUtil_Video_DrawCursor(
+ &gTegra2Vid_DrvUtil_BufInfo,
+ gTegra2Vid_CursorPos.x*giVT_CharWidth,
+ gTegra2Vid_CursorPos.y*giVT_CharHeight
+ );
+ else
+ DrvUtil_Video_DrawCursor(
+ &gTegra2Vid_DrvUtil_BufInfo,
+ gTegra2Vid_CursorPos.x,
+ gTegra2Vid_CursorPos.y
+ );
+ break;
+
+ default:
+ LEAVE('i', -2);
+ return -2;
+ }
+
+ LEAVE('i', ret);
+ return ret;
+}
+
+//
+//
+//
+
+int Tegra2Vid_int_SetMode(int Mode)
+{
+ 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;
+
+ *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0;
+ *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (h << 16) | w;
+ *(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_COLOR_CONTROL_0) = 0x8; // BASE888
+ *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12; // Could be 13 (BGR/RGB)
+ *(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (h << 16) | w;
+
+ Log_Debug("Tegra2Vid", "Mode %i (%ix%i) selected", Mode, w, h);
+
+ if( !gpTegra2Vid_Framebuffer || w*h*4 != giTegra2Vid_FramebufferSize )
+ {
+ if( gpTegra2Vid_Framebuffer )
+ {
+ // TODO: Free framebuffer for reallocation
+ }
+
+ giTegra2Vid_FramebufferSize = w*h*4;
+
+ gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA(
+ (giTegra2Vid_FramebufferSize + PAGE_SIZE-1) / PAGE_SIZE,
+ 32,
+ &gTegra2Vid_FramebufferPhys
+ );
+ // TODO: Catch allocation failures
+ Log_Debug("Tegra2Vid", "0x%x byte framebuffer at %p (%P phys)",
+ giTegra2Vid_FramebufferSize,
+ gpTegra2Vid_Framebuffer,
+ gTegra2Vid_FramebufferPhys
+ );
+
+ // 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;
+}
--- /dev/null
+/*
+ * Acess2 RealTek 8169 Gigabit Network Controller Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * rtl8169.c
+ * - Driver source
+ */
+#define DEBUG 0
+#define VERSION 0x001
+#include <acess.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include <api_drv_network.h>
+#include "rtl8169.h"
+
+#define N_RX_DESCS 128
+#define N_TX_DESCS (256-N_RX_DESCS) // 256 * 16 = 4096 (1 page)
+#define RX_BUF_SIZE 1024 // Most packets will fit in one buffer
+
+#define INT_SYSERR (1 << 15) // System Error
+#define INT_TIMEOUT (1 << 14) // Timer fire (TCTR reg)
+#define INT_LINKCHANGE (1 << 5)
+#define INT_TXERR (1 << 3)
+#define INT_TXOK (1 << 2)
+#define INT_RXERR (1 << 1)
+#define INT_RXOK (1 << 0)
+
+enum eRegisters
+{
+ REG_INTMASK = 0x3C,
+ REG_INSSTATE = 0x3E,
+ REG_TXC = 0x40,
+ REG_RXC = 0x44,
+}
+
+// === PROTOTYPES ===
+ int RTL8169_Initialise(char **Arguments);
+void RTL8169_Cleanup(void);
+void RTL8169_InterruptHandler(int IRQ, void *CardPtr);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, RTL8169, RTL8169_Initialise, RTL8169_Cleanup, NULL);
+ int giRTL8169_CardCount;
+tCard *gaRTL8169_Cards;
+
+// === CODE ===
+int RTL8169_Initialise(char **Arguments)
+{
+ const Uint16 vendor_id = 0x10EC;
+ const Uint16 device_id = 0x8129; // 8169 = 0x8129 PCI?
+ giRTL8169_CardCount = PCI_CountDevices(vendor_id, device_id);
+ if( !giRTL8169_CardCount ) return MODULE_ERR_NOTNEEDED;
+
+ // Allocate card structures
+ gaRTL8169_Cards = malloc( sizeof(tCard) * giRTL8169_CardCount );
+
+ // Initialise devices
+ for( int id = -1, int i = 0 ; (id = PCI_GetDevice(vendor_id, device_id, id)) != -1; i ++ )
+ {
+ tCard *card = &gaRTL8169_Cards[i];
+ card->PCIId = id;
+
+ card->IOAddr = PCI_GetBAR(id, 0);
+ if( !(card->IOAddr & 1) ) {
+ // Invalid IO address
+ Log_Warning("RTL8169", "Card %i doesn't have BAR0 as an IO space", i);
+ continue;
+ }
+
+ if(card->IOAddr == 1 )
+ {
+ // Try MMIO
+ card->PMemAddr = PCI_GetBAR(id, 1);
+ if( card->PMemAddr == 0 ) {
+ Log_Warning("RTL8169", "TODO: Allocate MMIO space");
+ continue ;
+ }
+ card->MemAddr = MM_MapHWPages(card->PMemAddr, 1);
+ }
+
+ card->IRQNum = PCI_GetIRQ(card);
+ IRQ_AddHandler( card->IRQNum, RTL8169_InterruptHandler, card );
+
+ RTL8169_int_SetupCard(card);
+ }
+}
+
+void RTL8169_int_SetupCard(tCard *Card)
+{
+ // Initialise RX/TX Descs
+ // TODO: Handle non-64-bit PCI
+ Card->RXDescs = MM_AllocDMA(1, -1, &Card->RXDescsPhys);
+ Card->TXDescs = Card->RXDescs + N_RX_DESCS;
+
+ // - RX Descs - Max of 4096 bytes per packet (1 page)
+ tPAddr paddr;
+ for( int i = 0; i < N_RX_DESCS; i += 2 )
+ {
+ t8169_Desc *desc;
+
+ desc = &Card->RXDescs[i];
+ if( i % (PAGE_SIZE/RX_BUF_SIZE) == 0 )
+ Card->RXBufs[i] = MM_AllocDMA(1, 64, &paddr);
+ else
+ Card->RXBufs[i] = Card->RXBufs[i-1] + RX_BUF_SIZE;
+ desc->FrameLength = RX_BUF_SIZE;
+ desc->Flags = TXD_FLAG_OWN;
+ desc->VLANTag = 0;
+ desc->VLANFlags = 0;
+ desc->AddressLow = paddr & 0xFFFFFFFF;
+ desc->AddressHigh = paddr >> 32;
+ paddr += RX_BUF_SIZE;
+ }
+ Card->RXDescs[N_RX_DESCS-1].Flags |= TXD_FLAG_EOR;
+ // - TX Descs - Just clear
+ memset(Card->TXDescs, 0, sizeof(t8169_Desc)*N_TX_DESCS);
+ Card->TXDescs[N_TX_DESCS-1].Flags |= TXD_FLAG_EOR;
+
+ // Reset
+ _WriteB(Card, 0x37, 0x10);
+ while( _ReadB(Card, 0x37) & 0x10 )
+ ; // TODO: Timeout
+
+ // Read MAC address
+ for( int i = 0; i < 6; i ++ )
+ Card->MacAddr[i] = _ReadB(Card, i);
+
+ // Initialise
+// _WriteB(Card, 0x50, 0xC0);
+ _WriteD(Card, 0x40, 0x03000700); // TX Config
+ _WriteD(Card, 0x44, 0x0000E70F); // RX Config
+ _WriteW(Card, 0xDA, RX_BUF_SIZE-1); // Max RX Size
+ _WriteW(Card, 0xEC, 2048/32); // Max TX size (in units of 32/128 bytes)
+
+ _WriteQ(Card, 0x20, MM_GetPhysAddr( (tVAddr)Card->TXDescs ));
+// _WriteQ(Card, 0x28, MM_GetPhysAddr( (tVAddr)Card->TXHighDescs ));
+ _WriteQ(Card, 0xE4, MM_GetPhysAddr( (tVAddr)Card->RXDescs ));
+
+ _WriteW(Card, 0x3C, INT_LINKCHANGE|INT_TXOK|INT_RXOK); // Set interrupt mask
+
+ _WriteB(card, 0x37, 0x0C); // Enable
+}
+
+void RTL8169_InterruptHandler(int IRQ, void *CardPtr)
+{
+
+}
+
+// --- IO ---
+void _WriteW(tCard *Card, int Offset, Uint16 Value)
+{
+ if( Card->MemAddr )
+ ((Uint16*)Card->MemAddr)[Offset/2] = Value;
+ else
+ outw(Card->IOAddr & ~1, Offset, Value);
+}
+
+void _WriteD(tCard *Card, int Offset, Uint32 Value)
+{
+ if( Card->MemAddr )
+ ((Uint32*)Card->MemAddr)[Offset/4] = Value;
+ else
+ outl(Card->IOAddr & ~1, Offset, Value);
+}
+
+void _WriteQ(tCard *Card, int Offset, Uint64 Value)
+{
+ if( Card->MemAddr ) {
+ ((Uint32*)Card->MemAddr)[Offset/4+0] = Value;
+ ((Uint32*)Card->MemAddr)[Offset/4+1] = Value>>32;
+ }
+ else {
+ outd(Card->IOAddr & ~1, Offset, Value);
+ outd(Card->IOAddr & ~1, Offset+4, Value>>32);
+ }
+}