* - Driver core
*/
#define DEBUG 0
+#define DUMP_REGISTERS 1
#define VERSION ((0<<8)|10)
#include <acess.h>
#include <errno.h>
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);
+size_t Tegra2Vid_Read(tVFS_Node *node, off_t off, size_t len, void *buffer, Uint Flags);
+size_t Tegra2Vid_Write(tVFS_Node *node, off_t off, size_t len, const void *buffer, Uint Flags);
int Tegra2Vid_IOCtl(tVFS_Node *node, int id, void *data);
// -- Internals
int Tegra2Vid_int_SetMode(int Mode);
Uint32 *gpTegra2Vid_IOMem;
tPAddr gTegra2Vid_FramebufferPhys;
void *gpTegra2Vid_Framebuffer;
+void *gpTegra2Vid_Cursor;
// -- Misc
tDrvUtil_Video_BufInfo gTegra2Vid_DrvUtil_BufInfo;
tVideo_IOCtl_Pos gTegra2Vid_CursorPos;
// === CODE ===
+inline void _dumpreg(int i)
+{
+ Log_Debug("Tegra2Vid", "[0x%03x] = 0x%08x (%s)", i, gpTegra2Vid_IOMem[i],
+ (csaTegra2Vid_RegisterNames[i] ? csaTegra2Vid_RegisterNames[i] : "-"));
+}
+
+void Tegra2Vid_int_DumpRegisters(void)
+{
+ Log_Debug("Tegra2Vid", "Display CMD Registers");
+ for( int i = 0x000; i <= 0x01A; i ++ ) _dumpreg(i);
+ for( int i = 0x028; i <= 0x043; i ++ ) _dumpreg(i);
+ Log_Debug("Tegra2Vid", "Display COM Registers");
+ for( int i = 0x300; i <= 0x329; i ++ ) _dumpreg(i);
+ Log_Debug("Tegra2Vid", "Display DISP Registers");
+ for( int i = 0x400; i <= 0x446; i ++ ) _dumpreg(i);
+ for( int i = 0x480; i <= 0x484; i ++ ) _dumpreg(i);
+ for( int i = 0x4C0; i <= 0x4C1; i ++ ) _dumpreg(i);
+ Log_Debug("Tegra2Vid", "WINC_A Registers");
+ for( int i = 0x700; i <= 0x714; i ++ ) _dumpreg(i);
+ Log_Debug("Tegra2Vid", "WINBUF_A");
+ for( int i = 0x800; i <= 0x80A; i ++ ) _dumpreg(i);
+}
+
/**
*/
int Tegra2Vid_Install(char **Arguments)
// 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]);
- }
+
+ #if DUMP_REGISTERS
+// Tegra2Vid_int_DumpRegisters();
#endif
-// return 1;
// HACK!!!
#if 0
}
#endif
+#if 0
giTegra2Vid_FramebufferSize =
(gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0]&0xFFFF)
*(gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0]>>16)*4;
gpTegra2Vid_IOMem[DC_WINBUF_A_START_ADDR_0],
(giTegra2Vid_FramebufferSize+PAGE_SIZE-1)/PAGE_SIZE
);
- memset(gpTegra2Vid_Framebuffer, 0xFF, 0x1000);
+ Log_Debug("Tegra2Vid", "gpTegra2Vid_Framebuffer = %p", gpTegra2Vid_Framebuffer);
+ memset(gpTegra2Vid_Framebuffer, 0xFF, giTegra2Vid_FramebufferSize);
+#endif
-// gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] &= ~0x40;
+#if 0
+ gpTegra2Vid_IOMem[DC_WIN_A_WIN_OPTIONS_0] = (1 << 30);
gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)
+ gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0];
+ gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] =
+ gTegra2Vid_DrvUtil_BufInfo.Pitch =
+ 1680*4;
+ gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
+ gTegra2Vid_DrvUtil_BufInfo.Width = 1680;
+ gTegra2Vid_DrvUtil_BufInfo.Height = 1050;
+ gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
+#elif 0
+ gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 13; // Could be 13 (BGR/RGB)
+ gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] =
+ gTegra2Vid_DrvUtil_BufInfo.Pitch = 1024*4;
+ gTegra2Vid_DrvUtil_BufInfo.Depth = 32;
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;
+ gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
+#endif
+ gpTegra2Vid_Cursor = (void*)MM_AllocDMA(1, 26, NULL);
+ Log_Debug("Tegra2Vid", "gpTegra2Vid_Cursor = %p", gpTegra2Vid_Cursor);
-// Tegra2Vid_int_SetMode(4);
+ Tegra2Vid_int_SetMode(0);
DevFS_AddDevice( &gTegra2Vid_DriverStruct );
/**
* \brief Read from the framebuffer
*/
-size_t Tegra2Vid_Read(tVFS_Node *node, off_t off, size_t len, void *buffer)
+size_t Tegra2Vid_Read(tVFS_Node *node, off_t off, size_t len, void *buffer, Uint Flags)
{
return 0;
}
/**
* \brief Write to the framebuffer
*/
-size_t Tegra2Vid_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+size_t Tegra2Vid_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)
{
gTegra2Vid_DrvUtil_BufInfo.BufferFormat = giTegra2Vid_BufferMode;
return DrvUtil_Video_WriteLFB(&gTegra2Vid_DrvUtil_BufInfo, Offset, Length, Buffer);
switch(ID)
{
- BASE_IOCTLS(DRV_TYPE_VIDEO, "PL110", VERSION, csaTegra2Vid_IOCtls);
+ BASE_IOCTLS(DRV_TYPE_VIDEO, "Tegra2", VERSION, csaTegra2Vid_IOCtls);
case VIDEO_IOCTL_SETBUFFORMAT:
DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );
LEAVE_RET('i', 0);
// DEBUG!!!
- mode->width = 1024;
- mode->height = 768;
+ mode->id = 1; mode->width = 1680; mode->height = 1050;
+ mode->id = 0; mode->width = 1024; mode->height = 768;
+
+ // DEBUG!
+ for( int i = 0x800; i <= 0x80A; i ++ ) _dumpreg(i);
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) {
+ if(mode->width == caTegra2Vid_Modes[i].W
+ && mode->height == caTegra2Vid_Modes[i].H) {
mode->id = i;
ret = 1;
break;
DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );
gTegra2Vid_CursorPos = *(tVideo_IOCtl_Pos*)Data;
+ // TODO: Set DC_DISP_CURSOR_POSITION_0
+ // TODO: Set DC_DISP_CURSOR_FOREGROUND_0 etc from image?
if(gTegra2Vid_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)
DrvUtil_Video_DrawCursor(
&gTegra2Vid_DrvUtil_BufInfo,
{
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;
+ gpTegra2Vid_IOMem[DC_DISP_REF_TO_SYNC_0] = (1 << 16) | 11; // TODO: <--
+ gpTegra2Vid_IOMem[DC_DISP_SYNC_WIDTH_0] = (mode->HS << 16) | mode->HS;
+ gpTegra2Vid_IOMem[DC_DISP_BACK_PORCH_0] = (mode->VBP << 16) | mode->HBP;
+ gpTegra2Vid_IOMem[DC_DISP_DISP_ACTIVE_0] = (mode->H << 16) | mode->W;
+ gpTegra2Vid_IOMem[DC_DISP_FRONT_PORCH_0] = (mode->VFP << 16) | mode->HFP;
+
+ gpTegra2Vid_IOMem[DC_DISP_DISP_COLOR_CONTROL_0] = 0x8; // BASE888 - TODO: useful?
+ gpTegra2Vid_IOMem[DC_WIN_A_POSITION_0] = 0;
+ gpTegra2Vid_IOMem[DC_WIN_A_SIZE_0] = (h << 16) | w;
+ gpTegra2Vid_IOMem[DC_WIN_A_COLOR_DEPTH_0] = 12; // Could be 13 (BGR/RGB)
+ gpTegra2Vid_IOMem[DC_WIN_A_PRESCALED_SIZE_0] = (h << 16) | w;
+ gpTegra2Vid_IOMem[DC_WIN_A_LINE_STRIDE_0] = w * 4;
+ gpTegra2Vid_IOMem[DC_WIN_A_DV_CONTROL_0] = 0;
+
+ gpTegra2Vid_IOMem[DC_DISP_BORDER_COLOR_0] = 0x70F010;
Log_Debug("Tegra2Vid", "Mode %i (%ix%i) selected", Mode, w, h);
giTegra2Vid_FramebufferSize = w*h*4;
+ // Uses RAM I think
gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA(
(giTegra2Vid_FramebufferSize + PAGE_SIZE-1) / PAGE_SIZE,
32,
&gTegra2Vid_FramebufferPhys
);
- // TODO: Catch allocation failures
+ if( !gpTegra2Vid_Framebuffer ) {
+ Log_Error("Tegra2Vid", "Can't allocate pages for 0x%x byte framebuffer",
+ giTegra2Vid_FramebufferSize);
+ return -1;
+ }
Log_Debug("Tegra2Vid", "0x%x byte framebuffer at %p (%P phys)",
giTegra2Vid_FramebufferSize,
gpTegra2Vid_Framebuffer,
);
// 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
+ gpTegra2Vid_IOMem[DC_WINBUF_A_START_ADDR_0] = gTegra2Vid_FramebufferPhys;
+ gpTegra2Vid_IOMem[DC_WINBUF_A_ADDR_V_OFFSET_0] = 0; // Y offset
+ gpTegra2Vid_IOMem[DC_WINBUF_A_ADDR_H_OFFSET_0] = 0; // X offset
}
+ gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = WIN_A_ACT_REQ;
+ gpTegra2Vid_IOMem[DC_CMD_STATE_CONTROL_0] = GEN_ACT_REQ;
+
+ // DEBUG!
+ for( int i = 0x800; i <= 0x80A; i ++ ) _dumpreg(i);
+
return 0;
}