^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * drivers/video/imsttfb.c -- frame buffer device for IMS TwinTurbo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file is derived from the powermac console "imstt" driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1997 Sigurdur Asgeirsson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * With additional hacking by Jeffrey Kuskin (jsk@mojave.stanford.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Modified by Danilo Beuche 1998
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Some register values added by Damien Doligez, INRIA Rocquencourt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Various cleanups by Paul Mundt (lethal@chaoticdreams.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This file was written by Ryan Nielsen (ran@krazynet.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Most of the frame buffer device stuff was copied from atyfb.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * License. See the file COPYING in the main directory of this archive for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #if defined(CONFIG_PPC_PMAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/nvram.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "macmodes.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifndef __powerpc__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define eieio() /* Enforce In-order Execution of I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* TwinTurbo (Cosmo) registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) S1SA = 0, /* 0x00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) S2SA = 1, /* 0x04 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) SP = 2, /* 0x08 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) DSA = 3, /* 0x0C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) CNT = 4, /* 0x10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) DP_OCTL = 5, /* 0x14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) CLR = 6, /* 0x18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) BI = 8, /* 0x20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) MBC = 9, /* 0x24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) BLTCTL = 10, /* 0x28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Scan Timing Generator Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) HES = 12, /* 0x30 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) HEB = 13, /* 0x34 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) HSB = 14, /* 0x38 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) HT = 15, /* 0x3C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) VES = 16, /* 0x40 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) VEB = 17, /* 0x44 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) VSB = 18, /* 0x48 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) VT = 19, /* 0x4C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) HCIV = 20, /* 0x50 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) VCIV = 21, /* 0x54 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) TCDR = 22, /* 0x58 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) VIL = 23, /* 0x5C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) STGCTL = 24, /* 0x60 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Screen Refresh Generator Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) SSR = 25, /* 0x64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) HRIR = 26, /* 0x68 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) SPR = 27, /* 0x6C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) CMR = 28, /* 0x70 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) SRGCTL = 29, /* 0x74 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* RAM Refresh Generator Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) RRCIV = 30, /* 0x78 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) RRSC = 31, /* 0x7C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) RRCR = 34, /* 0x88 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* System Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) GIOE = 32, /* 0x80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) GIO = 33, /* 0x84 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) SCR = 35, /* 0x8C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) SSTATUS = 36, /* 0x90 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) PRC = 37, /* 0x94 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* PCI Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) DVID = 0x00000000L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) SC = 0x00000004L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) CCR = 0x00000008L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) OG = 0x0000000CL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) BARM = 0x00000010L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) BARER = 0x00000030L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* IBM 624 RAMDAC Direct Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) PADDRW = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) PDATA = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) PPMASK = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) PADDRR = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) PIDXLO = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) PIDXHI = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) PIDXDATA= 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) PIDXCTL = 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* IBM 624 RAMDAC Indirect Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) CLKCTL = 0x02, /* (0x01) Miscellaneous Clock Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) SYNCCTL = 0x03, /* (0x00) Sync Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) HSYNCPOS = 0x04, /* (0x00) Horizontal Sync Position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) PWRMNGMT = 0x05, /* (0x00) Power Management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) DACOP = 0x06, /* (0x02) DAC Operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) PALETCTL = 0x07, /* (0x00) Palette Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) SYSCLKCTL = 0x08, /* (0x01) System Clock Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) PIXFMT = 0x0a, /* () Pixel Format [bpp >> 3 + 2] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) BPP8 = 0x0b, /* () 8 Bits/Pixel Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) BPP16 = 0x0c, /* () 16 Bits/Pixel Control [bit 1=1 for 565] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) BPP24 = 0x0d, /* () 24 Bits/Pixel Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) BPP32 = 0x0e, /* () 32 Bits/Pixel Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) PIXCTL1 = 0x10, /* (0x05) Pixel PLL Control 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) PIXCTL2 = 0x11, /* (0x00) Pixel PLL Control 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) SYSCLKN = 0x15, /* () System Clock N (System PLL Reference Divider) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) SYSCLKM = 0x16, /* () System Clock M (System PLL VCO Divider) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) SYSCLKP = 0x17, /* () System Clock P */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) SYSCLKC = 0x18, /* () System Clock C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Dot clock rate is 20MHz * (m + 1) / ((n + 1) * (p ? 2 * p : 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * c is charge pump bias which depends on the VCO frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) PIXM0 = 0x20, /* () Pixel M 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) PIXN0 = 0x21, /* () Pixel N 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) PIXP0 = 0x22, /* () Pixel P 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) PIXC0 = 0x23, /* () Pixel C 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) CURSCTL = 0x30, /* (0x00) Cursor Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) CURSXLO = 0x31, /* () Cursor X position, low 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) CURSXHI = 0x32, /* () Cursor X position, high 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) CURSYLO = 0x33, /* () Cursor Y position, low 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) CURSYHI = 0x34, /* () Cursor Y position, high 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) CURSHOTX = 0x35, /* () Cursor Hot Spot X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) CURSHOTY = 0x36, /* () Cursor Hot Spot Y */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) CURSACCTL = 0x37, /* () Advanced Cursor Control Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) CURSACATTR = 0x38, /* () Advanced Cursor Attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) CURS1R = 0x40, /* () Cursor 1 Red */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) CURS1G = 0x41, /* () Cursor 1 Green */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) CURS1B = 0x42, /* () Cursor 1 Blue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) CURS2R = 0x43, /* () Cursor 2 Red */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) CURS2G = 0x44, /* () Cursor 2 Green */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) CURS2B = 0x45, /* () Cursor 2 Blue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) CURS3R = 0x46, /* () Cursor 3 Red */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) CURS3G = 0x47, /* () Cursor 3 Green */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) CURS3B = 0x48, /* () Cursor 3 Blue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) BORDR = 0x60, /* () Border Color Red */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) BORDG = 0x61, /* () Border Color Green */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) BORDB = 0x62, /* () Border Color Blue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) MISCTL1 = 0x70, /* (0x00) Miscellaneous Control 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) MISCTL2 = 0x71, /* (0x00) Miscellaneous Control 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) MISCTL3 = 0x72, /* (0x00) Miscellaneous Control 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) KEYCTL = 0x78 /* (0x00) Key Control/DB Operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* TI TVP 3030 RAMDAC Direct Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) TVPADDRW = 0x00, /* 0 Palette/Cursor RAM Write Address/Index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) TVPPDATA = 0x04, /* 1 Palette Data RAM Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) TVPPMASK = 0x08, /* 2 Pixel Read-Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) TVPPADRR = 0x0c, /* 3 Palette/Cursor RAM Read Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) TVPCADRW = 0x10, /* 4 Cursor/Overscan Color Write Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) TVPCDATA = 0x14, /* 5 Cursor/Overscan Color Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* 6 reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) TVPCADRR = 0x1c, /* 7 Cursor/Overscan Color Read Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* 8 reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) TVPDCCTL = 0x24, /* 9 Direct Cursor Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) TVPIDATA = 0x28, /* 10 Index Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) TVPCRDAT = 0x2c, /* 11 Cursor RAM Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) TVPCXPOL = 0x30, /* 12 Cursor-Position X LSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) TVPCXPOH = 0x34, /* 13 Cursor-Position X MSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) TVPCYPOL = 0x38, /* 14 Cursor-Position Y LSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) TVPCYPOH = 0x3c, /* 15 Cursor-Position Y MSB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* TI TVP 3030 RAMDAC Indirect Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) TVPIRREV = 0x01, /* Silicon Revision [RO] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) TVPIRICC = 0x06, /* Indirect Cursor Control (0x00) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) TVPIRBRC = 0x07, /* Byte Router Control (0xe4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) TVPIRLAC = 0x0f, /* Latch Control (0x06) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) TVPIRTCC = 0x18, /* True Color Control (0x80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) TVPIRMXC = 0x19, /* Multiplex Control (0x98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) TVPIRCLS = 0x1a, /* Clock Selection (0x07) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) TVPIRPPG = 0x1c, /* Palette Page (0x00) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) TVPIRGEC = 0x1d, /* General Control (0x00) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) TVPIRMIC = 0x1e, /* Miscellaneous Control (0x00) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) TVPIRPLA = 0x2c, /* PLL Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) TVPIRPPD = 0x2d, /* Pixel Clock PLL Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) TVPIRMPD = 0x2e, /* Memory Clock PLL Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) TVPIRLPD = 0x2f, /* Loop Clock PLL Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) TVPIRCKL = 0x30, /* Color-Key Overlay Low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) TVPIRCKH = 0x31, /* Color-Key Overlay High */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) TVPIRCRL = 0x32, /* Color-Key Red Low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) TVPIRCRH = 0x33, /* Color-Key Red High */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) TVPIRCGL = 0x34, /* Color-Key Green Low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) TVPIRCGH = 0x35, /* Color-Key Green High */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) TVPIRCBL = 0x36, /* Color-Key Blue Low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) TVPIRCBH = 0x37, /* Color-Key Blue High */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) TVPIRCKC = 0x38, /* Color-Key Control (0x00) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) TVPIRMLC = 0x39, /* MCLK/Loop Clock Control (0x18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) TVPIRSEN = 0x3a, /* Sense Test (0x00) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) TVPIRTMD = 0x3b, /* Test Mode Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) TVPIRRML = 0x3c, /* CRC Remainder LSB [RO] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) TVPIRRMM = 0x3d, /* CRC Remainder MSB [RO] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) TVPIRRMS = 0x3e, /* CRC Bit Select [WO] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) TVPIRDID = 0x3f, /* Device ID [RO] (0x30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) TVPIRRES = 0xff /* Software Reset [WO] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct initvalues {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) __u8 addr, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static struct initvalues ibm_initregs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) { CLKCTL, 0x21 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) { SYNCCTL, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { HSYNCPOS, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) { PWRMNGMT, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { DACOP, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { PALETCTL, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { SYSCLKCTL, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Note that colors in X are correct only if all video data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * passed through the palette in the DAC. That is, "indirect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * color" must be configured. This is the case for the IBM DAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * used in the 2MB and 4MB cards, at least.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) { BPP8, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) { BPP16, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) { BPP24, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) { BPP32, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) { PIXCTL1, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) { PIXCTL2, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) { SYSCLKN, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { SYSCLKM, 0x4f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { SYSCLKP, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { SYSCLKC, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { CURSCTL, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { CURSACCTL, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { CURSACATTR, 0xa8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { CURS1R, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { CURS1G, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) { CURS1B, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { CURS2R, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { CURS2G, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) { CURS2B, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) { CURS3R, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) { CURS3G, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) { CURS3B, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) { BORDR, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) { BORDG, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) { BORDB, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) { MISCTL1, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) { MISCTL2, 0x45 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) { MISCTL3, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) { KEYCTL, 0x00 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static struct initvalues tvp_initregs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) { TVPIRICC, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) { TVPIRBRC, 0xe4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) { TVPIRLAC, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) { TVPIRTCC, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) { TVPIRMXC, 0x4d },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { TVPIRCLS, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { TVPIRPPG, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { TVPIRGEC, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { TVPIRMIC, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) { TVPIRCKL, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) { TVPIRCKH, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { TVPIRCRL, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) { TVPIRCRH, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) { TVPIRCGL, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) { TVPIRCGH, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) { TVPIRCBL, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) { TVPIRCBH, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) { TVPIRCKC, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) { TVPIRPLA, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) { TVPIRPPD, 0xc0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) { TVPIRPPD, 0xd5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) { TVPIRPPD, 0xea },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { TVPIRPLA, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { TVPIRMPD, 0xb9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { TVPIRMPD, 0x3a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { TVPIRMPD, 0xb1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) { TVPIRPLA, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) { TVPIRLPD, 0xc1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) { TVPIRLPD, 0x3d },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) { TVPIRLPD, 0xf3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct imstt_regvals {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) __u32 pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) __u16 hes, heb, hsb, ht, ves, veb, vsb, vt, vil;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) __u8 pclk_m, pclk_n, pclk_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Values of the tvp which change depending on colormode x resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) __u8 mlc[3]; /* Memory Loop Config 0x39 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) __u8 lckl_p[3]; /* P value of LCKL PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct imstt_par {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct imstt_regvals init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) __u32 __iomem *dc_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned long cmap_regs_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) __u8 *cmap_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) __u32 ramdac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) __u32 palette[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) IBM = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) TVP = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) #define INIT_BPP 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #define INIT_XRES 640
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) #define INIT_YRES 480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int inverse = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static char fontname[40] __initdata = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #if defined(CONFIG_PPC_PMAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static signed char init_vmode = -1, init_cmode = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static struct imstt_regvals tvp_reg_init_2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 0x0002, 0x0006, 0x0026, 0x0028, 0x0003, 0x0016, 0x0196, 0x0197, 0x0196,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 0xec, 0x2a, 0xf3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) { 0x3c, 0x3b, 0x39 }, { 0xf3, 0xf3, 0xf3 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static struct imstt_regvals tvp_reg_init_6 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 0x0004, 0x0009, 0x0031, 0x0036, 0x0003, 0x002a, 0x020a, 0x020d, 0x020a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 0xef, 0x2e, 0xb2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) { 0x39, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static struct imstt_regvals tvp_reg_init_12 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 0x0005, 0x000e, 0x0040, 0x0042, 0x0003, 0x018, 0x270, 0x271, 0x270,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 0xf6, 0x2e, 0xf2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) { 0x3a, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static struct imstt_regvals tvp_reg_init_13 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 832,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 0x0004, 0x0011, 0x0045, 0x0048, 0x0003, 0x002a, 0x029a, 0x029b, 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 0xfe, 0x3e, 0xf1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
^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) static struct imstt_regvals tvp_reg_init_17 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 0x0006, 0x0210, 0x0250, 0x0053, 0x1003, 0x0021, 0x0321, 0x0324, 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 0xfc, 0x3a, 0xf1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static struct imstt_regvals tvp_reg_init_18 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 1152,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 0x0009, 0x0011, 0x059, 0x5b, 0x0003, 0x0031, 0x0397, 0x039a, 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 0xfd, 0x3a, 0xf1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static struct imstt_regvals tvp_reg_init_19 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 1280,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 0x0009, 0x0016, 0x0066, 0x0069, 0x0003, 0x0027, 0x03e7, 0x03e8, 0x03e7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 0xf7, 0x36, 0xf0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) { 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static struct imstt_regvals tvp_reg_init_20 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 1280,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 0x0009, 0x0018, 0x0068, 0x006a, 0x0003, 0x0029, 0x0429, 0x042a, 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 0xf0, 0x2d, 0xf0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) { 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * PCI driver prototypes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void imsttfb_remove(struct pci_dev *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * Register access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static inline u32 read_reg_le32(volatile u32 __iomem *base, int regindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) #ifdef __powerpc__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return in_le32(base + regindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return readl(base + regindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static inline void write_reg_le32(volatile u32 __iomem *base, int regindex, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) #ifdef __powerpc__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) out_le32(base + regindex, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) writel(val, base + regindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static __u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) getclkMHz(struct imstt_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) __u32 clk_m, clk_n, clk_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) clk_m = par->init.pclk_m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) clk_n = par->init.pclk_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) clk_p = par->init.pclk_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) setclkMHz(struct imstt_par *par, __u32 MHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) __u32 clk_m, clk_n, x, stage, spilled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) clk_m = clk_n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) stage = spilled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) switch (stage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) clk_m++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) clk_n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) x = 20 * (clk_m + 1) / (clk_n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (x == MHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (x > MHz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) spilled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) stage = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) } else if (spilled && x < MHz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) stage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) par->init.pclk_m = clk_m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) par->init.pclk_n = clk_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) par->init.pclk_p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static struct imstt_regvals *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) compute_imstt_regvals_ibm(struct imstt_par *par, int xres, int yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct imstt_regvals *init = &par->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) __u32 MHz, hes, heb, veb, htp, vtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) switch (xres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) case 640:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) hes = 0x0008; heb = 0x0012; veb = 0x002a; htp = 10; vtp = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) MHz = 30 /* .25 */ ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case 832:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) hes = 0x0005; heb = 0x0020; veb = 0x0028; htp = 8; vtp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) MHz = 57 /* .27_ */ ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case 1024:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) hes = 0x000a; heb = 0x001c; veb = 0x0020; htp = 8; vtp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) MHz = 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) case 1152:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) hes = 0x0012; heb = 0x0022; veb = 0x0031; htp = 4; vtp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) MHz = 101 /* .6_ */ ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case 1280:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) hes = 0x0012; heb = 0x002f; veb = 0x0029; htp = 4; vtp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) MHz = yres == 960 ? 126 : 135;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case 1600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) hes = 0x0018; heb = 0x0040; veb = 0x002a; htp = 4; vtp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) MHz = 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) setclkMHz(par, MHz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) init->hes = hes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) init->heb = heb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) init->hsb = init->heb + (xres >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) init->ht = init->hsb + htp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) init->ves = 0x0003;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) init->veb = veb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) init->vsb = init->veb + yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) init->vt = init->vsb + vtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) init->vil = init->vsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) init->pitch = xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static struct imstt_regvals *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) compute_imstt_regvals_tvp(struct imstt_par *par, int xres, int yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct imstt_regvals *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) switch (xres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) case 512:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) init = &tvp_reg_init_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) case 640:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) init = &tvp_reg_init_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case 800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) init = &tvp_reg_init_12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) case 832:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) init = &tvp_reg_init_13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case 1024:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) init = &tvp_reg_init_17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) case 1152:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) init = &tvp_reg_init_18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) case 1280:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) init = yres == 960 ? &tvp_reg_init_19 : &tvp_reg_init_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) par->init = *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static struct imstt_regvals *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) compute_imstt_regvals (struct imstt_par *par, u_int xres, u_int yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (par->ramdac == IBM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return compute_imstt_regvals_ibm(par, xres, yres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return compute_imstt_regvals_tvp(par, xres, yres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) set_imstt_regvals_ibm (struct imstt_par *par, u_int bpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct imstt_regvals *init = &par->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) __u8 pformat = (bpp >> 3) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) par->cmap_regs[PIDXLO] = PIXM0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) par->cmap_regs[PIDXDATA] = init->pclk_m;eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) par->cmap_regs[PIDXLO] = PIXN0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) par->cmap_regs[PIDXDATA] = init->pclk_n;eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) par->cmap_regs[PIDXLO] = PIXP0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) par->cmap_regs[PIDXDATA] = init->pclk_p;eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) par->cmap_regs[PIDXLO] = PIXC0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) par->cmap_regs[PIDXDATA] = 0x02; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) par->cmap_regs[PIDXLO] = PIXFMT; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) par->cmap_regs[PIDXDATA] = pformat; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) set_imstt_regvals_tvp (struct imstt_par *par, u_int bpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct imstt_regvals *init = &par->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) __u8 tcc, mxc, lckl_n, mic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) __u8 mlc, lckl_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) switch (bpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) tcc = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) mxc = 0x4d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) lckl_n = 0xc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) mlc = init->mlc[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) lckl_p = init->lckl_p[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) tcc = 0x44;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) mxc = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) lckl_n = 0xe1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) mlc = init->mlc[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) lckl_p = init->lckl_p[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) tcc = 0x5e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mxc = 0x5d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) lckl_n = 0xf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mlc = init->mlc[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) lckl_p = init->lckl_p[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) tcc = 0x46;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) mxc = 0x5d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) lckl_n = 0xf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) mlc = init->mlc[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) lckl_p = init->lckl_p[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) mic = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) par->cmap_regs[TVPADDRW] = TVPIRPLA; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) par->cmap_regs[TVPIDATA] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) par->cmap_regs[TVPADDRW] = TVPIRPPD; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) par->cmap_regs[TVPIDATA] = init->pclk_m; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) par->cmap_regs[TVPADDRW] = TVPIRPPD; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) par->cmap_regs[TVPIDATA] = init->pclk_n; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) par->cmap_regs[TVPADDRW] = TVPIRPPD; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) par->cmap_regs[TVPIDATA] = init->pclk_p; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) par->cmap_regs[TVPADDRW] = TVPIRTCC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) par->cmap_regs[TVPIDATA] = tcc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) par->cmap_regs[TVPADDRW] = TVPIRMXC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) par->cmap_regs[TVPIDATA] = mxc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) par->cmap_regs[TVPADDRW] = TVPIRMIC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) par->cmap_regs[TVPIDATA] = mic; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) par->cmap_regs[TVPADDRW] = TVPIRPLA; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) par->cmap_regs[TVPIDATA] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) par->cmap_regs[TVPADDRW] = TVPIRLPD; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) par->cmap_regs[TVPIDATA] = lckl_n; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) par->cmap_regs[TVPADDRW] = TVPIRPLA; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) par->cmap_regs[TVPIDATA] = 0x15; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) par->cmap_regs[TVPADDRW] = TVPIRMLC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) par->cmap_regs[TVPIDATA] = mlc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) par->cmap_regs[TVPADDRW] = TVPIRPLA; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) par->cmap_regs[TVPIDATA] = 0x2a; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) par->cmap_regs[TVPADDRW] = TVPIRLPD; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) par->cmap_regs[TVPIDATA] = lckl_p; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) set_imstt_regvals (struct fb_info *info, u_int bpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct imstt_regvals *init = &par->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) __u32 ctl, pitch, byteswap, scr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (par->ramdac == IBM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) set_imstt_regvals_ibm(par, bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) set_imstt_regvals_tvp(par, bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * From what I (jsk) can gather poking around with MacsBug,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * bits 8 and 9 in the SCR register control endianness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * correction (byte swapping). These bits must be set according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * to the color depth as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * Color depth Bit 9 Bit 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * ========== ===== =====
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * 8bpp 0 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * 16bpp 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * 32bpp 1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) switch (bpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ctl = 0x17b1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) pitch = init->pitch >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) byteswap = 0x000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ctl = 0x17b3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) pitch = init->pitch >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) byteswap = 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ctl = 0x17b9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) pitch = init->pitch - (init->pitch >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) byteswap = 0x200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ctl = 0x17b5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) pitch = init->pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) byteswap = 0x300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (par->ramdac == TVP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ctl -= 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) write_reg_le32(par->dc_regs, HES, init->hes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) write_reg_le32(par->dc_regs, HEB, init->heb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) write_reg_le32(par->dc_regs, HSB, init->hsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) write_reg_le32(par->dc_regs, HT, init->ht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) write_reg_le32(par->dc_regs, VES, init->ves);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) write_reg_le32(par->dc_regs, VEB, init->veb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) write_reg_le32(par->dc_regs, VSB, init->vsb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) write_reg_le32(par->dc_regs, VT, init->vt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) write_reg_le32(par->dc_regs, VIL, init->vil);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) write_reg_le32(par->dc_regs, HCIV, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) write_reg_le32(par->dc_regs, VCIV, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) write_reg_le32(par->dc_regs, TCDR, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) write_reg_le32(par->dc_regs, RRCIV, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) write_reg_le32(par->dc_regs, RRSC, 0x980);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) write_reg_le32(par->dc_regs, RRCR, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (par->ramdac == IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) write_reg_le32(par->dc_regs, HRIR, 0x0100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) write_reg_le32(par->dc_regs, CMR, 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) write_reg_le32(par->dc_regs, SRGCTL, 0x0073);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) write_reg_le32(par->dc_regs, HRIR, 0x0200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) write_reg_le32(par->dc_regs, CMR, 0x01ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) write_reg_le32(par->dc_regs, SRGCTL, 0x0003);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) switch (info->fix.smem_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case 0x200000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) scr = 0x059d | byteswap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /* case 0x400000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) case 0x800000: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) pitch >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) scr = 0x150dd | byteswap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) write_reg_le32(par->dc_regs, SCR, scr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) write_reg_le32(par->dc_regs, SPR, pitch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) write_reg_le32(par->dc_regs, STGCTL, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) __u32 off = var->yoffset * (info->fix.line_length >> 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) + ((var->xoffset * (info->var.bits_per_pixel >> 3)) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) write_reg_le32(par->dc_regs, SSR, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) set_555 (struct imstt_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (par->ramdac == IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) par->cmap_regs[PIDXLO] = BPP16; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) par->cmap_regs[PIDXDATA] = 0x01; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) par->cmap_regs[TVPADDRW] = TVPIRTCC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) par->cmap_regs[TVPIDATA] = 0x44; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) set_565 (struct imstt_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (par->ramdac == IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) par->cmap_regs[PIDXLO] = BPP16; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) par->cmap_regs[PIDXDATA] = 0x03; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) par->cmap_regs[TVPADDRW] = TVPIRTCC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) par->cmap_regs[TVPIDATA] = 0x45; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) imsttfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if ((var->bits_per_pixel != 8 && var->bits_per_pixel != 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) && var->bits_per_pixel != 24 && var->bits_per_pixel != 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) || var->xres_virtual < var->xres || var->yres_virtual < var->yres
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) || var->nonstd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if ((var->xres * var->yres) * (var->bits_per_pixel >> 3) > info->fix.smem_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) || (var->xres_virtual * var->yres_virtual) * (var->bits_per_pixel >> 3) > info->fix.smem_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) switch (var->bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) var->red.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) var->green.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) var->transp.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) var->transp.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) case 16: /* RGB 555 or 565 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (var->green.length != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) var->red.offset = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) var->red.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) var->green.offset = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (var->green.length != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) var->green.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) var->blue.length = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) var->transp.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) var->transp.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case 24: /* RGB 888 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) var->red.offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) var->green.offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) var->transp.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) var->transp.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) case 32: /* RGBA 8888 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) var->red.offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) var->green.offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) var->blue.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) var->transp.offset = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) var->transp.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (var->yres == var->yres_virtual) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) __u32 vram = (info->fix.smem_len - (PAGE_SIZE << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) var->yres_virtual = ((vram << 3) / var->bits_per_pixel) / var->xres_virtual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (var->yres_virtual < var->yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) var->yres_virtual = var->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) var->red.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) var->green.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) var->blue.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) var->transp.msb_right = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) var->height = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) var->width = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) var->vmode = FB_VMODE_NONINTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) var->left_margin = var->right_margin = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) var->upper_margin = var->lower_margin = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) var->hsync_len = var->vsync_len = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) imsttfb_set_par(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (!compute_imstt_regvals(par, info->var.xres, info->var.yres))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (info->var.green.length == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) set_565(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) set_555(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) set_imstt_regvals(info, info->var.bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) info->var.pixclock = 1000000 / getclkMHz(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) u_int transp, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) u_int bpp = info->var.bits_per_pixel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (regno > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) red >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) green >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) blue >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) /* PADDRW/PDATA are the same as TVPPADDRW/TVPPDATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (0 && bpp == 16) /* screws up X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) par->cmap_regs[PADDRW] = regno << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) par->cmap_regs[PADDRW] = regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) par->cmap_regs[PDATA] = red; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) par->cmap_regs[PDATA] = green; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) par->cmap_regs[PDATA] = blue; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (regno < 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) switch (bpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) par->palette[regno] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) (regno << (info->var.green.length ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 5 ? 10 : 11)) | (regno << 5) | regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) par->palette[regno] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) (regno << 16) | (regno << 8) | regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) case 32: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) int i = (regno << 8) | regno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) par->palette[regno] = (i << 16) |i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) imsttfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (var->xoffset + info->var.xres > info->var.xres_virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) || var->yoffset + info->var.yres > info->var.yres_virtual)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) info->var.xoffset = var->xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) info->var.yoffset = var->yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) set_offset(var, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) imsttfb_blank(int blank, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) __u32 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ctrl = read_reg_le32(par->dc_regs, STGCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (blank > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) switch (blank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) case FB_BLANK_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) case FB_BLANK_POWERDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ctrl &= ~0x00000380;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (par->ramdac == IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) par->cmap_regs[PIDXLO] = MISCTL2; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) par->cmap_regs[PIDXDATA] = 0x55; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) par->cmap_regs[PIDXLO] = MISCTL1; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) par->cmap_regs[PIDXDATA] = 0x11; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) par->cmap_regs[PIDXLO] = SYNCCTL; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) par->cmap_regs[PIDXDATA] = 0x0f; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) par->cmap_regs[PIDXLO] = PWRMNGMT; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) par->cmap_regs[PIDXDATA] = 0x1f; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) par->cmap_regs[PIDXLO] = CLKCTL; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) par->cmap_regs[PIDXDATA] = 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) case FB_BLANK_VSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ctrl &= ~0x00000020;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) case FB_BLANK_HSYNC_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ctrl &= ~0x00000010;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (par->ramdac == IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ctrl |= 0x000017b0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) par->cmap_regs[PIDXLO] = CLKCTL; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) par->cmap_regs[PIDXDATA] = 0x01; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) par->cmap_regs[PIDXLO] = PWRMNGMT; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) par->cmap_regs[PIDXDATA] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) par->cmap_regs[PIDXLO] = SYNCCTL; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) par->cmap_regs[PIDXDATA] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) par->cmap_regs[PIDXLO] = MISCTL1; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) par->cmap_regs[PIDXDATA] = 0x01; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) par->cmap_regs[PIDXLO] = MISCTL2; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) par->cmap_regs[PIDXDATA] = 0x45; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ctrl |= 0x00001780;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) write_reg_le32(par->dc_regs, STGCTL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) __u32 Bpp, line_pitch, bgc, dx, dy, width, height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) bgc = rect->color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) bgc |= (bgc << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) bgc |= (bgc << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) Bpp = info->var.bits_per_pixel >> 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) line_pitch = info->fix.line_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) dy = rect->dy * line_pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) dx = rect->dx * Bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) height = rect->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) height--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) width = rect->width * Bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) width--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (rect->rop == ROP_COPY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) write_reg_le32(par->dc_regs, DSA, dy + dx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) write_reg_le32(par->dc_regs, CNT, (height << 16) | width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) write_reg_le32(par->dc_regs, DP_OCTL, line_pitch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) write_reg_le32(par->dc_regs, BI, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) write_reg_le32(par->dc_regs, MBC, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) write_reg_le32(par->dc_regs, CLR, bgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) write_reg_le32(par->dc_regs, BLTCTL, 0x840); /* 0x200000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) write_reg_le32(par->dc_regs, DSA, dy + dx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) write_reg_le32(par->dc_regs, S1SA, dy + dx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) write_reg_le32(par->dc_regs, CNT, (height << 16) | width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) write_reg_le32(par->dc_regs, DP_OCTL, line_pitch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) write_reg_le32(par->dc_regs, SP, line_pitch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) write_reg_le32(par->dc_regs, BLTCTL, 0x40005);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) __u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) __u32 cnt, bltctl, sx, sy, dx, dy, height, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) Bpp = info->var.bits_per_pixel >> 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) sx = area->sx * Bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) sy = area->sy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dx = area->dx * Bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) dy = area->dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) height = area->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) height--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) width = area->width * Bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) width--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) line_pitch = info->fix.line_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) bltctl = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) sp = line_pitch << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) cnt = height << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (sy < dy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) sy += height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) dy += height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) sp |= -(line_pitch) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) dp_octl = -(line_pitch) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) sp |= line_pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) dp_octl = line_pitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (sx < dx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) sx += width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) dx += width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) bltctl |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) cnt |= -(width) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) cnt |= width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) fb_offset_old = sy * line_pitch + sx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) fb_offset_new = dy * line_pitch + dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) write_reg_le32(par->dc_regs, S1SA, fb_offset_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) write_reg_le32(par->dc_regs, SP, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) write_reg_le32(par->dc_regs, DSA, fb_offset_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) write_reg_le32(par->dc_regs, CNT, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) write_reg_le32(par->dc_regs, DP_OCTL, dp_octl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) write_reg_le32(par->dc_regs, BLTCTL, bltctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) imsttfb_load_cursor_image(struct imstt_par *par, int width, int height, __u8 fgc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) u_int x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (width > 32 || height > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (par->ramdac == IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) par->cmap_regs[PIDXHI] = 1; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) for (x = 0; x < 0x100; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) par->cmap_regs[PIDXLO] = x; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) par->cmap_regs[PIDXDATA] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) par->cmap_regs[PIDXHI] = 1; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) for (y = 0; y < height; y++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) for (x = 0; x < width >> 2; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) par->cmap_regs[PIDXLO] = x + y * 8; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) par->cmap_regs[PIDXDATA] = 0xff; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) par->cmap_regs[PIDXLO] = CURS1R; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) par->cmap_regs[PIDXLO] = CURS1G; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) par->cmap_regs[PIDXLO] = CURS1B; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) par->cmap_regs[PIDXLO] = CURS2R; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) par->cmap_regs[PIDXLO] = CURS2G; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) par->cmap_regs[PIDXLO] = CURS2B; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) par->cmap_regs[PIDXLO] = CURS3R; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) par->cmap_regs[PIDXLO] = CURS3G; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) par->cmap_regs[PIDXLO] = CURS3B; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) par->cmap_regs[PIDXDATA] = fgc; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) par->cmap_regs[TVPIDATA] &= 0x03; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) par->cmap_regs[TVPADDRW] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) for (x = 0; x < 0x200; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) par->cmap_regs[TVPCRDAT] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) for (x = 0; x < 0x200; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) par->cmap_regs[TVPCRDAT] = 0xff; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) par->cmap_regs[TVPIDATA] &= 0x03; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) for (y = 0; y < height; y++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) for (x = 0; x < width >> 3; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) par->cmap_regs[TVPADDRW] = x + y * 8; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) par->cmap_regs[TVPCRDAT] = 0xff; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) par->cmap_regs[TVPIDATA] |= 0x08; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) for (y = 0; y < height; y++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) for (x = 0; x < width >> 3; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) par->cmap_regs[TVPADDRW] = x + y * 8; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) par->cmap_regs[TVPCRDAT] = 0xff; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) par->cmap_regs[TVPCADRW] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) for (x = 0; x < 12; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) par->cmap_regs[TVPCDATA] = fgc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) imstt_set_cursor(struct imstt_par *par, struct fb_image *d, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (par->ramdac == IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (!on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) par->cmap_regs[PIDXLO] = CURSCTL; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) par->cmap_regs[PIDXDATA] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) par->cmap_regs[PIDXLO] = CURSXHI; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) par->cmap_regs[PIDXDATA] = d->dx >> 8; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) par->cmap_regs[PIDXLO] = CURSXLO; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) par->cmap_regs[PIDXDATA] = d->dx & 0xff;eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) par->cmap_regs[PIDXLO] = CURSYHI; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) par->cmap_regs[PIDXDATA] = d->dy >> 8; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) par->cmap_regs[PIDXLO] = CURSYLO; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) par->cmap_regs[PIDXDATA] = d->dy & 0xff;eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) par->cmap_regs[PIDXLO] = CURSCTL; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) par->cmap_regs[PIDXDATA] = 0x02; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (!on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) par->cmap_regs[TVPIDATA] = 0x00; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) __u16 x = d->dx + 0x40, y = d->dy + 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) par->cmap_regs[TVPCXPOH] = x >> 8; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) par->cmap_regs[TVPCXPOL] = x & 0xff; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) par->cmap_regs[TVPCYPOH] = y >> 8; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) par->cmap_regs[TVPCYPOL] = y & 0xff; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) par->cmap_regs[TVPADDRW] = TVPIRICC; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) par->cmap_regs[TVPIDATA] = 0x02; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) u32 flags = cursor->set, fg, bg, xx, yy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (cursor->dest == NULL && cursor->rop == ROP_XOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) imstt_set_cursor(info, cursor, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (flags & FB_CUR_SETPOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) xx = cursor->image.dx - info->var.xoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) yy = cursor->image.dy - info->var.yoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (flags & FB_CUR_SETSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) int fg_idx = cursor->image.fg_color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int width = (cursor->image.width+7)/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) u8 *dat = (u8 *) cursor->image.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) u8 *dst = (u8 *) cursor->dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) u8 *msk = (u8 *) cursor->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) switch (cursor->rop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) case ROP_XOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) for (i = 0; i < cursor->image.height; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) for (j = 0; j < width; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) d_idx = i * MAX_CURS/8 + j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) data[d_idx] = byte_rev[dat[s_idx] ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) dst[s_idx]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) mask[d_idx] = byte_rev[msk[s_idx]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) s_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) case ROP_COPY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) for (i = 0; i < cursor->image.height; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) for (j = 0; j < width; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) d_idx = i * MAX_CURS/8 + j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) data[d_idx] = byte_rev[dat[s_idx]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) mask[d_idx] = byte_rev[msk[s_idx]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) s_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) ((info->cmap.green[fg_idx] & 0xf8) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) imsttfb_load_cursor_image(par, xx, yy, fgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if (cursor->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) imstt_set_cursor(info, cursor, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) #define FBIMSTT_SETREG 0x545401
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) #define FBIMSTT_GETREG 0x545402
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) #define FBIMSTT_SETCMAPREG 0x545403
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) #define FBIMSTT_GETCMAPREG 0x545404
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) #define FBIMSTT_SETIDXREG 0x545405
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) #define FBIMSTT_GETIDXREG 0x545406
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) imsttfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) __u32 reg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) __u8 idx[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) case FBIMSTT_SETREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) write_reg_le32(par->dc_regs, reg[0], reg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) case FBIMSTT_GETREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) reg[1] = read_reg_le32(par->dc_regs, reg[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (copy_to_user((void __user *)(arg + 4), ®[1], 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) case FBIMSTT_SETCMAPREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) write_reg_le32(((u_int __iomem *)par->cmap_regs), reg[0], reg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) case FBIMSTT_GETCMAPREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) reg[1] = read_reg_le32(((u_int __iomem *)par->cmap_regs), reg[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (copy_to_user((void __user *)(arg + 4), ®[1], 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) case FBIMSTT_SETIDXREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (copy_from_user(idx, argp, 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) par->cmap_regs[PIDXLO] = idx[0]; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) par->cmap_regs[PIDXDATA] = idx[1]; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) case FBIMSTT_GETIDXREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (copy_from_user(idx, argp, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) par->cmap_regs[PIDXHI] = 0; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) par->cmap_regs[PIDXLO] = idx[0]; eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) idx[1] = par->cmap_regs[PIDXDATA];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (copy_to_user((void __user *)(arg + 1), &idx[1], 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) static const struct pci_device_id imsttfb_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) { PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) PCI_ANY_ID, PCI_ANY_ID, 0, 0, IBM },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) { PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT3D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) PCI_ANY_ID, PCI_ANY_ID, 0, 0, TVP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) MODULE_DEVICE_TABLE(pci, imsttfb_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) static struct pci_driver imsttfb_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) .name = "imsttfb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .id_table = imsttfb_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .probe = imsttfb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) .remove = imsttfb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static const struct fb_ops imsttfb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) .fb_check_var = imsttfb_check_var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) .fb_set_par = imsttfb_set_par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) .fb_setcolreg = imsttfb_setcolreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) .fb_pan_display = imsttfb_pan_display,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) .fb_blank = imsttfb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) .fb_fillrect = imsttfb_fillrect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) .fb_copyarea = imsttfb_copyarea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) .fb_imageblit = cfb_imageblit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) .fb_ioctl = imsttfb_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) static void init_imstt(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) __u32 i, tmp, *ip, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) tmp = read_reg_le32(par->dc_regs, PRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) if (par->ramdac == IBM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) info->fix.smem_len = (tmp & 0x0004) ? 0x400000 : 0x200000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) info->fix.smem_len = 0x800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) ip = (__u32 *)info->screen_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) end = (__u32 *)(info->screen_base + info->fix.smem_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) while (ip < end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) *ip++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) /* initialize the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) tmp = read_reg_le32(par->dc_regs, STGCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) write_reg_le32(par->dc_regs, STGCTL, tmp & ~0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) write_reg_le32(par->dc_regs, SSR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) /* set default values for DAC registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (par->ramdac == IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) par->cmap_regs[PPMASK] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) par->cmap_regs[PIDXHI] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) for (i = 0; i < ARRAY_SIZE(ibm_initregs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) par->cmap_regs[PIDXLO] = ibm_initregs[i].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) par->cmap_regs[PIDXDATA] = ibm_initregs[i].value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) for (i = 0; i < ARRAY_SIZE(tvp_initregs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) par->cmap_regs[TVPIDATA] = tvp_initregs[i].value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (IS_REACHABLE(CONFIG_NVRAM) && machine_is(powermac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) int vmode = init_vmode, cmode = init_cmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (vmode == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) vmode = nvram_read_byte(NV_VMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (vmode <= 0 || vmode > VMODE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) vmode = VMODE_640_480_67;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (cmode == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) cmode = nvram_read_byte(NV_CMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (cmode < CMODE_8 || cmode > CMODE_32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) cmode = CMODE_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (mac_vmode_to_var(vmode, cmode, &info->var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) info->var.xres = info->var.xres_virtual = INIT_XRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) info->var.yres = info->var.yres_virtual = INIT_YRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) info->var.bits_per_pixel = INIT_BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) info->var.xres = info->var.xres_virtual = INIT_XRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) info->var.yres = info->var.yres_virtual = INIT_YRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) info->var.bits_per_pixel = INIT_BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) sprintf(info->fix.id, "IMS TT (%s)", par->ramdac == IBM ? "IBM" : "TVP");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) info->fix.mmio_len = 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) info->fix.accel = FB_ACCEL_IMS_TWINTURBO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) info->fix.type = FB_TYPE_PACKED_PIXELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) info->fix.visual = info->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) : FB_VISUAL_DIRECTCOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) info->fix.line_length = info->var.xres * (info->var.bits_per_pixel >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) info->fix.xpanstep = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) info->fix.ypanstep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) info->fix.ywrapstep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) info->var.accel_flags = FB_ACCELF_TEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) // if (par->ramdac == IBM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) // imstt_cursor_init(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (info->var.green.length == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) set_565(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) set_555(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) set_imstt_regvals(info, info->var.bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) info->var.pixclock = 1000000 / getclkMHz(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) info->fbops = &imsttfb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) info->flags = FBINFO_DEFAULT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) FBINFO_HWACCEL_COPYAREA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) FBINFO_HWACCEL_FILLRECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) FBINFO_HWACCEL_YPAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) fb_alloc_cmap(&info->cmap, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (register_framebuffer(info) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) tmp = (read_reg_le32(par->dc_regs, SSTATUS) & 0x0f00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) fb_info(info, "%s frame buffer; %uMB vram; chip version %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) info->fix.id, info->fix.smem_len >> 20, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) unsigned long addr, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct imstt_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) struct device_node *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) dp = pci_device_to_OF_node(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if(dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) printk(KERN_INFO "%s: OF name %pOFn\n",__func__, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) else if (IS_ENABLED(CONFIG_OF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) printk(KERN_ERR "imsttfb: no OF node for pci device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) addr = pci_resource_start (pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) size = pci_resource_len (pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (!request_mem_region(addr, size, "imsttfb")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) printk(KERN_ERR "imsttfb: Can't reserve memory region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) switch (pdev->device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) case PCI_DEVICE_ID_IMS_TT128: /* IMS,tt128mbA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) par->ramdac = IBM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (of_node_name_eq(dp, "IMS,tt128mb8") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) of_node_name_eq(dp, "IMS,tt128mb8A"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) par->ramdac = TVP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) case PCI_DEVICE_ID_IMS_TT3D: /* IMS,tt3d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) par->ramdac = TVP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) "contact maintainer.\n", pdev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) release_mem_region(addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) info->fix.smem_start = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 0x400000 : 0x800000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) info->fix.mmio_start = addr + 0x800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) par->dc_regs = ioremap(addr + 0x800000, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) par->cmap_regs_phys = addr + 0x840000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) info->pseudo_palette = par->palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) init_imstt(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) pci_set_drvdata(pdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) static void imsttfb_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) struct fb_info *info = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) struct imstt_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) int size = pci_resource_len(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) unregister_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) iounmap(par->cmap_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) iounmap(par->dc_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) iounmap(info->screen_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) release_mem_region(info->fix.smem_start, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) imsttfb_setup(char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) char *this_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (!options || !*options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) while ((this_opt = strsep(&options, ",")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (!strncmp(this_opt, "font:", 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) p = this_opt + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) for (i = 0; i < sizeof(fontname) - 1; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (!*p || *p == ' ' || *p == ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) memcpy(fontname, this_opt + 5, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) fontname[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) } else if (!strncmp(this_opt, "inverse", 7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) inverse = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) fb_invert_cmaps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) #if defined(CONFIG_PPC_PMAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) else if (!strncmp(this_opt, "vmode:", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) int vmode = simple_strtoul(this_opt+6, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) if (vmode > 0 && vmode <= VMODE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) init_vmode = vmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) } else if (!strncmp(this_opt, "cmode:", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) int cmode = simple_strtoul(this_opt+6, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) switch (cmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) case CMODE_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) init_cmode = CMODE_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) case CMODE_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) case 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) init_cmode = CMODE_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) case CMODE_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) init_cmode = CMODE_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) #endif /* MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) static int __init imsttfb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) char *option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (fb_get_options("imsttfb", &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) imsttfb_setup(option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) return pci_register_driver(&imsttfb_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) static void __exit imsttfb_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) pci_unregister_driver(&imsttfb_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) module_init(imsttfb_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) module_exit(imsttfb_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)