@@ -0,0 +1,244 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * 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, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.
+ */
+#include "global.h"
+
+void viafb_init_accel(void)
+{
+ viaparinfo->fbmem_free -= CURSOR_SIZE;
+ viaparinfo->cursor_start = viaparinfo->fbmem_free;
+ viaparinfo->fbmem_used += CURSOR_SIZE;
+
+ /* Reverse 8*1024 memory space for cursor image */
+ viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
+ viaparinfo->VQ_start = viaparinfo->fbmem_free;
+ viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
+ viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
+
+void viafb_init_2d_engine(void)
+{
+ u32 dwVQStartAddr, dwVQEndAddr;
+ u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
+
+ /* init 2D engine regs to reset 2D engine */
+ MMIO_OUT32(VIA_REG_GEMODE, 0x0);
+ MMIO_OUT32(VIA_REG_SRCPOS, 0x0);
+ MMIO_OUT32(VIA_REG_DSTPOS, 0x0);
+ MMIO_OUT32(VIA_REG_DIMENSION, 0x0);
+ MMIO_OUT32(VIA_REG_PATADDR, 0x0);
+ MMIO_OUT32(VIA_REG_FGCOLOR, 0x0);
+ MMIO_OUT32(VIA_REG_BGCOLOR, 0x0);
+ MMIO_OUT32(VIA_REG_CLIPTL, 0x0);
+ MMIO_OUT32(VIA_REG_CLIPBR, 0x0);
+ MMIO_OUT32(VIA_REG_OFFSET, 0x0);
+ MMIO_OUT32(VIA_REG_KEYCONTROL, 0x0);
+ MMIO_OUT32(VIA_REG_SRCBASE, 0x0);
+ MMIO_OUT32(VIA_REG_DSTBASE, 0x0);
+ MMIO_OUT32(VIA_REG_PITCH, 0x0);
+ MMIO_OUT32(VIA_REG_MONOPAT1, 0x0);
+
+ /* Init AGP and VQ regs */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ MMIO_OUT32(VIA_REG_CR_TRANSET, 0x00100000);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, 0x680A0000);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, 0x02000000);
+ break;
+
+ default:
+ MMIO_OUT32(VIA_REG_TRANSET, 0x00100000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x00000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x00333004);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x60000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x61000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x62000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x63000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x64000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x7D000000);
+
+ MMIO_OUT32(VIA_REG_TRANSET, 0xFE020000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x00000000);
+ break;
+ }
+ if (viaparinfo->VQ_start != 0) {
+ /* Enable VQ */
+ dwVQStartAddr = viaparinfo->VQ_start;
+ dwVQEndAddr = viaparinfo->VQ_end;
+
+ dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
+ dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
+ dwVQStartEndH = 0x52000000 |
+ ((dwVQStartAddr & 0xFF000000) >> 24) |
+ ((dwVQEndAddr & 0xFF000000) >> 16);
+ dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ dwVQStartL |= 0x20000000;
+ dwVQEndL |= 0x20000000;
+ dwVQStartEndH |= 0x20000000;
+ dwVQLen |= 0x20000000;
+ break;
+ default:
+ break;
+ }
+
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ MMIO_OUT32(VIA_REG_CR_TRANSET, 0x00100000);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, dwVQStartEndH);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, dwVQStartL);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, dwVQEndL);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, dwVQLen);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, 0x74301001);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, 0x00000000);
+ break;
+ default:
+ MMIO_OUT32(VIA_REG_TRANSET, 0x00FE0000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x080003FE);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x0A00027C);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x0B000260);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x0C000274);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x0D000264);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x0E000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x0F000020);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x1000027E);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x110002FE);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x200F0060);
+
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x00000006);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x40008C0F);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x44000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x45080C04);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x46800408);
+
+ MMIO_OUT32(VIA_REG_TRANSPACE, dwVQStartEndH);
+ MMIO_OUT32(VIA_REG_TRANSPACE, dwVQStartL);
+ MMIO_OUT32(VIA_REG_TRANSPACE, dwVQEndL);
+ MMIO_OUT32(VIA_REG_TRANSPACE, dwVQLen);
+ break;
+ }
+ } else {
+ /* Disable VQ */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ MMIO_OUT32(VIA_REG_CR_TRANSET, 0x00100000);
+ MMIO_OUT32(VIA_REG_CR_TRANSPACE, 0x74301000);
+ break;
+ default:
+ MMIO_OUT32(VIA_REG_TRANSET, 0x00FE0000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x00000004);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x40008C0F);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x44000000);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x45080C04);
+ MMIO_OUT32(VIA_REG_TRANSPACE, 0x46800408);
+ break;
+ }
+ }
+
+ viafb_set_2d_color_depth(viaparinfo->bpp);
+
+ MMIO_OUT32(VIA_REG_SRCBASE, 0x0);
+ MMIO_OUT32(VIA_REG_DSTBASE, 0x0);
+
+ MMIO_OUT32(VIA_REG_PITCH,
+ VIA_PITCH_ENABLE |
+ (((viaparinfo->hres *
+ viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres *
+ viaparinfo->
+ bpp >> 3) >> 3) << 16)));
+}
+
+void viafb_set_2d_color_depth(int bpp)
+{
+ u32 dwGEMode;
+
+ dwGEMode = MMIO_IN32(0x04) & 0xFFFFFCFF;
+
+ switch (bpp) {
+ case 16:
+ dwGEMode |= VIA_GEM_16bpp;
+ break;
+ case 32:
+ dwGEMode |= VIA_GEM_32bpp;
+ break;
+ default:
+ dwGEMode |= VIA_GEM_8bpp;
+ break;
+ }
+
+ /* Set BPP and Pitch */
+ MMIO_OUT32(VIA_REG_GEMODE, dwGEMode);
+}
+
+void viafb_hw_cursor_init(void)
+{
+ /* Set Cursor Image Base Address */
+ MMIO_OUT32(VIA_REG_CURSOR_MODE, viaparinfo->cursor_start);
+ MMIO_OUT32(VIA_REG_CURSOR_POS, 0x0);
+ MMIO_OUT32(VIA_REG_CURSOR_ORG, 0x0);
+ MMIO_OUT32(VIA_REG_CURSOR_BG, 0x0);
+ MMIO_OUT32(VIA_REG_CURSOR_FG, 0x0);
+}
+
+void viafb_show_hw_cursor(struct fb_info *info, int Status) {
+ u32 temp;
+ u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
+
+ temp = MMIO_IN32(VIA_REG_CURSOR_MODE);
+ switch (Status) {
+ case HW_Cursor_ON:
+ temp |= 0x1;
+ break;
+ case HW_Cursor_OFF:
+ temp &= 0xFFFFFFFE;
+ break;
+ }
+ switch (iga_path) {
+ case IGA2:
+ temp |= 0x80000000;
+ break;
+ case IGA1:
+ default:
+ temp &= 0x7FFFFFFF;
+ }
+ MMIO_OUT32(VIA_REG_CURSOR_MODE, temp); }
+
+int viafb_wait_engine_idle(void)
+{
+ int loop = 0;
+
+ while (!(MMIO_IN32(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)
+ && (loop++ < MAXLOOP))
+ cpu_relax();
+
+ while ((MMIO_IN32(VIA_REG_STATUS) &
+ (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
+ (loop++ < MAXLOOP))
+ cpu_relax();
+
+ return loop >= MAXLOOP;
+}