/*
 * SiS 300/540/630[S]/730[S]
 * SiS 315[E|PRO]/550/[M]65x/[M]66x[F|M|G]X/[M]74x[GX]/330/[M]76x[GX]
 * XGI V3XT/V5/V8, Z7
 * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
 *
 * Linux kernel specific extensions to init.c/init301.c
 *
 * Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the named License,
 * or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
 *
 * Author:	Thomas Winischhofer <thomas@winischhofer.net>
 */

#include "initdef.h"
#include "vgatypes.h"
#include "vstruct.h"

#include <linux/types.h>
#include <linux/fb.h>

int		sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
			unsigned char modeno, unsigned char rateindex);
int		sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
			unsigned char rateindex, struct fb_var_screeninfo *var);
bool		sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
			int *htotal, int *vtotal, unsigned char rateindex);

extern bool	SiSInitPtr(struct SiS_Private *SiS_Pr);
extern bool	SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
			unsigned short *ModeIdIndex);
extern void	SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
			int xres, int yres, struct fb_var_screeninfo *var, bool writeres);

int
sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
			unsigned char rateindex)
{
    unsigned short ModeNo = modeno;
    unsigned short ModeIdIndex = 0, ClockIndex = 0;
    unsigned short RRTI = 0;
    int Clock;

    if(!SiSInitPtr(SiS_Pr)) return 65000;

    if(rateindex > 0) rateindex--;

#ifdef CONFIG_FB_SIS_315
    switch(ModeNo) {
    case 0x5a: ModeNo = 0x50; break;
    case 0x5b: ModeNo = 0x56;
    }
#endif

    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
       printk(KERN_ERR "Could not find mode %x\n", ModeNo);
       return 65000;
    }

    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;

    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
       if(SiS_Pr->SiS_UseWide == 1) {
	  /* Wide screen: Ignore rateindex */
	  ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_WIDE;
       } else {
	  RRTI += rateindex;
	  ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK_NORM;
       }
    } else {
       RRTI += rateindex;
       ClockIndex = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRTVCLK;
    }

    Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;

    return Clock;
}

int
sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
			unsigned char rateindex, struct fb_var_screeninfo *var)
{
    unsigned short ModeNo = modeno;
    unsigned short ModeIdIndex = 0, index = 0, RRTI = 0;
    int            j;

    if(!SiSInitPtr(SiS_Pr)) return 0;

    if(rateindex > 0) rateindex--;

#ifdef CONFIG_FB_SIS_315
    switch(ModeNo) {
       case 0x5a: ModeNo = 0x50; break;
       case 0x5b: ModeNo = 0x56;
    }
#endif

    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;

    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
       if(SiS_Pr->SiS_UseWide == 1) {
	  /* Wide screen: Ignore rateindex */
	  index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
       } else {
	  RRTI += rateindex;
	  index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
       }
    } else {
       RRTI += rateindex;
       index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
    }

    SiS_Generic_ConvertCRData(SiS_Pr,
			(unsigned char *)&SiS_Pr->SiS_CRT1Table[index].CR[0],
			SiS_Pr->SiS_RefIndex[RRTI].XRes,
			SiS_Pr->SiS_RefIndex[RRTI].YRes,
			var, false);

    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x8000)
       var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
    else
       var->sync |= FB_SYNC_VERT_HIGH_ACT;

    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x4000)
       var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
    else
       var->sync |= FB_SYNC_HOR_HIGH_ACT;

    var->vmode = FB_VMODE_NONINTERLACED;
    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x0080)
       var->vmode = FB_VMODE_INTERLACED;
    else {
       j = 0;
       while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
	  if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
	                  SiS_Pr->SiS_RefIndex[RRTI].ModeID) {
	      if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
	      	  var->vmode = FB_VMODE_DOUBLE;
	      }
	      break;
	  }
	  j++;
       }
    }

    if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
#if 0  /* Do this? */
       var->upper_margin <<= 1;
       var->lower_margin <<= 1;
       var->vsync_len <<= 1;
#endif
    } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
       var->upper_margin >>= 1;
       var->lower_margin >>= 1;
       var->vsync_len >>= 1;
    }

    return 1;
}

bool
sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
			int *vtotal, unsigned char rateindex)
{
    unsigned short ModeNo = modeno;
    unsigned short ModeIdIndex = 0, CRT1Index = 0;
    unsigned short RRTI = 0;
    unsigned char  sr_data, cr_data, cr_data2;

    if(!SiSInitPtr(SiS_Pr)) return false;

    if(rateindex > 0) rateindex--;

#ifdef CONFIG_FB_SIS_315
    switch(ModeNo) {
       case 0x5a: ModeNo = 0x50; break;
       case 0x5b: ModeNo = 0x56;
    }
#endif

    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;

    RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
       if(SiS_Pr->SiS_UseWide == 1) {
	  /* Wide screen: Ignore rateindex */
	  CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_WIDE;
       } else {
	  RRTI += rateindex;
	  CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC_NORM;
       }
    } else {
       RRTI += rateindex;
       CRT1Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT1CRTC;
    }

    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
    *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;

    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
    cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
    *vtotal = ((cr_data & 0xFF) |
	       ((unsigned short)(cr_data2 & 0x01) <<  8) |
	       ((unsigned short)(cr_data2 & 0x20) <<  4) |
	       ((unsigned short)(sr_data  & 0x01) << 10)) + 2;

    if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & InterlaceMode)
       *vtotal *= 2;

    return true;
}



