/*
 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
/*#include <stdlib.h>
#include <string.h>*/
#include "xf86.h"

#include "via.h"
#include "via_driver.h"
#include "via_regrec.h"



void viaWaitHQVIdle(VIAPtr pVia)
{
    while (!IN_HQV_FIRE);
}

void viaWaitVideoCommandFire(VIAPtr pVia)
{
    /*while (IN_VIDEO_FIRE);*/
    CARD32 volatile *pdwState = (CARD32 volatile *) (pVia->VidMapBase+V_COMPOSE_MODE);
    /*pdwState = (CARD32 volatile *) (pVia->VidMapBase+V_COMPOSE_MODE);*/
    while ((*pdwState & V1_COMMAND_FIRE)||(*pdwState & V3_COMMAND_FIRE));
}

void viaWaitHQVFlip(VIAPtr pVia)
{
    CARD32 volatile *pdwState = (CARD32 volatile *) pVia->VidMapBase;
    pdwState = (CARD32 volatile *) (pVia->VidMapBase+HQV_CONTROL);
    while (!(*pdwState & HQV_FLIP_STATUS) );
/*
    while (!((*pdwState & 0xc0)== 0xc0) );
    while (!((*pdwState & 0xc0)!= 0xc0) );
*/    
}

void viaWaitHQVFlipClear(VIAPtr pVia, unsigned long dwData)
{
    CARD32 volatile *pdwState = (CARD32 volatile *) (pVia->VidMapBase+HQV_CONTROL);
    *pdwState =dwData;

    while ((*pdwState & HQV_FLIP_STATUS) )
    {
        VIDOutD(HQV_CONTROL, *pdwState|HQV_FLIP_STATUS);
    }
}

void viaWaitVBI(VIAPtr pVia)
{
    while (IN_VIDEO_DISPLAY);
}

void viaWaitHQVDone(VIAPtr pVia)
{
    CARD32 volatile *pdwState = (CARD32 volatile *) (pVia->VidMapBase+HQV_CONTROL);
    /*pdwState = (CARD32 volatile *) (GEAddr+HQV_CONTROL);*/

    /*if (*pdwState & HQV_ENABLE)*/
    if (pVia->swov.MPEG_ON)
    {
        while ((*pdwState & HQV_SW_FLIP) );
    }
}
/*
 * Send all data in VidRegBuffer to the hardware.
 */
void FlushVidRegBuffer(VIAPtr pVia)
{
    unsigned int i;
    
    viaWaitVideoCommandFire(pVia);

    for (i = 0; i < pVia->VidRegCursor; i += 2)
    {
        VIDOutD(pVia->VidRegBuffer[i], pVia->VidRegBuffer[i+1]);
        DBG_DD(ErrorF("FlushVideoRegs: [%i] %08lx %08lx\n",
            i>>1, pVia->VidRegBuffer[i]+0x200, pVia->VidRegBuffer[i+1]));
    }

    /* BUG: (?) VIA never resets the cursor. 
     * My fix is commented out for now, in case they had a reason for that. /A
     */
    /* pVia->VidRegCursor = 0; */
}

/*
 * Initialize and clear VidRegBuffer.
 */
void ResetVidRegBuffer(VIAPtr pVia)
{
    /* BUG: (Memory leak) This allocation may need have a corresponding free somewhere... /A */
    if (!pVia->VidRegBuffer)
        pVia->VidRegBuffer = xnfcalloc(VIDREG_BUFFER_SIZE, sizeof(CARD32) * 2);
    pVia->VidRegCursor = 0;
}

/*
 * Save a video register and data in VidRegBuffer.
 */
void SaveVideoRegister(VIAPtr pVia, CARD32 index, CARD32 data)
{
    pVia->VidRegBuffer[pVia->VidRegCursor++] = index;
    pVia->VidRegBuffer[pVia->VidRegCursor++] = data;

    if (pVia->VidRegCursor > VIDREG_BUFFER_SIZE) {
        DBG_DD(ErrorF("SaveVideoRegister: Out of video register space"));
    }
}
