diff options
Diffstat (limited to 'src/drivers/xgi/common/XGI_main.c')
-rw-r--r-- | src/drivers/xgi/common/XGI_main.c | 871 |
1 files changed, 871 insertions, 0 deletions
diff --git a/src/drivers/xgi/common/XGI_main.c b/src/drivers/xgi/common/XGI_main.c new file mode 100644 index 0000000000..c76ebf76c1 --- /dev/null +++ b/src/drivers/xgi/common/XGI_main.c @@ -0,0 +1,871 @@ +/* + * This file is part of the coreboot project. + * + * Code taken from the Linux xgifb driver (v3.18.5) + * + * 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; version 2 of the License. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Select functions taken from the Linux xgifb driver file XGI_main_26.c + * + * Original file header: + * XG20, XG21, XG40, XG42 frame buffer device + * for Linux kernels 2.5.x, 2.6.x + * Base on TW's sis fbdev code. + */ + + +#define Index_CR_GPIO_Reg1 0x48 +#define Index_CR_GPIO_Reg3 0x4a + +#define GPIOG_EN (1<<6) +#define GPIOG_READ (1<<1) + +// static char *mode; +static int vesa = -1; +static unsigned int refresh_rate; + +/* ---------------- Chip generation dependent routines ---------------- */ + +/* for XGI 315/550/650/740/330 */ + +static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) +{ + + u8 ChannelNum, tmp; + u8 reg = 0; + + /* xorg driver sets 32MB * 1 channel */ + if (xgifb_info->chip == XG27) + xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51); + + reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE); + if (!reg) + return -1; + + switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) { + case XGI_DRAM_SIZE_1MB: + xgifb_info->video_size = 0x100000; + break; + case XGI_DRAM_SIZE_2MB: + xgifb_info->video_size = 0x200000; + break; + case XGI_DRAM_SIZE_4MB: + xgifb_info->video_size = 0x400000; + break; + case XGI_DRAM_SIZE_8MB: + xgifb_info->video_size = 0x800000; + break; + case XGI_DRAM_SIZE_16MB: + xgifb_info->video_size = 0x1000000; + break; + case XGI_DRAM_SIZE_32MB: + xgifb_info->video_size = 0x2000000; + break; + case XGI_DRAM_SIZE_64MB: + xgifb_info->video_size = 0x4000000; + break; + case XGI_DRAM_SIZE_128MB: + xgifb_info->video_size = 0x8000000; + break; + case XGI_DRAM_SIZE_256MB: + xgifb_info->video_size = 0x10000000; + break; + default: + return -1; + } + + tmp = (reg & 0x0c) >> 2; + switch (xgifb_info->chip) { + case XG20: + case XG21: + case XG27: + ChannelNum = 1; + break; + + case XG42: + if (reg & 0x04) + ChannelNum = 2; + else + ChannelNum = 1; + break; + + case XG40: + default: + if (tmp == 2) + ChannelNum = 2; + else if (tmp == 3) + ChannelNum = 3; + else + ChannelNum = 1; + break; + } + + xgifb_info->video_size = xgifb_info->video_size * ChannelNum; + + pr_info("SR14=%x DramSzie %x ChannelNum %x\n", + reg, + xgifb_info->video_size, ChannelNum); + return 0; + +} + +void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr) +{ + XGI_Pr->P3c4 = BaseAddr + 0x14; + XGI_Pr->P3d4 = BaseAddr + 0x24; + XGI_Pr->P3c0 = BaseAddr + 0x10; + XGI_Pr->P3ce = BaseAddr + 0x1e; + XGI_Pr->P3c2 = BaseAddr + 0x12; + XGI_Pr->P3cc = BaseAddr + 0x1c; + XGI_Pr->P3ca = BaseAddr + 0x1a; + XGI_Pr->P3c6 = BaseAddr + 0x16; + XGI_Pr->P3c7 = BaseAddr + 0x17; + XGI_Pr->P3c8 = BaseAddr + 0x18; + XGI_Pr->P3c9 = BaseAddr + 0x19; + XGI_Pr->P3da = BaseAddr + 0x2A; + XGI_Pr->Part0Port = BaseAddr + XGI_CRT2_PORT_00; + /* Digital video interface registers (LCD) */ + XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04; + /* 301 TV Encoder registers */ + XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10; + /* 301 Macrovision registers */ + XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12; + /* 301 VGA2 (and LCD) registers */ + XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14; + /* 301 palette address port registers */ + XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; + +} + +/* ------------------ Internal helper routines ----------------- */ + +static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info) +{ + int i = 0; + + while ((XGIbios_mode[i].mode_no != 0) + && (XGIbios_mode[i].xres <= xgifb_info->lvds_data.LVDSHDE)) { + if ((XGIbios_mode[i].xres == xgifb_info->lvds_data.LVDSHDE) + && (XGIbios_mode[i].yres == xgifb_info->lvds_data.LVDSVDE) + && (XGIbios_mode[i].bpp == 8)) { + return i; + } + i++; + } + + return -1; +} + +static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info, + unsigned int rate) +{ + u16 xres, yres; + int i = 0; + + xres = XGIbios_mode[xgifb_info->mode_idx].xres; + yres = XGIbios_mode[xgifb_info->mode_idx].yres; + + xgifb_info->rate_idx = 0; + while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) { + if ((XGIfb_vrate[i].xres == xres) && + (XGIfb_vrate[i].yres == yres)) { + if (XGIfb_vrate[i].refresh == rate) { + xgifb_info->rate_idx = XGIfb_vrate[i].idx; + break; + } else if (XGIfb_vrate[i].refresh > rate) { + if ((XGIfb_vrate[i].refresh - rate) <= 3) { + pr_debug("Adjusting rate from %d up to %d\n", + rate, XGIfb_vrate[i].refresh); + xgifb_info->rate_idx = + XGIfb_vrate[i].idx; + xgifb_info->refresh_rate = + XGIfb_vrate[i].refresh; + } else if (((rate - XGIfb_vrate[i - 1].refresh) + <= 2) && (XGIfb_vrate[i].idx + != 1)) { + pr_debug("Adjusting rate from %d down to %d\n", + rate, + XGIfb_vrate[i-1].refresh); + xgifb_info->rate_idx = + XGIfb_vrate[i - 1].idx; + xgifb_info->refresh_rate = + XGIfb_vrate[i - 1].refresh; + } + break; + } else if ((rate - XGIfb_vrate[i].refresh) <= 2) { + pr_debug("Adjusting rate from %d down to %d\n", + rate, XGIfb_vrate[i].refresh); + xgifb_info->rate_idx = XGIfb_vrate[i].idx; + break; + } + } + i++; + } + if (xgifb_info->rate_idx > 0) + return xgifb_info->rate_idx; + pr_info("Unsupported rate %d for %dx%d\n", + rate, xres, yres); + return 0; +} + +static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) +{ + u8 cr32, temp = 0; + + xgifb_info->TV_plug = xgifb_info->TV_type = 0; + + cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32); + + if ((cr32 & SIS_CRT1) && !XGIfb_crt1off) + XGIfb_crt1off = 0; + else { + if (cr32 & 0x5F) + XGIfb_crt1off = 1; + else + XGIfb_crt1off = 0; + } + + if (!xgifb_info->display2_force) { + if (cr32 & SIS_VB_TV) + xgifb_info->display2 = XGIFB_DISP_TV; + else if (cr32 & SIS_VB_LCD) + xgifb_info->display2 = XGIFB_DISP_LCD; + else if (cr32 & SIS_VB_CRT2) + xgifb_info->display2 = XGIFB_DISP_CRT; + else + xgifb_info->display2 = XGIFB_DISP_NONE; + } + + if (XGIfb_tvplug != -1) + /* Override with option */ + xgifb_info->TV_plug = XGIfb_tvplug; + else if (cr32 & SIS_VB_HIVISION) { + xgifb_info->TV_type = TVMODE_HIVISION; + xgifb_info->TV_plug = TVPLUG_SVIDEO; + } else if (cr32 & SIS_VB_SVIDEO) + xgifb_info->TV_plug = TVPLUG_SVIDEO; + else if (cr32 & SIS_VB_COMPOSITE) + xgifb_info->TV_plug = TVPLUG_COMPOSITE; + else if (cr32 & SIS_VB_SCART) + xgifb_info->TV_plug = TVPLUG_SCART; + + if (xgifb_info->TV_type == 0) { + temp = xgifb_reg_get(XGICR, 0x38); + if (temp & 0x10) + xgifb_info->TV_type = TVMODE_PAL; + else + xgifb_info->TV_type = TVMODE_NTSC; + } + + /* Copy forceCRT1 option to CRT1off if option is given */ + if (XGIfb_forcecrt1 != -1) { + if (XGIfb_forcecrt1) + XGIfb_crt1off = 0; + else + XGIfb_crt1off = 1; + } +} + +static int XGIfb_has_VB(struct xgifb_video_info *xgifb_info) +{ + u8 vb_chipid; + + vb_chipid = xgifb_reg_get(XGIPART4, 0x00); + switch (vb_chipid) { + case 0x01: + xgifb_info->hasVB = HASVB_301; + break; + case 0x02: + xgifb_info->hasVB = HASVB_302; + break; + default: + xgifb_info->hasVB = HASVB_NONE; + return 0; + } + return 1; +} + +static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info) +{ + u8 reg; + + if (!XGIfb_has_VB(xgifb_info)) { + reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37); + switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) { + case SIS_EXTERNAL_CHIP_LVDS: + xgifb_info->hasVB = HASVB_LVDS; + break; + case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL: + xgifb_info->hasVB = HASVB_LVDS_CHRONTEL; + break; + default: + break; + } + } +} + +#if 0 +static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info, + const char *name) +{ + unsigned int xres; + unsigned int yres; + unsigned int bpp; + int i; + + if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3) + goto invalid_mode; + + if (bpp == 24) + bpp = 32; /* That's for people who mix up color and fb depth. */ + + for (i = 0; XGIbios_mode[i].mode_no != 0; i++) + if (XGIbios_mode[i].xres == xres && + XGIbios_mode[i].yres == yres && + XGIbios_mode[i].bpp == bpp) { + xgifb_info->mode_idx = i; + return; + } +invalid_mode: + pr_info("Invalid mode '%s'\n", name); +} +#endif + +static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info, + unsigned int vesamode) +{ + int i = 0; + + if (vesamode == 0) + goto invalid; + + vesamode &= 0x1dff; /* Clean VESA mode number from other flags */ + + while (XGIbios_mode[i].mode_no != 0) { + if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) || + (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) { + xgifb_info->mode_idx = i; + return; + } + i++; + } + +invalid: + pr_info("Invalid VESA mode 0x%x'\n", vesamode); +} + +static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex) +{ + u16 xres, yres; + struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info; + unsigned long required_mem; + + if (xgifb_info->chip == XG21) { + if (xgifb_info->display2 == XGIFB_DISP_LCD) { + xres = xgifb_info->lvds_data.LVDSHDE; + yres = xgifb_info->lvds_data.LVDSVDE; + if (XGIbios_mode[myindex].xres > xres) + return -1; + if (XGIbios_mode[myindex].yres > yres) + return -1; + if ((XGIbios_mode[myindex].xres < xres) && + (XGIbios_mode[myindex].yres < yres)) { + if (XGIbios_mode[myindex].bpp > 8) + return -1; + } + + } + goto check_memory; + + } + + /* FIXME: for now, all is valid on XG27 */ + if (xgifb_info->chip == XG27) + goto check_memory; + + if (!(XGIbios_mode[myindex].chipset & MD_XGI315)) + return -1; + + switch (xgifb_info->display2) { + case XGIFB_DISP_LCD: + switch (hw_info->ulCRT2LCDType) { + case LCD_640x480: + xres = 640; + yres = 480; + break; + case LCD_800x600: + xres = 800; + yres = 600; + break; + case LCD_1024x600: + xres = 1024; + yres = 600; + break; + case LCD_1024x768: + xres = 1024; + yres = 768; + break; + case LCD_1152x768: + xres = 1152; + yres = 768; + break; + case LCD_1280x960: + xres = 1280; + yres = 960; + break; + case LCD_1280x768: + xres = 1280; + yres = 768; + break; + case LCD_1280x1024: + xres = 1280; + yres = 1024; + break; + case LCD_1400x1050: + xres = 1400; + yres = 1050; + break; + case LCD_1600x1200: + xres = 1600; + yres = 1200; + break; + default: + xres = 0; + yres = 0; + break; + } + if (XGIbios_mode[myindex].xres > xres) + return -1; + if (XGIbios_mode[myindex].yres > yres) + return -1; + if ((hw_info->ulExternalChip == 0x01) || /* LVDS */ + (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */ + switch (XGIbios_mode[myindex].xres) { + case 512: + if (XGIbios_mode[myindex].yres != 512) + return -1; + if (hw_info->ulCRT2LCDType == LCD_1024x600) + return -1; + break; + case 640: + if ((XGIbios_mode[myindex].yres != 400) + && (XGIbios_mode[myindex].yres + != 480)) + return -1; + break; + case 800: + if (XGIbios_mode[myindex].yres != 600) + return -1; + break; + case 1024: + if ((XGIbios_mode[myindex].yres != 600) && + (XGIbios_mode[myindex].yres != 768)) + return -1; + if ((XGIbios_mode[myindex].yres == 600) && + (hw_info->ulCRT2LCDType != LCD_1024x600)) + return -1; + break; + case 1152: + if ((XGIbios_mode[myindex].yres) != 768) + return -1; + if (hw_info->ulCRT2LCDType != LCD_1152x768) + return -1; + break; + case 1280: + if ((XGIbios_mode[myindex].yres != 768) && + (XGIbios_mode[myindex].yres != 1024)) + return -1; + if ((XGIbios_mode[myindex].yres == 768) && + (hw_info->ulCRT2LCDType != LCD_1280x768)) + return -1; + break; + case 1400: + if (XGIbios_mode[myindex].yres != 1050) + return -1; + break; + case 1600: + if (XGIbios_mode[myindex].yres != 1200) + return -1; + break; + default: + return -1; + } + } else { + switch (XGIbios_mode[myindex].xres) { + case 512: + if (XGIbios_mode[myindex].yres != 512) + return -1; + break; + case 640: + if ((XGIbios_mode[myindex].yres != 400) && + (XGIbios_mode[myindex].yres != 480)) + return -1; + break; + case 800: + if (XGIbios_mode[myindex].yres != 600) + return -1; + break; + case 1024: + if (XGIbios_mode[myindex].yres != 768) + return -1; + break; + case 1280: + if ((XGIbios_mode[myindex].yres != 960) && + (XGIbios_mode[myindex].yres != 1024)) + return -1; + if (XGIbios_mode[myindex].yres == 960) { + if (hw_info->ulCRT2LCDType == + LCD_1400x1050) + return -1; + } + break; + case 1400: + if (XGIbios_mode[myindex].yres != 1050) + return -1; + break; + case 1600: + if (XGIbios_mode[myindex].yres != 1200) + return -1; + break; + default: + return -1; + } + } + break; + case XGIFB_DISP_TV: + switch (XGIbios_mode[myindex].xres) { + case 512: + case 640: + case 800: + break; + case 720: + if (xgifb_info->TV_type == TVMODE_NTSC) { + if (XGIbios_mode[myindex].yres != 480) + return -1; + } else if (xgifb_info->TV_type == TVMODE_PAL) { + if (XGIbios_mode[myindex].yres != 576) + return -1; + } + /* LVDS/CHRONTEL does not support 720 */ + if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL || + xgifb_info->hasVB == HASVB_CHRONTEL) { + return -1; + } + break; + case 1024: + if (xgifb_info->TV_type == TVMODE_NTSC) { + if (XGIbios_mode[myindex].bpp == 32) + return -1; + } + break; + default: + return -1; + } + break; + case XGIFB_DISP_CRT: + if (XGIbios_mode[myindex].xres > 1280) + return -1; + break; + case XGIFB_DISP_NONE: + break; + } + +check_memory: + required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres * + XGIbios_mode[myindex].bpp / 8; + if (required_mem > xgifb_info->video_size) + return -1; + return myindex; + +} + +/* --------------------- SetMode routines ------------------------- */ + +#if IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) + +static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info) +{ + u8 cr30 = 0, cr31 = 0; + + cr31 = xgifb_reg_get(XGICR, 0x31); + cr31 &= ~0x60; + + switch (xgifb_info->display2) { + case XGIFB_DISP_CRT: + cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE); + cr31 |= SIS_DRIVER_MODE; + break; + case XGIFB_DISP_LCD: + cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE); + cr31 |= SIS_DRIVER_MODE; + break; + case XGIFB_DISP_TV: + if (xgifb_info->TV_type == TVMODE_HIVISION) + cr30 = (SIS_VB_OUTPUT_HIVISION + | SIS_SIMULTANEOUS_VIEW_ENABLE); + else if (xgifb_info->TV_plug == TVPLUG_SVIDEO) + cr30 = (SIS_VB_OUTPUT_SVIDEO + | SIS_SIMULTANEOUS_VIEW_ENABLE); + else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE) + cr30 = (SIS_VB_OUTPUT_COMPOSITE + | SIS_SIMULTANEOUS_VIEW_ENABLE); + else if (xgifb_info->TV_plug == TVPLUG_SCART) + cr30 = (SIS_VB_OUTPUT_SCART + | SIS_SIMULTANEOUS_VIEW_ENABLE); + cr31 |= SIS_DRIVER_MODE; + + if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL) + cr31 |= 0x01; + else + cr31 &= ~0x01; + break; + default: /* disable CRT2 */ + cr30 = 0x00; + cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); + } + + xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30); + xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31); + xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, + (xgifb_info->rate_idx & 0x0F)); +} + +static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) +{ + u8 reg; + unsigned char doit = 1; + + if (xgifb_info->video_bpp == 8) { + /* + * We can't switch off CRT1 on LVDS/Chrontel + * in 8bpp Modes + */ + if ((xgifb_info->hasVB == HASVB_LVDS) || + (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) { + doit = 0; + } + /* + * We can't switch off CRT1 on 301B-DH + * in 8bpp Modes if using LCD + */ + if (xgifb_info->display2 == XGIFB_DISP_LCD) + doit = 0; + } + + /* We can't switch off CRT1 if bridge is in slave mode */ + if (xgifb_info->hasVB != HASVB_NONE) { + reg = xgifb_reg_get(XGIPART1, 0x00); + + if ((reg & 0x50) == 0x10) + doit = 0; + + } else { + XGIfb_crt1off = 0; + } + + reg = xgifb_reg_get(XGICR, 0x17); + if ((XGIfb_crt1off) && (doit)) + reg &= ~0x80; + else + reg |= 0x80; + xgifb_reg_set(XGICR, 0x17, reg); + + xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04); + + if (xgifb_info->display2 == XGIFB_DISP_TV && + xgifb_info->hasVB == HASVB_301) { + + reg = xgifb_reg_get(XGIPART4, 0x01); + + if (reg < 0xB0) { /* Set filter for XGI301 */ + int filter_tb; + + switch (xgifb_info->video_width) { + case 320: + filter_tb = (xgifb_info->TV_type == + TVMODE_NTSC) ? 4 : 12; + break; + case 640: + filter_tb = (xgifb_info->TV_type == + TVMODE_NTSC) ? 5 : 13; + break; + case 720: + filter_tb = (xgifb_info->TV_type == + TVMODE_NTSC) ? 6 : 14; + break; + case 800: + filter_tb = (xgifb_info->TV_type == + TVMODE_NTSC) ? 7 : 15; + break; + default: + filter_tb = 0; + filter = -1; + break; + } + xgifb_reg_or(XGIPART1, + SIS_CRT2_WENABLE_315, + 0x01); + + if (xgifb_info->TV_type == TVMODE_NTSC) { + + xgifb_reg_and(XGIPART2, 0x3a, 0x1f); + + if (xgifb_info->TV_plug == TVPLUG_SVIDEO) { + + xgifb_reg_and(XGIPART2, 0x30, 0xdf); + + } else if (xgifb_info->TV_plug + == TVPLUG_COMPOSITE) { + + xgifb_reg_or(XGIPART2, 0x30, 0x20); + + switch (xgifb_info->video_width) { + case 640: + xgifb_reg_set(XGIPART2, + 0x35, + 0xEB); + xgifb_reg_set(XGIPART2, + 0x36, + 0x04); + xgifb_reg_set(XGIPART2, + 0x37, + 0x25); + xgifb_reg_set(XGIPART2, + 0x38, + 0x18); + break; + case 720: + xgifb_reg_set(XGIPART2, + 0x35, + 0xEE); + xgifb_reg_set(XGIPART2, + 0x36, + 0x0C); + xgifb_reg_set(XGIPART2, + 0x37, + 0x22); + xgifb_reg_set(XGIPART2, + 0x38, + 0x08); + break; + case 800: + xgifb_reg_set(XGIPART2, + 0x35, + 0xEB); + xgifb_reg_set(XGIPART2, + 0x36, + 0x15); + xgifb_reg_set(XGIPART2, + 0x37, + 0x25); + xgifb_reg_set(XGIPART2, + 0x38, + 0xF6); + break; + } + } + + } else if (xgifb_info->TV_type == TVMODE_PAL) { + + xgifb_reg_and(XGIPART2, 0x3A, 0x1F); + + if (xgifb_info->TV_plug == TVPLUG_SVIDEO) { + + xgifb_reg_and(XGIPART2, 0x30, 0xDF); + + } else if (xgifb_info->TV_plug + == TVPLUG_COMPOSITE) { + + xgifb_reg_or(XGIPART2, 0x30, 0x20); + + switch (xgifb_info->video_width) { + case 640: + xgifb_reg_set(XGIPART2, + 0x35, + 0xF1); + xgifb_reg_set(XGIPART2, + 0x36, + 0xF7); + xgifb_reg_set(XGIPART2, + 0x37, + 0x1F); + xgifb_reg_set(XGIPART2, + 0x38, + 0x32); + break; + case 720: + xgifb_reg_set(XGIPART2, + 0x35, + 0xF3); + xgifb_reg_set(XGIPART2, + 0x36, + 0x00); + xgifb_reg_set(XGIPART2, + 0x37, + 0x1D); + xgifb_reg_set(XGIPART2, + 0x38, + 0x20); + break; + case 800: + xgifb_reg_set(XGIPART2, + 0x35, + 0xFC); + xgifb_reg_set(XGIPART2, + 0x36, + 0xFB); + xgifb_reg_set(XGIPART2, + 0x37, + 0x14); + xgifb_reg_set(XGIPART2, + 0x38, + 0x2A); + break; + } + } + } + + if ((filter >= 0) && (filter <= 7)) { + pr_debug("FilterTable[%d]-%d: %*ph\n", + filter_tb, filter, + 4, XGI_TV_filter[filter_tb]. + filter[filter]); + xgifb_reg_set( + XGIPART2, + 0x35, + (XGI_TV_filter[filter_tb]. + filter[filter][0])); + xgifb_reg_set( + XGIPART2, + 0x36, + (XGI_TV_filter[filter_tb]. + filter[filter][1])); + xgifb_reg_set( + XGIPART2, + 0x37, + (XGI_TV_filter[filter_tb]. + filter[filter][2])); + xgifb_reg_set( + XGIPART2, + 0x38, + (XGI_TV_filter[filter_tb]. + filter[filter][3])); + } + } + } +} + +#endif
\ No newline at end of file |