Modules/PL110 - Added ARM PL110 CLCD driver
authorJohn Hodge <[email protected]>
Sun, 16 Oct 2011 14:28:41 +0000 (22:28 +0800)
committerJohn Hodge <[email protected]>
Sun, 16 Oct 2011 14:28:41 +0000 (22:28 +0800)
- Added more to DrvUtils (video)
- Working on an API to parse Key/Value pairs (header only)

Kernel/drvutil.c
Kernel/include/api_drv_video.h
Kernel/include/lib/keyvalue.h [new file with mode: 0644]
Modules/Display/PL110/Makefile [new file with mode: 0644]
Modules/Display/PL110/main.c [new file with mode: 0644]
Modules/Display/VESA/main.c

index e86f9a8..3835f0c 100644 (file)
@@ -7,9 +7,24 @@
 #include <api_drv_disk.h>
 #include <api_drv_video.h>
 
+// === TYPES ===
+
+// === PROTOTYPES ===
+//int  DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length, tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers);
+//size_t       DrvUtil_Video_WriteLFB(int Mode, tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Src);
+void   DrvUtil_Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);
+void   DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);
+
+// === GLOBALS ===
+tDrvUtil_Video_2DHandlers      gDrvUtil_Stub_2DFunctions = {
+       NULL,
+       DrvUtil_Video_2D_Fill,
+       DrvUtil_Video_2D_Blit
+};
+
 // === CODE ===
 // --- Video Driver Helpers ---
-Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
+int DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
        tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers)
 {
        void    *stream = Buffer;
@@ -22,13 +37,16 @@ Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
                stream = (void*)((tVAddr)stream + 1);
                
                if(op > NUM_VIDEO_2DOPS) {
-                       Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Unknown"
-                               " operation %i", op);
+                       Log_Warning("DrvUtil",
+                               "DrvUtil_Video_2DStream: Unknown operation %i",
+                               op);
+                       return Length-rem;
                }
                
                if(op*sizeof(void*) > SizeofHandlers) {
-                       Log_Warning("DrvUtil", "DrvUtil_Video_2DStream: Driver does"
-                               " not support op %i", op);
+                       Log_Warning("DrvUtil",
+                               "DrvUtil_Video_2DStream: Driver does not support op %i",
+                               op);
                        return Length-rem;
                }
                
@@ -81,6 +99,163 @@ Uint64 DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,
        return 0;
 }
 
+int DrvUtil_Video_WriteLFB(int Mode, tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Buffer)
+{
+       Uint8   *dest;
+       ENTER("iMode pFBInfo xOffset xLength pBuffer",
+               Mode, FBInfo, Offset, Length, Buffer);
+       switch( Mode )
+       {
+       case VIDEO_BUFFMT_TEXT:
+               {
+               tVT_Char        *chars = Buffer;
+                int    bytes_per_px = FBInfo->Depth / 8;
+                int    widthInChars = FBInfo->Width/giVT_CharWidth;
+                int    heightInChars = FBInfo->Height/giVT_CharHeight;
+                int    x, y, i;
+               
+               Length /= sizeof(tVT_Char);     Offset /= sizeof(tVT_Char);
+               
+               x = Offset % widthInChars;      y = Offset / widthInChars;
+               
+               // Sanity Check
+               if(Offset > heightInChars * widthInChars)       LEAVE_RET('i', 0);
+               if(y >= heightInChars)  LEAVE_RET('i', 0);
+               
+               if( Offset + Length > heightInChars*widthInChars )
+               {
+                       Length = heightInChars*widthInChars - Offset;
+               }
+               
+               dest = FBInfo->Framebuffer;
+               dest += y * giVT_CharHeight * FBInfo->Pitch;
+               
+               for( i = 0; i < Length; i++ )
+               {
+                       if( y >= heightInChars )
+                       {
+                               Log_Notice("DrvUtil", "Stopped at %i", i);
+                               break;
+                       }
+                       
+                       VT_Font_Render(
+                               chars->Ch,
+                               dest + x*giVT_CharWidth*bytes_per_px, FBInfo->Depth, FBInfo->Pitch,
+                               VT_Colour12toN(chars->BGCol, FBInfo->Depth),
+                               VT_Colour12toN(chars->FGCol, FBInfo->Depth)
+                               );
+                       
+                       chars ++;
+                       x ++;
+                       if( x >= widthInChars )
+                       {
+                               x = 0;
+                               y ++;
+                               dest += FBInfo->Pitch*giVT_CharHeight;
+                       }
+               }
+               Length = i * sizeof(tVT_Char);
+               }
+               break;
+       
+       case VIDEO_BUFFMT_FRAMEBUFFER:
+               if(FBInfo->Width*FBInfo->Height*4 < Offset+Length)
+               {
+                       Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Framebuffer Overflow");
+                       return 0;
+               }
+               
+               //TODO: Handle non 32-bpp framebuffer modes
+               if( FBInfo->Depth != 32 ) {
+                       Log_Warning("DrvUtil", "DrvUtil_Video_WriteLFB - Don't support non 32-bpp FB mode");
+                       return 0;
+               }       
+
+               
+               //TODO: Handle pitch != Width*BytesPerPixel
+               // Copy to Frambuffer
+               dest = (Uint8 *)FBInfo->Framebuffer + Offset;
+               memcpy(dest, Buffer, Length);
+               break;
+       
+       case VIDEO_BUFFMT_2DSTREAM:
+               Length = DrvUtil_Video_2DStream(
+                       FBInfo, Buffer, Length,
+                       &gDrvUtil_Stub_2DFunctions, sizeof(gDrvUtil_Stub_2DFunctions)
+                       );
+               break;
+       
+       default:
+               LEAVE('i', -1);
+               return -1;
+       }
+       LEAVE('x', Length);
+       return Length;
+}
+
+void DrvUtil_Video_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour)
+{
+       tDrvUtil_Video_BufInfo  *FBInfo = Ent;
+
+       // TODO: Handle non-32bit modes
+       if( FBInfo->Depth != 32 )       return;
+
+       // TODO: Be less hacky
+        int    pitch = FBInfo->Pitch/4;
+       Uint32  *buf = (Uint32*)FBInfo->Framebuffer + Y*pitch + X;
+       while( H -- ) {
+               Uint32 *tmp;
+                int    i;
+               tmp = buf;
+               for(i=W;i--;tmp++)      *tmp = Colour;
+               buf += pitch;
+       }
+}
+
+void DrvUtil_Video_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H)
+{
+       tDrvUtil_Video_BufInfo  *FBInfo = Ent;
+        int    scrnpitch = FBInfo->Pitch;
+        int    bytes_per_px = (FBInfo->Depth + 7) / 8;
+        int    dst = DstY*scrnpitch + DstX;
+        int    src = SrcY*scrnpitch + SrcX;
+        int    tmp;
+       
+       //Log("Vesa_2D_Blit: (Ent=%p, DstX=%i, DstY=%i, SrcX=%i, SrcY=%i, W=%i, H=%i)",
+       //      Ent, DstX, DstY, SrcX, SrcY, W, H);
+       
+       if(SrcX + W > FBInfo->Width)    W = FBInfo->Width - SrcX;
+       if(DstX + W > FBInfo->Width)    W = FBInfo->Width - DstX;
+       if(SrcY + H > FBInfo->Height)   H = FBInfo->Height - SrcY;
+       if(DstY + H > FBInfo->Height)   H = FBInfo->Height - DstY;
+       
+       //Debug("W = %i, H = %i", W, H);
+       
+       if( dst > src ) {
+               // Reverse copy
+               dst += H*scrnpitch;
+               src += H*scrnpitch;
+               while( H -- ) {
+                       dst -= scrnpitch;
+                       src -= scrnpitch;
+                       tmp = W*bytes_per_px;
+                       for( tmp = W; tmp --; ) {
+                               *((Uint8*)FBInfo->Framebuffer + dst + tmp) = *((Uint8*)FBInfo->Framebuffer + src + tmp);
+                       }
+               }
+       }
+       else {
+               // Normal copy is OK
+               while( H -- ) {
+                       memcpy((Uint8*)FBInfo->Framebuffer + dst, (Uint8*)FBInfo->Framebuffer + src, W*bytes_per_px);
+                       dst += scrnpitch;
+                       src += scrnpitch;
+               }
+       }
+       //Log("Vesa_2D_Blit: RETURN");
+}
+       
+
 // --- Disk Driver Helpers ---
 Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
        tDrvUtil_Callback ReadBlocks, Uint64 BlockSize, Uint Argument)
