1801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan/* 2801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 3801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 4801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 5801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * This program is free software; you can redistribute it and/or 6801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * modify it under the terms of the GNU General Public 7801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * License as published by the Free Software Foundation; 8801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * either version 2, or (at your option) any later version. 9801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 10801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * This program is distributed in the hope that it will be useful, 11801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even 12801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * the implied warranty of MERCHANTABILITY or FITNESS FOR 13801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * A PARTICULAR PURPOSE.See the GNU General Public License 14801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * for more details. 15801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 16801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * You should have received a copy of the GNU General Public License 17801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * along with this program; if not, write to the Free Software 18801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * Foundation, Inc., 19801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan */ 21ec66841e495b9ab4f92bdf91efe8cf56e1471fbdJonathan Corbet#include <linux/via-core.h> 22801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan#include "global.h" 23801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 24f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet/* 25f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet * Figure out an appropriate bytes-per-pixel setting. 26f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet */ 27f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbetstatic int viafb_set_bpp(void __iomem *engine, u8 bpp) 28f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet{ 29f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet u32 gemode; 30f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet 31f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet /* Preserve the reserved bits */ 32f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet /* Lowest 2 bits to zero gives us no rotation */ 33f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet gemode = readl(engine + VIA_REG_GEMODE) & 0xfffffcfc; 34f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet switch (bpp) { 35f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet case 8: 36f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet gemode |= VIA_GEM_8bpp; 37f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet break; 38f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet case 16: 39f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet gemode |= VIA_GEM_16bpp; 40f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet break; 41f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet case 32: 42f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet gemode |= VIA_GEM_32bpp; 43f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet break; 44f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet default: 45f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet printk(KERN_WARNING "viafb_set_bpp: Unsupported bpp %d\n", bpp); 46f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet return -EINVAL; 47f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet } 48f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet writel(gemode, engine + VIA_REG_GEMODE); 49f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet return 0; 50f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet} 51f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet 52f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet 53c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinatstatic int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height, 54c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, 55c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, 56c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat u32 fg_color, u32 bg_color, u8 fill_rop) 57801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan{ 58c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat u32 ge_cmd = 0, tmp, i; 59f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet int ret; 60c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 61c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (!op || op > 3) { 62c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op); 63c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 64c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 65c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 66c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) { 67c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (src_x < dst_x) { 68c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00008000; 69c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat src_x += width - 1; 70c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat dst_x += width - 1; 71c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 72c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (src_y < dst_y) { 73c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00004000; 74c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat src_y += height - 1; 75c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat dst_y += height - 1; 76c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 77c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 78c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 79c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_FILL) { 80c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat switch (fill_rop) { 81c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case 0x00: /* blackness */ 82c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case 0x5A: /* pattern inversion */ 83c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case 0xF0: /* pattern copy */ 84c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case 0xFF: /* whiteness */ 85c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat break; 86c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat default: 87c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_1: Invalid fill rop: " 88c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "%u\n", fill_rop); 89c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 90c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 91c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 92c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 93f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet ret = viafb_set_bpp(engine, dst_bpp); 94f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet if (ret) 95f1b99aa9dbe908b2839885aa999d6e8512fe1040Jonathan Corbet return ret; 96c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 97c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op != VIA_BITBLT_FILL) { 98c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000) 99c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat || src_y & 0xFFFFF000) { 100c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_1: Unsupported source " 101c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "x/y %d %d\n", src_x, src_y); 102c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 103c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 104c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = src_x | (src_y << 16); 105c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x08); 106c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 107c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 108c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) { 109c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_1: Unsupported destination x/y " 110c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "%d %d\n", dst_x, dst_y); 111c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 112c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 113c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = dst_x | (dst_y << 16); 114c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x0C); 115c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 116c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) { 117c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_1: Unsupported width/height " 118c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "%d %d\n", width, height); 119c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 120c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 121c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = (width - 1) | ((height - 1) << 16); 122c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x10); 123c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 124c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op != VIA_BITBLT_COLOR) 125c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(fg_color, engine + 0x18); 126c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 127c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_MONO) 128c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(bg_color, engine + 0x1C); 129c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 130c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op != VIA_BITBLT_FILL) { 131c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = src_mem ? 0 : src_addr; 132c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (dst_addr & 0xE0000007) { 133c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_1: Unsupported source " 134c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "address %X\n", tmp); 135c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 136c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 137c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp >>= 3; 138c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x30); 139c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 140c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 141c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (dst_addr & 0xE0000007) { 142c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_1: Unsupported destination " 143c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "address %X\n", dst_addr); 144c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 145c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 146c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = dst_addr >> 3; 147c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x34); 148c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 149c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_FILL) 150c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = 0; 151c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat else 152c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = src_pitch; 153c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) { 154c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_1: Unsupported pitch %X %X\n", 155c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp, dst_pitch); 156c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 157c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 15897922b5462fa543484831d42ab0fe4562b9373fcErik-Jan Post tmp = VIA_PITCH_ENABLE | (tmp >> 3) | (dst_pitch << (16 - 3)); 159c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x38); 160c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 161c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_FILL) 162c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001; 163c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat else { 164c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */ 165c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (src_mem) 166c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00000040; 167c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_MONO) 168c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000; 169c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat else 170c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00000001; 171c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 172c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(ge_cmd, engine); 173c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 174c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_FILL || !src_mem) 175c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return 0; 176c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 177c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) + 178c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 3) >> 2; 179c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 180c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat for (i = 0; i < tmp; i++) 181c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(src_mem[i], engine + VIA_MMIO_BLTBASE); 182c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 183c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return 0; 184c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat} 185c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 186c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinatstatic int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height, 187c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, 188c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, 189c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat u32 fg_color, u32 bg_color, u8 fill_rop) 190c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat{ 191c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat u32 ge_cmd = 0, tmp, i; 1929ca43cf41d014e12f4b25d4538f362d7513448ddJonathan Corbet int ret; 193c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 194c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (!op || op > 3) { 195c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op); 196c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 197c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 198c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 199c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) { 200c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (src_x < dst_x) { 201c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00008000; 202c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat src_x += width - 1; 203c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat dst_x += width - 1; 204c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 205c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (src_y < dst_y) { 206c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00004000; 207c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat src_y += height - 1; 208c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat dst_y += height - 1; 209c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 210c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 211c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 212c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_FILL) { 213c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat switch (fill_rop) { 214c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case 0x00: /* blackness */ 215c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case 0x5A: /* pattern inversion */ 216c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case 0xF0: /* pattern copy */ 217c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case 0xFF: /* whiteness */ 218c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat break; 219c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat default: 220c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_2: Invalid fill rop: " 221c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "%u\n", fill_rop); 222c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 223c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 224c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 225c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 2269ca43cf41d014e12f4b25d4538f362d7513448ddJonathan Corbet ret = viafb_set_bpp(engine, dst_bpp); 2279ca43cf41d014e12f4b25d4538f362d7513448ddJonathan Corbet if (ret) 2289ca43cf41d014e12f4b25d4538f362d7513448ddJonathan Corbet return ret; 229c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 230c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_FILL) 231c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = 0; 232c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat else 233c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = src_pitch; 234c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) { 235c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_2: Unsupported pitch %X %X\n", 236c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp, dst_pitch); 237c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 238c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 239c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = (tmp >> 3) | (dst_pitch << (16 - 3)); 240c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x08); 241c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 242c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) { 243c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_2: Unsupported width/height " 244c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "%d %d\n", width, height); 245c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 246c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 247c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = (width - 1) | ((height - 1) << 16); 248c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x0C); 249c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 250c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) { 251c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_2: Unsupported destination x/y " 252c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "%d %d\n", dst_x, dst_y); 253c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 254c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 255c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = dst_x | (dst_y << 16); 256c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x10); 257c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 258c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (dst_addr & 0xE0000007) { 259c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_2: Unsupported destination " 260c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "address %X\n", dst_addr); 261c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 262c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 263c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = dst_addr >> 3; 264c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x14); 265c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 266c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op != VIA_BITBLT_FILL) { 267c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000) 268c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat || src_y & 0xFFFFF000) { 269c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_2: Unsupported source " 270c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "x/y %d %d\n", src_x, src_y); 271c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 272c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 273c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = src_x | (src_y << 16); 274c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x18); 275c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 276c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = src_mem ? 0 : src_addr; 277c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (dst_addr & 0xE0000007) { 278c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat printk(KERN_WARNING "hw_bitblt_2: Unsupported source " 279c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat "address %X\n", tmp); 280c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return -EINVAL; 281c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 282c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp >>= 3; 283c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(tmp, engine + 0x1C); 284c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 285c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 286efd4f6398dc92b5bf392670df862f42a19f34cf2Florian Tobias Schandinat if (op == VIA_BITBLT_FILL) { 287efd4f6398dc92b5bf392670df862f42a19f34cf2Florian Tobias Schandinat writel(fg_color, engine + 0x58); 288efd4f6398dc92b5bf392670df862f42a19f34cf2Florian Tobias Schandinat } else if (op == VIA_BITBLT_MONO) { 289c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(fg_color, engine + 0x4C); 290c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(bg_color, engine + 0x50); 291efd4f6398dc92b5bf392670df862f42a19f34cf2Florian Tobias Schandinat } 292c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 293c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_FILL) 294c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001; 295c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat else { 296c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */ 297c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (src_mem) 298c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00000040; 299c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_MONO) 300c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000; 301c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat else 302c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat ge_cmd |= 0x00000001; 303c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 304c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(ge_cmd, engine); 305c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 306c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat if (op == VIA_BITBLT_FILL || !src_mem) 307c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return 0; 308c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 309c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) + 310c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 3) >> 2; 311c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 312c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat for (i = 0; i < tmp; i++) 313c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat writel(src_mem[i], engine + VIA_MMIO_BLTBASE); 314c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 315c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat return 0; 316c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat} 317c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 318adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinatint viafb_setup_engine(struct fb_info *info) 319c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat{ 32031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat struct viafb_par *viapar = info->par; 32131de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat void __iomem *engine; 322adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat u32 chip_name = viapar->shared->chip_info.gfx_chip_name; 32331de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat 32424b4d82e4715841848a499534ed5cb7db3d6bca3Jonathan Corbet engine = viapar->shared->vdev->engine_mmio; 32531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat if (!engine) { 32631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat printk(KERN_WARNING "viafb_init_accel: ioremap failed, " 32731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat "hardware acceleration disabled\n"); 32831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat return -ENOMEM; 32931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat } 33031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat 33131de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat switch (chip_name) { 332c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_CLE266: 333c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_K400: 334c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_K800: 335c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_PM800: 336c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_CN700: 337c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_CX700: 338c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_CN750: 339c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_K8M890: 340c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_P4M890: 341c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_P4M900: 34231de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->shared->hw_bitblt = hw_bitblt_1; 343c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat break; 344c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat case UNICHROME_VX800: 3453a32456909380150a92ed207c160a3a0bd687e14Florian Tobias Schandinat case UNICHROME_VX855: 34651f4332bb5fef869e8a89895a7bac6b4c03b4946Florian Tobias Schandinat case UNICHROME_VX900: 34731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->shared->hw_bitblt = hw_bitblt_2; 348c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat break; 349c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat default: 35031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->shared->hw_bitblt = NULL; 351c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat } 352c3e25673843153ea75fda79a47cf12f10a25ca37Florian Tobias Schandinat 35331de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->fbmem_free -= CURSOR_SIZE; 35431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->shared->cursor_vram_addr = viapar->fbmem_free; 35531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->fbmem_used += CURSOR_SIZE; 356801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 35731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->fbmem_free -= VQ_SIZE; 35831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->shared->vq_vram_addr = viapar->fbmem_free; 35931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat viapar->fbmem_used += VQ_SIZE; 360801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 361024fafbac36b176d978ccd0fb1cae1fbc38c7feeJonathan Corbet#if defined(CONFIG_VIDEO_VIA_CAMERA) || defined(CONFIG_VIDEO_VIA_CAMERA_MODULE) 362c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet /* 363c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet * Set aside a chunk of framebuffer memory for the camera 364c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet * driver. Someday this driver probably needs a proper allocator 365c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet * for fbmem; for now, we just have to do this before the 366c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet * framebuffer initializes itself. 367c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet * 368c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet * As for the size: the engine can handle three frames, 369c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet * 16 bits deep, up to VGA resolution. 370c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet */ 371c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet viapar->shared->vdev->camera_fbmem_size = 3*VGA_HEIGHT*VGA_WIDTH*2; 372c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet viapar->fbmem_free -= viapar->shared->vdev->camera_fbmem_size; 373c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet viapar->fbmem_used += viapar->shared->vdev->camera_fbmem_size; 374c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free; 375c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet#endif 376c2b12cd496bbe5eff6a48bc669fe6b0c56f2b3d9Jonathan Corbet 377adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat viafb_reset_engine(viapar); 378adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat return 0; 379adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat} 380adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat 381adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinatvoid viafb_reset_engine(struct viafb_par *viapar) 382adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat{ 383adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat void __iomem *engine = viapar->shared->vdev->engine_mmio; 384adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat int highest_reg, i; 385adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high, 386adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name; 387adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat 388adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat /* Initialize registers to reset the 2D engine */ 389adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat switch (viapar->shared->chip_info.twod_engine) { 390adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat case VIA_2D_ENG_M1: 391adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat highest_reg = 0x5c; 392adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat break; 393adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat default: 394adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat highest_reg = 0x40; 395adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat break; 396adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat } 397adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat for (i = 0; i <= highest_reg; i += 4) 398adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat writel(0x0, engine + i); 399adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat 400801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan /* Init AGP and VQ regs */ 40131de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat switch (chip_name) { 402801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan case UNICHROME_K8M890: 403801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan case UNICHROME_P4M900: 4041317824376482781200980c6f026ef576d7ed1ddJonathan Corbet case UNICHROME_VX800: 4051317824376482781200980c6f026ef576d7ed1ddJonathan Corbet case UNICHROME_VX855: 40651f4332bb5fef869e8a89895a7bac6b4c03b4946Florian Tobias Schandinat case UNICHROME_VX900: 40731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00100000, engine + VIA_REG_CR_TRANSET); 40831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE); 40931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x02000000, engine + VIA_REG_CR_TRANSPACE); 410801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan break; 411801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 412801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan default: 41331de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00100000, engine + VIA_REG_TRANSET); 41431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00000000, engine + VIA_REG_TRANSPACE); 41531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00333004, engine + VIA_REG_TRANSPACE); 41631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x60000000, engine + VIA_REG_TRANSPACE); 41731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x61000000, engine + VIA_REG_TRANSPACE); 41831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x62000000, engine + VIA_REG_TRANSPACE); 41931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x63000000, engine + VIA_REG_TRANSPACE); 42031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x64000000, engine + VIA_REG_TRANSPACE); 42131de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x7D000000, engine + VIA_REG_TRANSPACE); 42231de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat 42331de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0xFE020000, engine + VIA_REG_TRANSET); 42431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00000000, engine + VIA_REG_TRANSPACE); 425801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan break; 426801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan } 427801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 42831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat /* Enable VQ */ 42931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_start_addr = viapar->shared->vq_vram_addr; 43031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_end_addr = viapar->shared->vq_vram_addr + VQ_SIZE - 1; 43131de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat 43231de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_start_low = 0x50000000 | (vq_start_addr & 0xFFFFFF); 43331de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_end_low = 0x51000000 | (vq_end_addr & 0xFFFFFF); 43431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_high = 0x52000000 | ((vq_start_addr & 0xFF000000) >> 24) | 43531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat ((vq_end_addr & 0xFF000000) >> 16); 43631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_len = 0x53000000 | (VQ_SIZE >> 3); 43731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat 43831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat switch (chip_name) { 43931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat case UNICHROME_K8M890: 44031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat case UNICHROME_P4M900: 4411317824376482781200980c6f026ef576d7ed1ddJonathan Corbet case UNICHROME_VX800: 4421317824376482781200980c6f026ef576d7ed1ddJonathan Corbet case UNICHROME_VX855: 44351f4332bb5fef869e8a89895a7bac6b4c03b4946Florian Tobias Schandinat case UNICHROME_VX900: 44431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_start_low |= 0x20000000; 44531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_end_low |= 0x20000000; 44631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_high |= 0x20000000; 44731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat vq_len |= 0x20000000; 44831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat 44931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00100000, engine + VIA_REG_CR_TRANSET); 45031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(vq_high, engine + VIA_REG_CR_TRANSPACE); 45131de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(vq_start_low, engine + VIA_REG_CR_TRANSPACE); 45231de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(vq_end_low, engine + VIA_REG_CR_TRANSPACE); 45331de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(vq_len, engine + VIA_REG_CR_TRANSPACE); 45431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x74301001, engine + VIA_REG_CR_TRANSPACE); 45531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00000000, engine + VIA_REG_CR_TRANSPACE); 45631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat break; 45731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat default: 45831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00FE0000, engine + VIA_REG_TRANSET); 45931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x080003FE, engine + VIA_REG_TRANSPACE); 46031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0A00027C, engine + VIA_REG_TRANSPACE); 46131de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0B000260, engine + VIA_REG_TRANSPACE); 46231de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0C000274, engine + VIA_REG_TRANSPACE); 46331de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0D000264, engine + VIA_REG_TRANSPACE); 46431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0E000000, engine + VIA_REG_TRANSPACE); 46531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0F000020, engine + VIA_REG_TRANSPACE); 46631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x1000027E, engine + VIA_REG_TRANSPACE); 46731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x110002FE, engine + VIA_REG_TRANSPACE); 46831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x200F0060, engine + VIA_REG_TRANSPACE); 46931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat 47031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x00000006, engine + VIA_REG_TRANSPACE); 47131de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x40008C0F, engine + VIA_REG_TRANSPACE); 47231de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x44000000, engine + VIA_REG_TRANSPACE); 47331de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x45080C04, engine + VIA_REG_TRANSPACE); 47431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x46800408, engine + VIA_REG_TRANSPACE); 47531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat 47631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(vq_high, engine + VIA_REG_TRANSPACE); 47731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(vq_start_low, engine + VIA_REG_TRANSPACE); 47831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(vq_end_low, engine + VIA_REG_TRANSPACE); 47931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(vq_len, engine + VIA_REG_TRANSPACE); 48031de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat break; 481801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan } 482801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 483801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan /* Set Cursor Image Base Address */ 48431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(viapar->shared->cursor_vram_addr, engine + VIA_REG_CURSOR_MODE); 48531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0, engine + VIA_REG_CURSOR_POS); 48631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0, engine + VIA_REG_CURSOR_ORG); 48731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0, engine + VIA_REG_CURSOR_BG); 48831de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat writel(0x0, engine + VIA_REG_CURSOR_FG); 489adac8d65f399b02e8a2222fc75c658e4b8d24f65Florian Tobias Schandinat return; 490801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan} 491801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 492801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chanvoid viafb_show_hw_cursor(struct fb_info *info, int Status) 493801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan{ 49431de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat struct viafb_par *viapar = info->par; 49531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat u32 temp, iga_path = viapar->iga_path; 496801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 49724b4d82e4715841848a499534ed5cb7db3d6bca3Jonathan Corbet temp = readl(viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE); 498801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan switch (Status) { 499801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan case HW_Cursor_ON: 500801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan temp |= 0x1; 501801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan break; 502801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan case HW_Cursor_OFF: 503801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan temp &= 0xFFFFFFFE; 504801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan break; 505801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan } 506801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan switch (iga_path) { 507801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan case IGA2: 508801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan temp |= 0x80000000; 509801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan break; 510801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan case IGA1: 511801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan default: 512801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan temp &= 0x7FFFFFFF; 513801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan } 51424b4d82e4715841848a499534ed5cb7db3d6bca3Jonathan Corbet writel(temp, viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE); 515801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan} 516801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 51731de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinatvoid viafb_wait_engine_idle(struct fb_info *info) 518801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan{ 51931de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat struct viafb_par *viapar = info->par; 520801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan int loop = 0; 5211317824376482781200980c6f026ef576d7ed1ddJonathan Corbet u32 mask; 52224b4d82e4715841848a499534ed5cb7db3d6bca3Jonathan Corbet void __iomem *engine = viapar->shared->vdev->engine_mmio; 523801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 5241317824376482781200980c6f026ef576d7ed1ddJonathan Corbet switch (viapar->shared->chip_info.twod_engine) { 5251317824376482781200980c6f026ef576d7ed1ddJonathan Corbet case VIA_2D_ENG_H5: 5261317824376482781200980c6f026ef576d7ed1ddJonathan Corbet case VIA_2D_ENG_M1: 5271317824376482781200980c6f026ef576d7ed1ddJonathan Corbet mask = VIA_CMD_RGTR_BUSY_M1 | VIA_2D_ENG_BUSY_M1 | 5281317824376482781200980c6f026ef576d7ed1ddJonathan Corbet VIA_3D_ENG_BUSY_M1; 5291317824376482781200980c6f026ef576d7ed1ddJonathan Corbet break; 5301317824376482781200980c6f026ef576d7ed1ddJonathan Corbet default: 53124b4d82e4715841848a499534ed5cb7db3d6bca3Jonathan Corbet while (!(readl(engine + VIA_REG_STATUS) & 5321317824376482781200980c6f026ef576d7ed1ddJonathan Corbet VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { 5331317824376482781200980c6f026ef576d7ed1ddJonathan Corbet loop++; 5341317824376482781200980c6f026ef576d7ed1ddJonathan Corbet cpu_relax(); 5351317824376482781200980c6f026ef576d7ed1ddJonathan Corbet } 5361317824376482781200980c6f026ef576d7ed1ddJonathan Corbet mask = VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY; 5371317824376482781200980c6f026ef576d7ed1ddJonathan Corbet break; 5382bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin } 539801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 54024b4d82e4715841848a499534ed5cb7db3d6bca3Jonathan Corbet while ((readl(engine + VIA_REG_STATUS) & mask) && (loop < MAXLOOP)) { 5412bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin loop++; 542801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan cpu_relax(); 5432bd8c47597b2522795f5eb2e61c22dcfec5dfa6aRoel Kluin } 544801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan 54531de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat if (loop >= MAXLOOP) 54631de59d5e1cd6968ea9d1a19cceefb7a037e46bfFlorian Tobias Schandinat printk(KERN_ERR "viafb_wait_engine_idle: not syncing\n"); 547801b8a8c91ff054cc93fdac65e2f067c22986bbbJoseph Chan} 548