Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/via-core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "global.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Figure out an appropriate bytes-per-pixel setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) static int viafb_set_bpp(void __iomem *engine, u8 bpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	u32 gemode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	/* Preserve the reserved bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	/* Lowest 2 bits to zero gives us no rotation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	gemode = readl(engine + VIA_REG_GEMODE) & 0xfffffcfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	switch (bpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		gemode |= VIA_GEM_8bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		gemode |= VIA_GEM_16bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		gemode |= VIA_GEM_32bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		printk(KERN_WARNING "viafb_set_bpp: Unsupported bpp %d\n", bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	writel(gemode, engine + VIA_REG_GEMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	u32 fg_color, u32 bg_color, u8 fill_rop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	u32 ge_cmd = 0, tmp, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	if (!op || op > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		if (src_x < dst_x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			ge_cmd |= 0x00008000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			src_x += width - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			dst_x += width - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		if (src_y < dst_y) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			ge_cmd |= 0x00004000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			src_y += height - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			dst_y += height - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	if (op == VIA_BITBLT_FILL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		switch (fill_rop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		case 0x00: /* blackness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		case 0x5A: /* pattern inversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		case 0xF0: /* pattern copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		case 0xFF: /* whiteness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			printk(KERN_WARNING "hw_bitblt_1: Invalid fill rop: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				"%u\n", fill_rop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	ret = viafb_set_bpp(engine, dst_bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (op != VIA_BITBLT_FILL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			|| src_y & 0xFFFFF000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			printk(KERN_WARNING "hw_bitblt_1: Unsupported source "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				"x/y %d %d\n", src_x, src_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		tmp = src_x | (src_y << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		writel(tmp, engine + 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		printk(KERN_WARNING "hw_bitblt_1: Unsupported destination x/y "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			"%d %d\n", dst_x, dst_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	tmp = dst_x | (dst_y << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	writel(tmp, engine + 0x0C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		printk(KERN_WARNING "hw_bitblt_1: Unsupported width/height "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			"%d %d\n", width, height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	tmp = (width - 1) | ((height - 1) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	writel(tmp, engine + 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	if (op != VIA_BITBLT_COLOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		writel(fg_color, engine + 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	if (op == VIA_BITBLT_MONO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		writel(bg_color, engine + 0x1C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (op != VIA_BITBLT_FILL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		tmp = src_mem ? 0 : src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		if (dst_addr & 0xE0000007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			printk(KERN_WARNING "hw_bitblt_1: Unsupported source "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 				"address %X\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		tmp >>= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		writel(tmp, engine + 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (dst_addr & 0xE0000007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		printk(KERN_WARNING "hw_bitblt_1: Unsupported destination "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			"address %X\n", dst_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	tmp = dst_addr >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	writel(tmp, engine + 0x34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	if (op == VIA_BITBLT_FILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		tmp = src_pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		printk(KERN_WARNING "hw_bitblt_1: Unsupported pitch %X %X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			tmp, dst_pitch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	tmp = VIA_PITCH_ENABLE | (tmp >> 3) | (dst_pitch << (16 - 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	writel(tmp, engine + 0x38);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (op == VIA_BITBLT_FILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		if (src_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			ge_cmd |= 0x00000040;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		if (op == VIA_BITBLT_MONO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			ge_cmd |= 0x00000001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	writel(ge_cmd, engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (op == VIA_BITBLT_FILL || !src_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		3) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	for (i = 0; i < tmp; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		writel(src_mem[i], engine + VIA_MMIO_BLTBASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	u32 fg_color, u32 bg_color, u8 fill_rop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	u32 ge_cmd = 0, tmp, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (!op || op > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		if (src_x < dst_x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			ge_cmd |= 0x00008000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			src_x += width - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			dst_x += width - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		if (src_y < dst_y) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			ge_cmd |= 0x00004000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			src_y += height - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			dst_y += height - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (op == VIA_BITBLT_FILL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		switch (fill_rop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		case 0x00: /* blackness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		case 0x5A: /* pattern inversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		case 0xF0: /* pattern copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		case 0xFF: /* whiteness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			printk(KERN_WARNING "hw_bitblt_2: Invalid fill rop: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				"%u\n", fill_rop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	ret = viafb_set_bpp(engine, dst_bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (op == VIA_BITBLT_FILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		tmp = src_pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		printk(KERN_WARNING "hw_bitblt_2: Unsupported pitch %X %X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			tmp, dst_pitch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	tmp = (tmp >> 3) | (dst_pitch << (16 - 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	writel(tmp, engine + 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		printk(KERN_WARNING "hw_bitblt_2: Unsupported width/height "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			"%d %d\n", width, height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	tmp = (width - 1) | ((height - 1) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	writel(tmp, engine + 0x0C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		printk(KERN_WARNING "hw_bitblt_2: Unsupported destination x/y "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			"%d %d\n", dst_x, dst_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	tmp = dst_x | (dst_y << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	writel(tmp, engine + 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (dst_addr & 0xE0000007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		printk(KERN_WARNING "hw_bitblt_2: Unsupported destination "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			"address %X\n", dst_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	tmp = dst_addr >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	writel(tmp, engine + 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if (op != VIA_BITBLT_FILL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			|| src_y & 0xFFFFF000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			printk(KERN_WARNING "hw_bitblt_2: Unsupported source "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 				"x/y %d %d\n", src_x, src_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		tmp = src_x | (src_y << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		writel(tmp, engine + 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		tmp = src_mem ? 0 : src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		if (dst_addr & 0xE0000007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			printk(KERN_WARNING "hw_bitblt_2: Unsupported source "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 				"address %X\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		tmp >>= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		writel(tmp, engine + 0x1C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (op == VIA_BITBLT_FILL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		writel(fg_color, engine + 0x58);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	} else if (op == VIA_BITBLT_MONO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		writel(fg_color, engine + 0x4C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		writel(bg_color, engine + 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (op == VIA_BITBLT_FILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		if (src_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			ge_cmd |= 0x00000040;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		if (op == VIA_BITBLT_MONO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			ge_cmd |= 0x00000001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	writel(ge_cmd, engine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (op == VIA_BITBLT_FILL || !src_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		3) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	for (i = 0; i < tmp; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		writel(src_mem[i], engine + VIA_MMIO_BLTBASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int viafb_setup_engine(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	struct viafb_par *viapar = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	void __iomem *engine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	u32 chip_name = viapar->shared->chip_info.gfx_chip_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	engine = viapar->shared->vdev->engine_mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (!engine) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		printk(KERN_WARNING "viafb_init_accel: ioremap failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			"hardware acceleration disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	switch (chip_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	case UNICHROME_CLE266:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	case UNICHROME_K400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	case UNICHROME_K800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	case UNICHROME_PM800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	case UNICHROME_CN700:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	case UNICHROME_CX700:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	case UNICHROME_CN750:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	case UNICHROME_K8M890:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	case UNICHROME_P4M890:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	case UNICHROME_P4M900:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		viapar->shared->hw_bitblt = hw_bitblt_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	case UNICHROME_VX800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	case UNICHROME_VX855:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	case UNICHROME_VX900:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		viapar->shared->hw_bitblt = hw_bitblt_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		viapar->shared->hw_bitblt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	viapar->fbmem_free -= CURSOR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	viapar->shared->cursor_vram_addr = viapar->fbmem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	viapar->fbmem_used += CURSOR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	viapar->fbmem_free -= VQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	viapar->shared->vq_vram_addr = viapar->fbmem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	viapar->fbmem_used += VQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #if IS_ENABLED(CONFIG_VIDEO_VIA_CAMERA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	 * Set aside a chunk of framebuffer memory for the camera
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	 * driver.  Someday this driver probably needs a proper allocator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	 * for fbmem; for now, we just have to do this before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	 * framebuffer initializes itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	 * As for the size: the engine can handle three frames,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	 * 16 bits deep, up to VGA resolution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	viapar->shared->vdev->camera_fbmem_size = 3*VGA_HEIGHT*VGA_WIDTH*2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	viapar->fbmem_free -= viapar->shared->vdev->camera_fbmem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	viapar->fbmem_used += viapar->shared->vdev->camera_fbmem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	viafb_reset_engine(viapar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) void viafb_reset_engine(struct viafb_par *viapar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	void __iomem *engine = viapar->shared->vdev->engine_mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	int highest_reg, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	/* Initialize registers to reset the 2D engine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	switch (viapar->shared->chip_info.twod_engine) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	case VIA_2D_ENG_M1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		highest_reg = 0x5c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		highest_reg = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	for (i = 0; i <= highest_reg; i += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		writel(0x0, engine + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	/* Init AGP and VQ regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	switch (chip_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	case UNICHROME_K8M890:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	case UNICHROME_P4M900:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	case UNICHROME_VX800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	case UNICHROME_VX855:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	case UNICHROME_VX900:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		writel(0x00100000, engine + VIA_REG_CR_TRANSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		writel(0x02000000, engine + VIA_REG_CR_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		writel(0x00100000, engine + VIA_REG_TRANSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		writel(0x00000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		writel(0x00333004, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		writel(0x60000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		writel(0x61000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		writel(0x62000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		writel(0x63000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		writel(0x64000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		writel(0x7D000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		writel(0xFE020000, engine + VIA_REG_TRANSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		writel(0x00000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	/* Enable VQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	vq_start_addr = viapar->shared->vq_vram_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	vq_end_addr = viapar->shared->vq_vram_addr + VQ_SIZE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	vq_start_low = 0x50000000 | (vq_start_addr & 0xFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	vq_end_low = 0x51000000 | (vq_end_addr & 0xFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	vq_high = 0x52000000 | ((vq_start_addr & 0xFF000000) >> 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		((vq_end_addr & 0xFF000000) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	vq_len = 0x53000000 | (VQ_SIZE >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	switch (chip_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	case UNICHROME_K8M890:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	case UNICHROME_P4M900:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	case UNICHROME_VX800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	case UNICHROME_VX855:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	case UNICHROME_VX900:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		vq_start_low |= 0x20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		vq_end_low |= 0x20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		vq_high |= 0x20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		vq_len |= 0x20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		writel(0x00100000, engine + VIA_REG_CR_TRANSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		writel(vq_high, engine + VIA_REG_CR_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		writel(vq_start_low, engine + VIA_REG_CR_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		writel(vq_end_low, engine + VIA_REG_CR_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		writel(vq_len, engine + VIA_REG_CR_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		writel(0x74301001, engine + VIA_REG_CR_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		writel(0x00000000, engine + VIA_REG_CR_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		writel(0x00FE0000, engine + VIA_REG_TRANSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		writel(0x080003FE, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		writel(0x0A00027C, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		writel(0x0B000260, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		writel(0x0C000274, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		writel(0x0D000264, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		writel(0x0E000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		writel(0x0F000020, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		writel(0x1000027E, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		writel(0x110002FE, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		writel(0x200F0060, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		writel(0x00000006, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		writel(0x40008C0F, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		writel(0x44000000, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		writel(0x45080C04, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		writel(0x46800408, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		writel(vq_high, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		writel(vq_start_low, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		writel(vq_end_low, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		writel(vq_len, engine + VIA_REG_TRANSPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	/* Set Cursor Image Base Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	writel(viapar->shared->cursor_vram_addr, engine + VIA_REG_CURSOR_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	writel(0x0, engine + VIA_REG_CURSOR_POS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	writel(0x0, engine + VIA_REG_CURSOR_ORG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	writel(0x0, engine + VIA_REG_CURSOR_BG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	writel(0x0, engine + VIA_REG_CURSOR_FG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) void viafb_show_hw_cursor(struct fb_info *info, int Status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	struct viafb_par *viapar = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	u32 temp, iga_path = viapar->iga_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	temp = readl(viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	switch (Status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	case HW_Cursor_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		temp |= 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	case HW_Cursor_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		temp &= 0xFFFFFFFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	switch (iga_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	case IGA2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		temp |= 0x80000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	case IGA1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		temp &= 0x7FFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	writel(temp, viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) void viafb_wait_engine_idle(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	struct viafb_par *viapar = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	int loop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	void __iomem *engine = viapar->shared->vdev->engine_mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	switch (viapar->shared->chip_info.twod_engine) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	case VIA_2D_ENG_H5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	case VIA_2D_ENG_M1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		mask = VIA_CMD_RGTR_BUSY_M1 | VIA_2D_ENG_BUSY_M1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 			      VIA_3D_ENG_BUSY_M1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		while (!(readl(engine + VIA_REG_STATUS) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 				VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 			loop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		mask = VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	while ((readl(engine + VIA_REG_STATUS) & mask) && (loop < MAXLOOP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		loop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	if (loop >= MAXLOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		printk(KERN_ERR "viafb_wait_engine_idle: not syncing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }