/*
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
*
* (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
*
* Portions Copyright (c) 2001 Matrox Graphics Inc.
*
* Version: 1.65 2002/08/14
*
* See matroxfb_base.c for contributors.
*
*/
#include "matroxfb_DAC1064.h"
#include "matroxfb_misc.h"
#include "matroxfb_accel.h"
#include "g450_pll.h"
#include <linux/matroxfb.h>
#ifdef NEED_DAC1064
#define outDAC1064 matroxfb_DAC_out
#define inDAC1064 matroxfb_DAC_in
#define DAC1064_OPT_SCLK_PCI 0x00
#define DAC1064_OPT_SCLK_PLL 0x01
#define DAC1064_OPT_SCLK_EXT 0x02
#define DAC1064_OPT_SCLK_MASK 0x03
#define DAC1064_OPT_GDIV1 0x04 /* maybe it is GDIV2 on G100 ?! */
#define DAC1064_OPT_GDIV3 0x00
#define DAC1064_OPT_MDIV1 0x08
#define DAC1064_OPT_MDIV2 0x00
#define DAC1064_OPT_RESERVED 0x10
static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {
unsigned int fvco;
unsigned int p;
DBG(__FUNCTION__)
/* only for devices older than G450 */
fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p);
p = (1 << p) - 1;
if (fvco <= 100000)
;
else if (fvco <= 140000)
p |= 0x08;
else if (fvco <= 180000)
p |= 0x10;
else
p |= 0x18;
*post = p;
}
/* they must be in POS order */
static const unsigned char MGA1064_DAC_regs[] = {
M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,
DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,
M1064_XMISCCTRL,
M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,
M1064_XCRCBITSEL,
M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
static const unsigned char MGA1064_DAC[] = {
0x00, 0x00, M1064_XCURCTRL_DIS,
0x00, 0x00, 0x00, /* black */
0xFF, 0xFF, 0xFF, /* white */
0xFF, 0x00, 0x00, /* red */
0x00, 0,
M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,
M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,
M1064_XMISCCTRL_DAC_8BIT,
0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,
0x00,
0x00, 0x00, 0xFF, 0xFF};
static void DAC1064_setpclk(WPMINFO unsigned long fout) {
unsigned int m, n, p;
DBG(__FUNCTION__)
DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
ACCESS_FBINFO(hw).DACclk[0] = m;
ACCESS_FBINFO(hw).DACclk[1] = n;
ACCESS_FBINFO(hw).DACclk[2] = p;
}
static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
u_int32_t mx;
struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
DBG(__FUNCTION__)
if (ACCESS_FBINFO(devflags.noinit)) {
/* read MCLK and give up... */
hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
return;
}
mx = hw->MXoptionReg | 0x00000004;
pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
mx &= ~0x000000BB;
if (oscinfo & DAC1064_OPT_GDIV1)
mx |= 0x00000008;
if