/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/*****************************************************************************
 *
 * SOURCE FILE NAME = TMPINIT.C
 *
 * AUTHOR           = Joe Celi
 *
 * DATE CREATED     = 6/2/94
 *
 * DESCRIPTIVE NAME = Initialization code.
 *
 *
 * VERSION = V2.1
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS
 *
 * NOTES
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_WIN
#define INCL_GPI
#define INCL_DOS
#define INCL_DOSERRORS
#include <os2.h>
#include "next.h"
#include "endive.h"
#include "template.h"

extern BOOL         fInterpolation;
extern BYTE         bRevNum;
extern BYTE         bPelToDWORDShift;
extern FBINFO       FBInfo;
extern BOOL         fInitialized;

/*****************************************************************************
 *
 *  FUNCTION NAME:    TmpInit()
 *
 *
 *  DESCRIPTIVE NAME:
 *
 *  FUNCTION:         High level initialization logic
 *
 *  ENTRY POINT:
 *
 *  INPUT:
 *
 *  EXIT-NORMAL:      RC_SUCCESS
 *
 *  EXIT-ERROR:       RC_ERROR
 *
 *  EFFECTS:
 *
 *  NOTES:
 *
 *  INTERNAL REFERENCES:
 *    ROUTINES:
 *
 *  EXTERNAL REFERENCES:
 *    ROUTINES:
 *
 ****************************************************************************/

ULONG TmpInit( PFBINFO pFBInfo, PEXTINITOUT pOut )
{

   if(pFBInfo->ulLength != sizeof(FBINFO))
   {
      return(RC_ERROR);
   }

   FBInfo = *pFBInfo;

   /*
   ** POWERPLAY32 supports 8, 16, and 32 bpp output display modes
   **
   ** NOTE: Even though POWERPLAY32 supports 32 bpp we are not.
   **       Since the S3 PM driver does not support 32 bpp there
   **       is no way to test this mode.
   */
   switch(FBInfo.ulBPP)
   {
      case 8:
         /* Interpolation not supported at 8 bpp */
         fInterpolation = FALSE;
         bPelToDWORDShift = 2;
         break;

      case 16:
         fInterpolation = TRUE;
         bPelToDWORDShift = 1;
         break;

      default:
         return(RC_ERROR);
   }

   if(InitHW())
      return(RC_ERROR);

   if(pOut)
   {
      pOut->ulLength = sizeof(EXTINITOUT);
      pOut->ulFlags = 0;
   }
   fInitialized = TRUE;
   return(RC_SUCCESS);

} /* end of TmpInit */

/*****************************************************************************
 *
 *  FUNCTION NAME:    InitHW()
 *
 *
 *  DESCRIPTIVE NAME:
 *
 *  FUNCTION:         Initialize the video accelerator
 *                       - ensure that the HW is there
 *                       - init hardware to the appropriate state
 *
 *  INPUT:         NONE
 *
 *  EXIT-NORMAL:   RC_SUCCESS
 *
 *  EXIT-ERROR:    RC_ERROR
 *
 *  EFFECTS:
 *
 *  NOTES:
 *
 *  INTERNAL REFERENCES:
 *    ROUTINES:
 *
 *  EXTERNAL REFERENCES:
 *    ROUTINES:
 *
 ****************************************************************************/

ULONG InitHW( VOID )
{

   USHORT  i;
   BYTE    bBGTPInterval = 4;
   BYTE    bDTEPInterval;
   BOOL    fUseDTEP = FALSE;
   BOOL    fUseEXID = FALSE;

   /*
   ** Ensure that the HW is there by checking the chip ID.
   ** Also check for the appropriate chip revision number.
   ** NOTE:  We must save the contents of the changed registers
   **        so we can restore it if the ID does not match.
   */

   /*
   ** HW detection logic removed!
   */
// if(!fHWFound)
//   return(RC_ERROR);

   switch(FBInfo.ulXres)
   {
      case 640:
         if(FBInfo.ulBPP == 16)
         {
            bBGTPInterval = 8;
         }
         break;

      case 800:
         if(FBInfo.ulBPP == 16)
         {
            bBGTPInterval = 0x0F;
            bDTEPInterval = 3;
            fUseDTEP = TRUE;
            fUseEXID = TRUE;
         }
         else if(FBInfo.ulBPP == 8)
         {
            bBGTPInterval = 0x1d;
         }
         else
         {
            bBGTPInterval = 8;
         }
         break;

      case 1024:
         bBGTPInterval = 8;
         break;

      case 1280:
         if(FBInfo.ulBPP == 8)
         {
            bBGTPInterval = 11;
         }
         break;

      default:
         break;

   }

   /* Set the 928 for POWERPLAY32 cycles. */
   HWOutpByte(0x3d4,0x40);
   HWOutpByte(0x3d5,HWInpByte(0x3d5) | 2);
   HWOutpByte(0x3d4,0x55);
   HWOutpByte(0x3d5,HWInpByte(0x3d5) & 0xFB);

   /* Set bus grant terminate position. */
   HWOutpByte(0x3d4,0x00);
   i = (BYTE) HWInpByte(0x3d5);

   HWOutpByte(0x3d4,0x5D);
   i |= ((USHORT)(HWInpByte(0x3d5) & 1) << 8);

   HWOutpByte(0x3d4,0x5f);
   HWOutpByte(0x3d5,(BYTE)(i - bBGTPInterval));

   /* Set bit 7 in CR 5D to bit 8 of i */

   HWOutpByte(0x3d4,0x5D);
   HWOutpByte(0x3d5,HWInpByte(0x3d5) | ((i - bBGTPInterval) >> 1) & 0x80);

   /* Set DTEP if required */
   if (fUseDTEP)
   {
      HWOutpByte(0x3d4, 0x34);
      HWOutpByte(0x3d5,(BYTE)(HWInpByte(0x3d5) | 0x10));

      HWOutpByte(0x3d4, 0x3B);
      HWOutpByte(0x3d5, (BYTE)(i-bDTEPInterval));
      HWOutpByte(0x3d4, 0x5D);          /*  Set bit 7 in CR 5D to bit 8 of i */
      HWOutpByte(0x3d5, (BYTE)(HWInpByte(0x3d5) | ((i-bDTEPInterval) >> 2) & 0x40));
   }

   /* Set EXID if required */
   if (fUseEXID)
   {
      HWOutpByte(0x3d4, 0x65);
      HWOutpByte(0x3d5,(BYTE)(HWInpByte(0x3d5) | 0x40));
   }

   /*
   ** POWERPLAY32 init logic removed!
   */

   return(RC_SUCCESS);

}  /* end of InitHW */
