#include <drv_pci.h>\r
#include <api_drv_video.h>\r
#include <lib/keyvalue.h>\r
+#include <options.h> // ARM Arch\r
\r
#define ABS(a) ((a)>0?(a):-(a))\r
\r
Uint32 LCDLPCurr;\r
};\r
\r
-// === CONSTANTS ===\r
+#ifndef PL110_BASE\r
#define PL110_BASE 0x10020000 // Integrator\r
+#endif\r
\r
+// === CONSTANTS ===\r
const struct {\r
short W, H;\r
} caPL110_Modes[] = {\r
// Internal\r
// Filesystem\r
Uint64 PL110_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
-Uint64 PL110_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
+Uint64 PL110_Write(tVFS_Node *node, Uint64 off, Uint64 len, const void *buffer);\r
int PL110_IOCtl(tVFS_Node *node, int id, void *data);\r
// -- Internals\r
int PL110_int_SetResolution(int W, int H);\r
\r
// === GLOBALS ===\r
MODULE_DEFINE(0, VERSION, PL110, PL110_Install, NULL, NULL);\r
-tDevFS_Driver gPL110_DriverStruct = {\r
- NULL, "PL110",\r
- {\r
+tVFS_NodeType gPL110_DevNodeType = {\r
.Read = PL110_Read,\r
.Write = PL110_Write,\r
.IOCtl = PL110_IOCtl\r
- }\r
+ };\r
+tDevFS_Driver gPL110_DriverStruct = {\r
+ NULL, "PL110",\r
+ {.Type = &gPL110_DevNodeType}\r
};\r
// -- Options\r
tPAddr gPL110_PhysBase = PL110_BASE;\r
+ int gbPL110_IsVersatile = 1;\r
// -- KeyVal parse rules\r
const tKeyVal_ParseRules gPL110_KeyValueParser = {\r
NULL,\r
{\r
{"Base", "P", &gPL110_PhysBase},\r
+ {"IsVersatile", "i", &gbPL110_IsVersatile},\r
{NULL, NULL, NULL}\r
}\r
};\r
void *gpPL110_Framebuffer;\r
// -- Misc\r
tDrvUtil_Video_BufInfo gPL110_DrvUtil_BufInfo;\r
+tVideo_IOCtl_Pos gPL110_CursorPos;\r
\r
// === CODE ===\r
/**\r
/**\r
* \brief Write to the framebuffer\r
*/\r
-Uint64 PL110_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+Uint64 PL110_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer)\r
{\r
gPL110_DrvUtil_BufInfo.BufferFormat = giPL110_BufferMode;\r
return DrvUtil_Video_WriteLFB(&gPL110_DrvUtil_BufInfo, Offset, Length, Buffer);\r
BASE_IOCTLS(DRV_TYPE_VIDEO, "PL110", VERSION, csaPL110_IOCtls);\r
\r
case VIDEO_IOCTL_SETBUFFORMAT:\r
+ DrvUtil_Video_RemoveCursor( &gPL110_DrvUtil_BufInfo );\r
ret = giPL110_BufferMode;\r
if(Data) giPL110_BufferMode = *(int*)Data;\r
+ if(gPL110_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)\r
+ DrvUtil_Video_SetCursor( &gPL110_DrvUtil_BufInfo, &gDrvUtil_TextModeCursor );\r
break;\r
\r
case VIDEO_IOCTL_GETSETMODE:\r
break;\r
}\r
\r
- case VIDEO_IOCTL_SETCURSOR: break;\r
+ case VIDEO_IOCTL_SETCURSOR:\r
+ if( !Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Pos)) )\r
+ LEAVE_RET('i', -1);\r
+\r
+ DrvUtil_Video_RemoveCursor( &gPL110_DrvUtil_BufInfo );\r
+ \r
+ gPL110_CursorPos = *(tVideo_IOCtl_Pos*)Data;\r
+ if(gPL110_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)\r
+ DrvUtil_Video_DrawCursor(\r
+ &gPL110_DrvUtil_BufInfo,\r
+ gPL110_CursorPos.x*giVT_CharWidth,\r
+ gPL110_CursorPos.y*giVT_CharHeight\r
+ );\r
+ else\r
+ DrvUtil_Video_DrawCursor(\r
+ &gPL110_DrvUtil_BufInfo,\r
+ gPL110_CursorPos.x,\r
+ gPL110_CursorPos.y\r
+ );\r
+ break;\r
\r
default:\r
LEAVE('i', -2);\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 PL110_int_SetResolution(int W, int H)\r
{\r
- W = (W + 15)/16;\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 = 1024;\r
if(H > 768) H = 768;\r
\r
gpPL110_IOMem->LCDUPBase = gPL110_FramebufferPhys;\r
gpPL110_IOMem->LCDLPBase = 0;\r
\r
- gpPL110_IOMem->LCDIMSC = 0;\r
- gpPL110_IOMem->LCDControl = (1 << 11)|(1 << 5)|(5<<1)|1;\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( gbPL110_IsVersatile )\r
+ {\r
+ gpPL110_IOMem->LCDIMSC = controlWord; // Actually LCDControl\r
+ gpPL110_IOMem->LCDControl = 0; // Actually LCDIMSC\r
+ }\r
+ else\r
+ {\r
+ gpPL110_IOMem->LCDIMSC = 0;\r
+ gpPL110_IOMem->LCDControl = controlWord;\r
+ }\r
\r
giPL110_Width = W;\r
giPL110_Height = H;\r