index a4eb46c..28b9854 100644 (file)
@@ -51,8 +51,8 @@ enum eTplVideo_IOCtl {
         * \return 1 if a mode was found, 0 otherwise\r
         * \r
         * Using avaliable modes matching the \a bpp and \a flags fields\r
-        * set the \a id field to the mode id of the mode with the closest\r
-        * \a width and \a height.\r
+        * set the \a id, \a width and \a heights fields to the closest\r
+        * matching mode.\r
         */\r
        VIDEO_IOCTL_FINDMODE,\r
        \r
@@ -111,8 +111,8 @@ typedef struct sVideo_IOCtl_Mode
        short   id;             //!< Mode ID\r
        Uint16  width;  //!< Width\r
        Uint16  height; //!< Height\r
-       Uint8   bpp;    //!< Bits per Unit (Character or Pixel, depending on \a flags)\r
-       Uint8   flags;  //!< Mode Flags\r
+       Uint8   bpp;    //!< Bits per pixel\r
+       Uint8   flags;  //!< Mode Flags (none defined, should be zero)\r
 }      tVideo_IOCtl_Mode;\r
 \r
 /**\r
@@ -292,10 +292,40 @@ extern Uint16     VT_Colour12to15(Uint16 Col12);
  */\r
 extern Uint32  VT_Colour12toN(Uint16 Col12, int Depth);\r
 \r
+typedef struct sDrvUtil_Video_BufInfo  tDrvUtil_Video_BufInfo;\r
+typedef struct sDrvUtil_Video_2DHandlers       tDrvUtil_Video_2DHandlers;\r
+\r
+/**\r
+ * \brief Framebuffer information used by all DrvUtil_Video functions\r
+ */\r
+struct sDrvUtil_Video_BufInfo\r
+{\r
+       /**\r
+        * \brief Framebuffer virtual address\r
+        */\r
+       void    *Framebuffer;\r
+       /**\r
+        * \brief Bytes between the start of each line\r
+        */\r
+        int    Pitch;\r
+       /**\r
+        * \brief Number of pixels in each line\r
+        */\r
+        int    Width;\r
+       /**\r
+        * \brief Total number of lines\r
+        */\r
+        int    Height;\r
+       /**\r
+        * \brief Bit depth of the framebuffer\r
+        */\r
+        int    Depth;\r
+};\r
+\r
 /**\r
  * \brief Handlers for eTplVideo_2DCommands\r
  */\r
-typedef struct sDrvUtil_Video_2DHandlers\r
+struct sDrvUtil_Video_2DHandlers\r
 {\r
        /**\r
         * \brief No Operation, Ignored\r
@@ -323,7 +353,7 @@ typedef struct sDrvUtil_Video_2DHandlers
         * \see VIDEO_2DOP_BLIT\r
         */\r
        void    (*Blit)(void *Ent, Uint16 DestX, Uint16 DestY, Uint16 SrcX, Uint16 SrcY, Uint16 W, Uint16 H);\r
-}      tDrvUtil_Video_2DHandlers;\r
+};\r
 \r
 /**\r
  * \brief Handle a 2D operation stream for a driver\r
@@ -334,7 +364,19 @@ typedef struct sDrvUtil_Video_2DHandlers
  * \param SizeofHandlers       Size of \a tDrvUtil_Video_2DHandlers according\r
  *        to the driver. Used as version control and error avoidence.\r
  */\r
-extern Uint64  DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,\r
+extern int     DrvUtil_Video_2DStream(void *Ent, void *Buffer, int Length,\r
        tDrvUtil_Video_2DHandlers *Handlers, int SizeofHandlers);\r
 \r
+/**\r
+ * \brief Perform write operations to a LFB\r
+ * \param Mode Buffer mode (see eTplVideo_BufFormats)\r
+ * \param FBInfo       Framebuffer descriptor, see type for details\r
+ * \param Offset       Offset provided by VFS call\r
+ * \param Length       Length provided by VFS call\r
+ * \param Src  Data from VFS call\r
+ * \return Number of bytes written\r
+ *\r
+ * Handles all write modes in software, using the VT font calls for rendering.\r
+ */\r
+extern int     DrvUtil_Video_WriteLFB(int Mode, tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t Length, void *Src);\r
 #endif\r
