Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.29 279 lines 8.6 kB view raw
1/* 2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 4 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public 7 * License as published by the Free Software Foundation; 8 * either version 2, or (at your option) any later version. 9 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even 12 * the implied warranty of MERCHANTABILITY or FITNESS FOR 13 * A PARTICULAR PURPOSE.See the GNU General Public License 14 * for more details. 15 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 */ 21#include "global.h" 22 23void viafb_init_accel(void) 24{ 25 viaparinfo->fbmem_free -= CURSOR_SIZE; 26 viaparinfo->cursor_start = viaparinfo->fbmem_free; 27 viaparinfo->fbmem_used += CURSOR_SIZE; 28 29 /* Reverse 8*1024 memory space for cursor image */ 30 viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE); 31 viaparinfo->VQ_start = viaparinfo->fbmem_free; 32 viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1; 33 viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); } 34 35void viafb_init_2d_engine(void) 36{ 37 u32 dwVQStartAddr, dwVQEndAddr; 38 u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH; 39 40 /* init 2D engine regs to reset 2D engine */ 41 writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE); 42 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS); 43 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS); 44 writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION); 45 writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR); 46 writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR); 47 writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR); 48 writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL); 49 writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR); 50 writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET); 51 writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL); 52 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); 53 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE); 54 writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH); 55 writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1); 56 57 /* Init AGP and VQ regs */ 58 switch (viaparinfo->chip_info->gfx_chip_name) { 59 case UNICHROME_K8M890: 60 case UNICHROME_P4M900: 61 writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET); 62 writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 63 writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 64 break; 65 66 default: 67 writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET); 68 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 69 writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE); 70 writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 71 writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 72 writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 73 writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 74 writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 75 writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 76 77 writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET); 78 writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE); 79 break; 80 } 81 if (viaparinfo->VQ_start != 0) { 82 /* Enable VQ */ 83 dwVQStartAddr = viaparinfo->VQ_start; 84 dwVQEndAddr = viaparinfo->VQ_end; 85 86 dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); 87 dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); 88 dwVQStartEndH = 0x52000000 | 89 ((dwVQStartAddr & 0xFF000000) >> 24) | 90 ((dwVQEndAddr & 0xFF000000) >> 16); 91 dwVQLen = 0x53000000 | (VQ_SIZE >> 3); 92 switch (viaparinfo->chip_info->gfx_chip_name) { 93 case UNICHROME_K8M890: 94 case UNICHROME_P4M900: 95 dwVQStartL |= 0x20000000; 96 dwVQEndL |= 0x20000000; 97 dwVQStartEndH |= 0x20000000; 98 dwVQLen |= 0x20000000; 99 break; 100 default: 101 break; 102 } 103 104 switch (viaparinfo->chip_info->gfx_chip_name) { 105 case UNICHROME_K8M890: 106 case UNICHROME_P4M900: 107 writel(0x00100000, 108 viaparinfo->io_virt + VIA_REG_CR_TRANSET); 109 writel(dwVQStartEndH, 110 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 111 writel(dwVQStartL, 112 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 113 writel(dwVQEndL, 114 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 115 writel(dwVQLen, 116 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 117 writel(0x74301001, 118 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 119 writel(0x00000000, 120 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 121 break; 122 default: 123 writel(0x00FE0000, 124 viaparinfo->io_virt + VIA_REG_TRANSET); 125 writel(0x080003FE, 126 viaparinfo->io_virt + VIA_REG_TRANSPACE); 127 writel(0x0A00027C, 128 viaparinfo->io_virt + VIA_REG_TRANSPACE); 129 writel(0x0B000260, 130 viaparinfo->io_virt + VIA_REG_TRANSPACE); 131 writel(0x0C000274, 132 viaparinfo->io_virt + VIA_REG_TRANSPACE); 133 writel(0x0D000264, 134 viaparinfo->io_virt + VIA_REG_TRANSPACE); 135 writel(0x0E000000, 136 viaparinfo->io_virt + VIA_REG_TRANSPACE); 137 writel(0x0F000020, 138 viaparinfo->io_virt + VIA_REG_TRANSPACE); 139 writel(0x1000027E, 140 viaparinfo->io_virt + VIA_REG_TRANSPACE); 141 writel(0x110002FE, 142 viaparinfo->io_virt + VIA_REG_TRANSPACE); 143 writel(0x200F0060, 144 viaparinfo->io_virt + VIA_REG_TRANSPACE); 145 146 writel(0x00000006, 147 viaparinfo->io_virt + VIA_REG_TRANSPACE); 148 writel(0x40008C0F, 149 viaparinfo->io_virt + VIA_REG_TRANSPACE); 150 writel(0x44000000, 151 viaparinfo->io_virt + VIA_REG_TRANSPACE); 152 writel(0x45080C04, 153 viaparinfo->io_virt + VIA_REG_TRANSPACE); 154 writel(0x46800408, 155 viaparinfo->io_virt + VIA_REG_TRANSPACE); 156 157 writel(dwVQStartEndH, 158 viaparinfo->io_virt + VIA_REG_TRANSPACE); 159 writel(dwVQStartL, 160 viaparinfo->io_virt + VIA_REG_TRANSPACE); 161 writel(dwVQEndL, 162 viaparinfo->io_virt + VIA_REG_TRANSPACE); 163 writel(dwVQLen, 164 viaparinfo->io_virt + VIA_REG_TRANSPACE); 165 break; 166 } 167 } else { 168 /* Disable VQ */ 169 switch (viaparinfo->chip_info->gfx_chip_name) { 170 case UNICHROME_K8M890: 171 case UNICHROME_P4M900: 172 writel(0x00100000, 173 viaparinfo->io_virt + VIA_REG_CR_TRANSET); 174 writel(0x74301000, 175 viaparinfo->io_virt + VIA_REG_CR_TRANSPACE); 176 break; 177 default: 178 writel(0x00FE0000, 179 viaparinfo->io_virt + VIA_REG_TRANSET); 180 writel(0x00000004, 181 viaparinfo->io_virt + VIA_REG_TRANSPACE); 182 writel(0x40008C0F, 183 viaparinfo->io_virt + VIA_REG_TRANSPACE); 184 writel(0x44000000, 185 viaparinfo->io_virt + VIA_REG_TRANSPACE); 186 writel(0x45080C04, 187 viaparinfo->io_virt + VIA_REG_TRANSPACE); 188 writel(0x46800408, 189 viaparinfo->io_virt + VIA_REG_TRANSPACE); 190 break; 191 } 192 } 193 194 viafb_set_2d_color_depth(viaparinfo->bpp); 195 196 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE); 197 writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE); 198 199 writel(VIA_PITCH_ENABLE | 200 (((viaparinfo->hres * 201 viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres * 202 viaparinfo-> 203 bpp >> 3) >> 3) << 16)), 204 viaparinfo->io_virt + VIA_REG_PITCH); 205} 206 207void viafb_set_2d_color_depth(int bpp) 208{ 209 u32 dwGEMode; 210 211 dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF; 212 213 switch (bpp) { 214 case 16: 215 dwGEMode |= VIA_GEM_16bpp; 216 break; 217 case 32: 218 dwGEMode |= VIA_GEM_32bpp; 219 break; 220 default: 221 dwGEMode |= VIA_GEM_8bpp; 222 break; 223 } 224 225 /* Set BPP and Pitch */ 226 writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE); 227} 228 229void viafb_hw_cursor_init(void) 230{ 231 /* Set Cursor Image Base Address */ 232 writel(viaparinfo->cursor_start, 233 viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 234 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS); 235 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG); 236 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG); 237 writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG); 238} 239 240void viafb_show_hw_cursor(struct fb_info *info, int Status) 241{ 242 u32 temp; 243 u32 iga_path = ((struct viafb_par *)(info->par))->iga_path; 244 245 temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 246 switch (Status) { 247 case HW_Cursor_ON: 248 temp |= 0x1; 249 break; 250 case HW_Cursor_OFF: 251 temp &= 0xFFFFFFFE; 252 break; 253 } 254 switch (iga_path) { 255 case IGA2: 256 temp |= 0x80000000; 257 break; 258 case IGA1: 259 default: 260 temp &= 0x7FFFFFFF; 261 } 262 writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE); 263} 264 265int viafb_wait_engine_idle(void) 266{ 267 int loop = 0; 268 269 while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) & 270 VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)) 271 cpu_relax(); 272 273 while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) & 274 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && 275 (loop++ < MAXLOOP)) 276 cpu_relax(); 277 278 return loop >= MAXLOOP; 279}