diff --git a/Kernel/include/lib/keyvalue.h b/Kernel/include/lib/keyvalue.h
new file mode 100644 (file)
index 0000000..ef37d5b
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge
+ *
+ * include/keyvalue.h
+ * - Key/Value pair parsing
+ */
+#ifndef _ACESS_KEYVALUE_H_
+#define _ACESS_KEYVALUE_H_
+
+typedef struct sKeyVal_ParseRules      tKeyVal_ParseRules;
+typedef struct sKeyVal_int_Rule        tKeyVal_int_Rule;
+typedef void (*tKeyVal_UnkCb)(char *String);
+typedef void (*tKeyVal_KeyCb)(const char *Key, char *Value);
+
+/**
+ * \brief Handling rule for a key
+ */
+struct sKeyVal_int_Rule
+{
+       const char      *Key;
+       const char      *Type;  // Acess printf format, with 'F' being a tKeyVal_KeyCb
+       void    *Data;
+};
+
+struct sKeyVal_ParseRules
+{
+       /**
+        * \brief Function to call when no match is found
+        */
+       tKeyVal_UnkCb   Unknown;
+       tKeyVal_int_Rule        Rules[];
+};
+
+/**
+ * \brief Parse a NULL terminated list of strings as Key/Value pairs
+ * \param Rules        Parsing rules
+ * \param Strings      Input string list
+ */
+extern int     KeyVal_ParseNull(tKeyVal_ParseRules *Rules, char **Strings);
+
+#endif
+
diff --git a/Modules/Display/PL110/Makefile b/Modules/Display/PL110/Makefile
new file mode 100644 (file)
index 0000000..0f90347
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = main.o
+NAME = PL110
+
+-include ../Makefile.tpl
diff --git a/Modules/Display/PL110/main.c b/Modules/Display/PL110/main.c
new file mode 100644 (file)
index 0000000..f1604c6
--- /dev/null
@@ -0,0 +1,294 @@
+/**\r
+ * Acess2 ARM PrimeCell Colour LCD Controller (PL110) Driver\r
+ * - By John Hodge (thePowersGang)\r
+ *\r
+ * main.c\r
+ * - Driver core\r
+ *\r
+ *\r
+ * NOTE: The PL110 is set to 24bpp, but these are stored as 32-bit words.\r
+ *       This corresponds to the Acess 32bpp mode, as the Acess 24bpp is packed\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
+\r
+#define ABS(a) ((a)>0?(a):-(a))\r
+\r
+// === TYPEDEFS ===\r
+typedef struct sPL110  tPL110;\r
+\r
+struct sPL110\r
+{\r
+       Uint32  LCDTiming0;\r
+       Uint32  LCDTiming1;\r
+       Uint32  LCDTiming2;\r
+       Uint32  LCDTiming3;\r
+       \r
+       Uint32  LCDUPBase;\r
+       Uint32  LCDLPBase;\r
+       Uint32  LCDIMSC;\r
+       Uint32  LCDControl;\r
+       Uint32  LCDRIS;\r
+       Uint32  LCDMIS;\r
+       Uint32  LCDICR;\r
+       Uint32  LCDUPCurr;\r
+       Uint32  LCDLPCurr;\r
+};\r
+\r
+// === CONSTANTS ===\r
+#define PL110_BASE     0x10020000      \r
+const struct {\r
+       short W, H;\r
+}      caPL110_Modes[] = {\r
+       {640,480},\r
+       {800,600},\r
+       {1024,768}      // MAX\r
+};\r
+const int      ciPL110_ModeCount = sizeof(caPL110_Modes)/sizeof(caPL110_Modes[0]);\r
+\r
+// === PROTOTYPES ===\r
+// Driver\r
+ int   PL110_Install(char **Arguments);\r
+void   PL110_Uninstall();\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
+ 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
+       .Read = PL110_Read,\r
+       .Write = PL110_Write,\r
+       .IOCtl = PL110_IOCtl\r
+       }\r
+};\r
+// -- Options\r
+tPAddr gPL110_PhysBase = PL110_BASE;\r
+// -- KeyVal parse rules\r
+const tKeyVal_ParseRules       gPL110_KeyValueParser = {\r
+       NULL,\r
+       {\r
+               {"Base", "P", &gPL110_PhysBase},\r
+               {NULL, NULL, NULL}\r
+       }\r
+};\r
+// -- Driver state\r
+ int   giPL110_CurrentMode = 0;\r
+ int   giPL110_BufferMode;\r
+ int   giPL110_Width = 640;\r
+ int   giPL110_Height = 480;\r
+size_t giPL110_FramebufferSize;\r
+tPL110 *gpPL110_IOMem;\r
+tPAddr gPL110_FramebufferPhys;\r
+void   *gpPL110_Framebuffer;\r
+// -- Misc\r
+tDrvUtil_Video_BufInfo gPL110_DrvUtil_BufInfo;\r
+\r
+// === CODE ===\r
+/**\r
+ */\r
+int PL110_Install(char **Arguments)\r
+{\r
+//     KeyVal_Parse(&gPL110_KeyValueParser, Arguments);\r
+       \r
+       gpPL110_IOMem = (void*)MM_MapHWPages(gPL110_PhysBase, 1);\r
+\r
+       PL110_int_SetResolution(caPL110_Modes[0].W, caPL110_Modes[0].H);\r
+\r
+       DevFS_AddDevice( &gPL110_DriverStruct );\r
+\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \brief Clean up resources for driver unloading\r
+ */\r
+void PL110_Uninstall()\r
+{\r
+}\r
+\r
+/**\r
+ * \brief Read from the framebuffer\r
+ */\r
+Uint64 PL110_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
+{\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \brief Write to the framebuffer\r
+ */\r
+Uint64 PL110_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
+{\r
+       return DrvUtil_Video_WriteLFB(giPL110_BufferMode, &gPL110_DrvUtil_BufInfo, Offset, Length, Buffer);\r
+}\r
+\r
+const char *csaPL110_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};\r
+\r
+/**\r
+ * \brief Handle messages to the device\r
+ */\r
+int PL110_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, csaPL110_IOCtls);\r
+\r
+       case VIDEO_IOCTL_SETBUFFORMAT:\r
+               ret = giPL110_BufferMode;\r
+               if(Data)        giPL110_BufferMode = *(int*)Data;\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 >= ciPL110_ModeCount)\r
+                               LEAVE_RET('i', -1);\r
+\r
+                       if(newMode != giPL110_CurrentMode)\r
+                       {\r
+                               giPL110_CurrentMode = newMode;\r
+                               PL110_int_SetResolution( caPL110_Modes[newMode].W, caPL110_Modes[newMode].H );\r
+                       }\r
+               }\r
+               ret = giPL110_CurrentMode;\r
+               break;\r
+       \r
+       case VIDEO_IOCTL_FINDMODE:\r
+               {\r
+               tVideo_IOCtl_Mode *mode = Data;\r
+                int    closest, 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 < ciPL110_ModeCount; i ++ )\r
+               {\r
+                        int    area;\r
+                       if(mode->width == caPL110_Modes[i].W && mode->height == caPL110_Modes[i].H) {\r
+                               mode->id = i;\r
+                               ret = 1;\r
+                               break;\r
+                       }\r
+                       \r
+                       area = caPL110_Modes[i].W * caPL110_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 = caPL110_Modes[mode->id].W;\r
+               mode->height = caPL110_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 >= ciPL110_ModeCount)\r
+                       LEAVE_RET('i', 0);\r
+               \r
+\r
+               mode->bpp = 32;\r
+               mode->flags = 0;\r
+               mode->width = caPL110_Modes[mode->id].W;\r
+               mode->height = caPL110_Modes[mode->id].H;\r
+\r
+               ret = 1;\r
+               break;\r
+               }\r
+       \r
+       case VIDEO_IOCTL_SETCURSOR:     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
+/**\r
+ */\r
+int PL110_int_SetResolution(int W, int H)\r
+{\r
+       W = (W + 15)/16;\r
+       if(W > 1024)    W = 1024;\r
+       if(H > 768)     H = 768;\r
+\r
+       gpPL110_IOMem->LCDTiming0 = ((W/16)-1) << 2;\r
+       gpPL110_IOMem->LCDTiming1 = H-1;\r
+       gpPL110_IOMem->LCDTiming2 = (14 << 27);\r
+       gpPL110_IOMem->LCDTiming3 = 0;\r
+\r
+       if( gpPL110_Framebuffer ) {\r
+               MM_UnmapHWPages((tVAddr)gpPL110_Framebuffer, (giPL110_FramebufferSize+0xFFF)>>12);\r
+       }\r
+       giPL110_FramebufferSize = W*H*4;\r
+\r
+       gpPL110_Framebuffer = (void*)MM_AllocDMA( (giPL110_FramebufferSize+0xFFF)>>12, 32, &gPL110_FramebufferPhys );\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
+\r
+       giPL110_Width = W;\r
+       giPL110_Height = H;\r
+\r
+       // Update the DrvUtil buffer info\r
+       gPL110_DrvUtil_BufInfo.Framebuffer = gpPL110_Framebuffer;\r
+       gPL110_DrvUtil_BufInfo.Pitch = W * 4;\r
+       gPL110_DrvUtil_BufInfo.Width = W;\r
+       gPL110_DrvUtil_BufInfo.Height = H;\r
+       gPL110_DrvUtil_BufInfo.Depth = 32;\r
+       \r
+       return 0;\r
+}\r
index c18891f..a227f17 100644 (file)
@@ -390,10 +390,7 @@ int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data)
        \r
        case VIDEO_IOCTL_SETBUFFORMAT:\r
                ret = giVesaCurrentFormat;\r
-               if(Data) {\r
-                       //Log_Log("VESA", "Buffer mode to %i", *(int*)Data);\r
-                       giVesaCurrentFormat = *(int*)Data;\r
-               }\r
+               if(Data)        giVesaCurrentFormat = *(int*)Data;\r
                return ret;\r
        \r
        case VIDEO_IOCTL_SETCURSOR:     // Set cursor position\r

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