diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-03-03 01:22:27 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-03-03 01:22:27 +0000 |
commit | f9bbe9da79dbc8557c74efeb158b431cd67ace52 (patch) | |
tree | 3220d014a35f9d88a48668a1468524e988daebff /arch/m68k/amiga | |
parent | 3d697109c1ff85ef563aec3d5e113ef225ed2792 (diff) |
Upgrade to 2.1.73.
Diffstat (limited to 'arch/m68k/amiga')
-rw-r--r-- | arch/m68k/amiga/amifb.c | 3633 | ||||
-rw-r--r-- | arch/m68k/amiga/amikeyb.c | 343 | ||||
-rw-r--r-- | arch/m68k/amiga/cyberfb.c | 1253 | ||||
-rw-r--r-- | arch/m68k/amiga/retz3fb.c | 1754 | ||||
-rw-r--r-- | arch/m68k/amiga/retz3fb.h | 286 |
5 files changed, 0 insertions, 7269 deletions
diff --git a/arch/m68k/amiga/amifb.c b/arch/m68k/amiga/amifb.c deleted file mode 100644 index eb72970d7..000000000 --- a/arch/m68k/amiga/amifb.c +++ /dev/null @@ -1,3633 +0,0 @@ -/* - * linux/arch/m68k/amiga/amifb.c -- Low level implementation of the Amiga frame - * buffer device - * - * Copyright (C) 1995 Geert Uytterhoeven - * - * with work by Roman Zippel - * - * - * This file is based on the Atari frame buffer device (atafb.c): - * - * Copyright (C) 1994 Martin Schaller - * Roman Hodek - * - * with work by Andreas Schwab - * Guenther Kelleter - * - * and on the original Amiga console driver (amicon.c): - * - * Copyright (C) 1993 Hamish Macdonald - * Greg Harp - * Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk] - * - * with work by William Rucklidge (wjr@cs.cornell.edu) - * Geert Uytterhoeven - * Jes Sorensen (jds@kom.auc.dk) - * - * - * History: - * - * - 24 Jul 96: Copper generates now vblank interrupt and - * VESA Power Saving Protocol is fully implemented - * - 14 Jul 96: Rework and hopefully last ECS bugs fixed - * - 7 Mar 96: Hardware sprite support by Roman Zippel - * - 18 Feb 96: OCS and ECS support by Roman Zippel - * Hardware functions completely rewritten - * - 2 Dec 95: AGA version by Geert Uytterhoeven - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/malloc.h> -#include <linux/delay.h> -#include <linux/config.h> -#include <linux/interrupt.h> -#include <linux/fb.h> -#include <linux/init.h> - -#include <asm/uaccess.h> -#include <asm/system.h> -#include <asm/irq.h> -#include <asm/amigahw.h> -#include <asm/amigaints.h> - -#define DEBUG - -#if !defined(CONFIG_AMIFB_OCS) && !defined(CONFIG_AMIFB_ECS) && !defined(CONFIG_AMIFB_AGA) -#define CONFIG_AMIFB_OCS /* define at least one fb driver, this will change later */ -#endif - -#if !defined(CONFIG_AMIFB_OCS) -# define IS_OCS (0) -#elif defined(CONFIG_AMIFB_ECS) || defined(CONFIG_AMIFB_AGA) -# define IS_OCS (chipset == TAG_OCS) -#else -# define CONFIG_AMIFB_OCS_ONLY -# define IS_OCS (1) -#endif - -#if !defined(CONFIG_AMIFB_ECS) -# define IS_ECS (0) -#elif defined(CONFIG_AMIFB_OCS) || defined(CONFIG_AMIFB_AGA) -# define IS_ECS (chipset == TAG_ECS) -#else -# define CONFIG_AMIFB_ECS_ONLY -# define IS_ECS (1) -#endif - -#if !defined(CONFIG_AMIFB_AGA) -# define IS_AGA (0) -#elif defined(CONFIG_AMIFB_OCS) || defined(CONFIG_AMIFB_ECS) -# define IS_AGA (chipset == TAG_AGA) -#else -# define CONFIG_AMIFB_AGA_ONLY -# define IS_AGA (1) -#endif - -/******************************************************************************* - - - Generic video timings - --------------------- - - Timings used by the frame buffer interface: - - +----------+---------------------------------------------+----------+-------+ - | | ^ | | | - | | |upper_margin | | | - | | ¥ | | | - +----------###############################################----------+-------+ - | # ^ # | | - | # | # | | - | # | # | | - | # | # | | - | left # | # right | hsync | - | margin # | xres # margin | len | - |<-------->#<---------------+--------------------------->#<-------->|<----->| - | # | # | | - | # | # | | - | # | # | | - | # |yres # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # | # | | - | # ¥ # | | - +----------###############################################----------+-------+ - | | ^ | | | - | | |lower_margin | | | - | | ¥ | | | - +----------+---------------------------------------------+----------+-------+ - | | ^ | | | - | | |vsync_len | | | - | | ¥ | | | - +----------+---------------------------------------------+----------+-------+ - - - Amiga video timings - ------------------- - - The Amiga native chipsets uses another timing scheme: - - - hsstrt: Start of horizontal synchronization pulse - - hsstop: End of horizontal synchronization pulse - - htotal: Last value on the line (i.e. line length = htotal+1) - - vsstrt: Start of vertical synchronization pulse - - vsstop: End of vertical synchronization pulse - - vtotal: Last line value (i.e. number of lines = vtotal+1) - - hcenter: Start of vertical retrace for interlace - - You can specify the blanking timings independently. Currently I just set - them equal to the respective synchronization values: - - - hbstrt: Start of horizontal blank - - hbstop: End of horizontal blank - - vbstrt: Start of vertical blank - - vbstop: End of vertical blank - - Horizontal values are in color clock cycles (280 ns), vertical values are in - scanlines. - - (0, 0) is somewhere in the upper-left corner :-) - - - Amiga visible window definitions - -------------------------------- - - Currently I only have values for AGA, SHRES (28 MHz dotclock). Feel free to - make corrections and/or additions. - - Within the above synchronization specifications, the visible window is - defined by the following parameters (actual register resolutions may be - different; all horizontal values are normalized with respect to the pixel - clock): - - - diwstrt_h: Horizontal start of the visible window - - diwstop_h: Horizontal stop+1(*) of the visible window - - diwstrt_v: Vertical start of the visible window - - diwstop_v: Vertical stop of the visible window - - ddfstrt: Horizontal start of display DMA - - ddfstop: Horizontal stop of display DMA - - hscroll: Horizontal display output delay - - Sprite positioning: - - - sprstrt_h: Horizontal start-4 of sprite - - sprstrt_v: Vertical start of sprite - - (*) Even Commodore did it wrong in the AGA monitor drivers by not adding 1. - - Horizontal values are in dotclock cycles (35 ns), vertical values are in - scanlines. - - (0, 0) is somewhere in the upper-left corner :-) - - - Dependencies (AGA, SHRES (35 ns dotclock)) - ------------------------------------------- - - Since there are much more parameters for the Amiga display than for the - frame buffer interface, there must be some dependencies among the Amiga - display parameters. Here's what I found out: - - - ddfstrt and ddfstop are best aligned to 64 pixels. - - the chipset needs 64+4 horizontal pixels after the DMA start before the - first pixel is output, so diwstrt_h = ddfstrt+64+4 if you want to - display the first pixel on the line too. Increase diwstrt_h for virtual - screen panning. - - the display DMA always fetches 64 pixels at a time (fmode = 3). - - ddfstop is ddfstrt+#pixels-64. - - diwstop_h = diwstrt_h+xres+1. Because of the additional 1 this can be 1 - more than htotal. - - hscroll simply adds a delay to the display output. Smooth horizontal - panning needs an extra 64 pixels on the left to prefetch the pixels that - `fall off' on the left. - - if ddfstrt < 192, the sprite DMA cycles are all stolen by the bitplane - DMA, so it's best to make the DMA start as late as possible. - - you really don't want to make ddfstrt < 128, since this will steal DMA - cycles from the other DMA channels (audio, floppy and Chip RAM refresh). - - I make diwstop_h and diwstop_v as large as possible. - - General dependencies - -------------------- - - - all values are SHRES pixel (35ns) - - table 1:fetchstart table 2:prefetch table 3:fetchsize - ------------------ ---------------- ----------------- - Pixclock # SHRES|HIRES|LORES # SHRES|HIRES|LORES # SHRES|HIRES|LORES - -------------#------+-----+------#------+-----+------#------+-----+------ - Bus width 1x # 16 | 32 | 64 # 16 | 32 | 64 # 64 | 64 | 64 - Bus width 2x # 32 | 64 | 128 # 32 | 64 | 64 # 64 | 64 | 128 - Bus width 4x # 64 | 128 | 256 # 64 | 64 | 64 # 64 | 128 | 256 - - - chipset needs 4 pixels before the first pixel is output - - ddfstrt must be aligned to fetchstart (table 1) - - chipset needs also prefetch (table 2) to get first pixel data, so - ddfstrt = ((diwstrt_h-4) & -fetchstart) - prefetch - - for horizontal panning decrease diwstrt_h - - the length of a fetchline must be aligned to fetchsize (table 3) - - if fetchstart is smaller than fetchsize, then ddfstrt can a little bit - moved to optimize use of dma (usefull for OCS/ECS overscan displays) - - ddfstop is ddfstrt+ddfsize-fetchsize - - If C= didn't change anything for AGA, then at following positions the - dma bus is allready used: - ddfstrt < 48 -> memory refresh - < 96 -> disk dma - < 160 -> audio dma - < 192 -> sprite 0 dma - < 416 -> sprite dma (32 per sprite) - - in accordance with the hardware reference manual a hardware stop is at - 192, but AGA (ECS?) can go below this. - - DMA priorities - -------------- - - Since there are limits on the earliest start value for display DMA and the - display of sprites, I use the following policy on horizontal panning and - the hardware cursor: - - - if you want to start display DMA too early, you loose the ability to - do smooth horizontal panning (xpanstep 1 -> 64). - - if you want to go even further, you loose the hardware cursor too. - - IMHO a hardware cursor is more important for X than horizontal scrolling, - so that's my motivation. - - - Implementation - -------------- - - ami_decode_var() converts the frame buffer values to the Amiga values. It's - just a `straightforward' implementation of the above rules. - - - Standard VGA timings - -------------------- - - xres yres left right upper lower hsync vsync - ---- ---- ---- ----- ----- ----- ----- ----- - 80x25 720 400 27 45 35 12 108 2 - 80x30 720 480 27 45 30 9 108 2 - - These were taken from a XFree86 configuration file, recalculated for a 28 MHz - dotclock (Amigas don't have a 25 MHz dotclock) and converted to frame buffer - generic timings. - - As a comparison, graphics/monitor.h suggests the following: - - xres yres left right upper lower hsync vsync - ---- ---- ---- ----- ----- ----- ----- ----- - - VGA 640 480 52 112 24 19 112 - 2 + - VGA70 640 400 52 112 27 21 112 - 2 - - - - Sync polarities - --------------- - - VSYNC HSYNC Vertical size Vertical total - ----- ----- ------------- -------------- - + + Reserved Reserved - + - 400 414 - - + 350 362 - - - 480 496 - - Source: CL-GD542X Technical Reference Manual, Cirrus Logic, Oct 1992 - - - Broadcast video timings - ----------------------- - - According to the CCIR and RETMA specifications, we have the following values: - - CCIR -> PAL - ----------- - - - a scanline is 64 µs long, of which 52.48 µs are visible. This is about - 736 visible 70 ns pixels per line. - - we have 625 scanlines, of which 575 are visible (interlaced); after - rounding this becomes 576. - - RETMA -> NTSC - ------------- - - - a scanline is 63.5 µs long, of which 53.5 µs are visible. This is about - 736 visible 70 ns pixels per line. - - we have 525 scanlines, of which 485 are visible (interlaced); after - rounding this becomes 484. - - Thus if you want a PAL compatible display, you have to do the following: - - - set the FB_SYNC_BROADCAST flag to indicate that standard broadcast - timings are to be used. - - make sure upper_margin+yres+lower_margin+vsync_len = 625 for an - interlaced, 312 for a non-interlaced and 156 for a doublescanned - display. - - make sure left_margin+xres+right_margin+hsync_len = 1816 for a SHRES, - 908 for a HIRES and 454 for a LORES display. - - the left visible part begins at 360 (SHRES; HIRES:180, LORES:90), - left_margin+2*hsync_len must be greater or equal. - - the upper visible part begins at 48 (interlaced; non-interlaced:24, - doublescanned:12), upper_margin+2*vsync_len must be greater or equal. - - ami_encode_var() calculates margins with a hsync of 5320 ns and a vsync - of 4 scanlines - - The settings for a NTSC compatible display are straightforward. - - Note that in a strict sense the PAL and NTSC standards only define the - encoding of the color part (chrominance) of the video signal and don't say - anything about horizontal/vertical synchronization nor refresh rates. - - - -- Geert -- - -*******************************************************************************/ - - - /* - * Custom Chipset Definitions - */ - -#define CUSTOM_OFS(fld) ((long)&((struct CUSTOM*)0)->fld) - - /* - * BPLCON0 -- Bitplane Control Register 0 - */ - -#define BPC0_HIRES (0x8000) -#define BPC0_BPU2 (0x4000) /* Bit plane used count */ -#define BPC0_BPU1 (0x2000) -#define BPC0_BPU0 (0x1000) -#define BPC0_HAM (0x0800) /* HAM mode */ -#define BPC0_DPF (0x0400) /* Double playfield */ -#define BPC0_COLOR (0x0200) /* Enable colorburst */ -#define BPC0_GAUD (0x0100) /* Genlock audio enable */ -#define BPC0_UHRES (0x0080) /* Ultrahi res enable */ -#define BPC0_SHRES (0x0040) /* Super hi res mode */ -#define BPC0_BYPASS (0x0020) /* Bypass LUT - AGA */ -#define BPC0_BPU3 (0x0010) /* AGA */ -#define BPC0_LPEN (0x0008) /* Light pen enable */ -#define BPC0_LACE (0x0004) /* Interlace */ -#define BPC0_ERSY (0x0002) /* External resync */ -#define BPC0_ECSENA (0x0001) /* ECS enable */ - - /* - * BPLCON2 -- Bitplane Control Register 2 - */ - -#define BPC2_ZDBPSEL2 (0x4000) /* Bitplane to be used for ZD - AGA */ -#define BPC2_ZDBPSEL1 (0x2000) -#define BPC2_ZDBPSEL0 (0x1000) -#define BPC2_ZDBPEN (0x0800) /* Enable ZD with ZDBPSELx - AGA */ -#define BPC2_ZDCTEN (0x0400) /* Enable ZD with palette bit #31 - AGA */ -#define BPC2_KILLEHB (0x0200) /* Kill EHB mode - AGA */ -#define BPC2_RDRAM (0x0100) /* Color table accesses read, not write - AGA */ -#define BPC2_SOGEN (0x0080) /* SOG output pin high - AGA */ -#define BPC2_PF2PRI (0x0040) /* PF2 priority over PF1 */ -#define BPC2_PF2P2 (0x0020) /* PF2 priority wrt sprites */ -#define BPC2_PF2P1 (0x0010) -#define BPC2_PF2P0 (0x0008) -#define BPC2_PF1P2 (0x0004) /* ditto PF1 */ -#define BPC2_PF1P1 (0x0002) -#define BPC2_PF1P0 (0x0001) - - /* - * BPLCON3 -- Bitplane Control Register 3 (AGA) - */ - -#define BPC3_BANK2 (0x8000) /* Bits to select color register bank */ -#define BPC3_BANK1 (0x4000) -#define BPC3_BANK0 (0x2000) -#define BPC3_PF2OF2 (0x1000) /* Bits for color table offset when PF2 */ -#define BPC3_PF2OF1 (0x0800) -#define BPC3_PF2OF0 (0x0400) -#define BPC3_LOCT (0x0200) /* Color register writes go to low bits */ -#define BPC3_SPRES1 (0x0080) /* Sprite resolution bits */ -#define BPC3_SPRES0 (0x0040) -#define BPC3_BRDRBLNK (0x0020) /* Border blanked? */ -#define BPC3_BRDRTRAN (0x0010) /* Border transparent? */ -#define BPC3_ZDCLKEN (0x0004) /* ZD pin is 14 MHz (HIRES) clock output */ -#define BPC3_BRDRSPRT (0x0002) /* Sprites in border? */ -#define BPC3_EXTBLKEN (0x0001) /* BLANK programmable */ - - /* - * BPLCON4 -- Bitplane Control Register 4 (AGA) - */ - -#define BPC4_BPLAM7 (0x8000) /* bitplane color XOR field */ -#define BPC4_BPLAM6 (0x4000) -#define BPC4_BPLAM5 (0x2000) -#define BPC4_BPLAM4 (0x1000) -#define BPC4_BPLAM3 (0x0800) -#define BPC4_BPLAM2 (0x0400) -#define BPC4_BPLAM1 (0x0200) -#define BPC4_BPLAM0 (0x0100) -#define BPC4_ESPRM7 (0x0080) /* 4 high bits for even sprite colors */ -#define BPC4_ESPRM6 (0x0040) -#define BPC4_ESPRM5 (0x0020) -#define BPC4_ESPRM4 (0x0010) -#define BPC4_OSPRM7 (0x0008) /* 4 high bits for odd sprite colors */ -#define BPC4_OSPRM6 (0x0004) -#define BPC4_OSPRM5 (0x0002) -#define BPC4_OSPRM4 (0x0001) - - /* - * BEAMCON0 -- Beam Control Register - */ - -#define BMC0_HARDDIS (0x4000) /* Disable hardware limits */ -#define BMC0_LPENDIS (0x2000) /* Disable light pen latch */ -#define BMC0_VARVBEN (0x1000) /* Enable variable vertical blank */ -#define BMC0_LOLDIS (0x0800) /* Disable long/short line toggle */ -#define BMC0_CSCBEN (0x0400) /* Composite sync/blank */ -#define BMC0_VARVSYEN (0x0200) /* Enable variable vertical sync */ -#define BMC0_VARHSYEN (0x0100) /* Enable variable horizontal sync */ -#define BMC0_VARBEAMEN (0x0080) /* Enable variable beam counters */ -#define BMC0_DUAL (0x0040) /* Enable alternate horizontal beam counter */ -#define BMC0_PAL (0x0020) /* Set decodes for PAL */ -#define BMC0_VARCSYEN (0x0010) /* Enable variable composite sync */ -#define BMC0_BLANKEN (0x0008) /* Blank enable (no longer used on AGA) */ -#define BMC0_CSYTRUE (0x0004) /* CSY polarity */ -#define BMC0_VSYTRUE (0x0002) /* VSY polarity */ -#define BMC0_HSYTRUE (0x0001) /* HSY polarity */ - - - /* - * FMODE -- Fetch Mode Control Register (AGA) - */ - -#define FMODE_SSCAN2 (0x8000) /* Sprite scan-doubling */ -#define FMODE_BSCAN2 (0x4000) /* Use PF2 modulus every other line */ -#define FMODE_SPAGEM (0x0008) /* Sprite page mode */ -#define FMODE_SPR32 (0x0004) /* Sprite 32 bit fetch */ -#define FMODE_BPAGEM (0x0002) /* Bitplane page mode */ -#define FMODE_BPL32 (0x0001) /* Bitplane 32 bit fetch */ - - /* - * Tags used to indicate a specific Pixel Clock - * - * clk_shift is the shift value to get the timings in 35 ns units - */ - -enum { TAG_SHRES, TAG_HIRES, TAG_LORES }; - - /* - * Tags used to indicate the specific chipset - */ - -enum { TAG_OCS, TAG_ECS, TAG_AGA }; - - /* - * Tags used to indicate the memory bandwidth - */ - -enum { TAG_FMODE_1, TAG_FMODE_2, TAG_FMODE_4 }; - - - /* - * Clock Definitions, Maximum Display Depth - * - * These depend on the E-Clock or the Chipset, so they are filled in - * dynamically - */ - -static u_long pixclock[3]; /* SHRES/HIRES/LORES: index = clk_shift */ -static u_short maxdepth[3]; /* SHRES/HIRES/LORES: index = clk_shift */ -static u_short maxfmode, chipset; - - - /* - * Broadcast Video Timings - * - * Horizontal values are in 35 ns (SHRES) units - * Vertical values are in interlaced scanlines - */ - -#define PAL_DIWSTRT_H (360) /* PAL Window Limits */ -#define PAL_DIWSTRT_V (48) -#define PAL_HTOTAL (1816) -#define PAL_VTOTAL (625) - -#define NTSC_DIWSTRT_H (360) /* NTSC Window Limits */ -#define NTSC_DIWSTRT_V (40) -#define NTSC_HTOTAL (1816) -#define NTSC_VTOTAL (525) - - - /* - * Monitor Specifications - * - * These are typical for a `generic' Amiga monitor (e.g. A1960) - */ - -static long vfmin = 50, vfmax = 90, hfmin = 15000, hfmax = 38000; - - - /* - * Various macros - */ - -#define up2(v) (((v)+1) & -2) -#define down2(v) ((v) & -2) -#define div2(v) ((v)>>1) -#define mod2(v) ((v) & 1) - -#define up4(v) (((v)+3) & -4) -#define down4(v) ((v) & -4) -#define mul4(v) ((v)<<2) -#define div4(v) ((v)>>2) -#define mod4(v) ((v) & 3) - -#define up8(v) (((v)+7) & -8) -#define down8(v) ((v) & -8) -#define div8(v) ((v)>>3) -#define mod8(v) ((v) & 7) - -#define up16(v) (((v)+15) & -16) -#define down16(v) ((v) & -16) -#define div16(v) ((v)>>4) -#define mod16(v) ((v) & 15) - -#define up32(v) (((v)+31) & -32) -#define down32(v) ((v) & -32) -#define div32(v) ((v)>>5) -#define mod32(v) ((v) & 31) - -#define up64(v) (((v)+63) & -64) -#define down64(v) ((v) & -64) -#define div64(v) ((v)>>6) -#define mod64(v) ((v) & 63) - -#define upx(x,v) (((v)+(x)-1) & -(x)) -#define downx(x,v) ((v) & -(x)) -#define modx(x,v) ((v) & ((x)-1)) - -/* if x1 is not a constant, this macro won't make real sense :-) */ -#define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \ - "d" (x2), "d" ((long)((x1)/0x100000000ULL)), "0" ((long)(x1))); res;}) - -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) - -#define highw(x) ((u_long)(x)>>16 & 0xffff) -#define loww(x) ((u_long)(x) & 0xffff) - -#define arraysize(x) (sizeof(x)/sizeof(*(x))) - -#define VBlankOn() custom.intena = IF_SETCLR|IF_COPER -#define VBlankOff() custom.intena = IF_COPER - - - /* - * Chip RAM we reserve for the Frame Buffer - * - * This defines the Maximum Virtual Screen Size - * (Setable per kernel options?) - */ - -#define VIDEOMEMSIZE_AGA_2M (1310720) /* AGA (2MB) : max 1280*1024*256 */ -#define VIDEOMEMSIZE_AGA_1M (786432) /* AGA (1MB) : max 1024*768*256 */ -#define VIDEOMEMSIZE_ECS_2M (655360) /* ECS (2MB) : max 1280*1024*16 */ -#define VIDEOMEMSIZE_ECS_1M (393216) /* ECS (1MB) : max 1024*768*16 */ -#define VIDEOMEMSIZE_OCS (262144) /* OCS : max ca. 800*600*16 */ - -#define SPRITEMEMSIZE (64*64/4) /* max 64*64*4 */ -#define DUMMYSPRITEMEMSIZE (8) - -#define CHIPRAM_SAFETY_LIMIT (16384) - -static u_long videomemory, spritememory; -static u_long videomemorysize; - - /* - * This is the earliest allowed start of fetching display data. - * Only if you really want no hardware cursor and audio, - * set this to 128, but let it better at 192 - */ - -static u_long min_fstrt = 192; - -#define assignchunk(name, type, ptr, size) \ -{ \ - (name) = (type)(ptr); \ - ptr += size; \ -} - - - /* - * Copper Instructions - */ - -#define CMOVE(val, reg) (CUSTOM_OFS(reg)<<16 | (val)) -#define CMOVE2(val, reg) ((CUSTOM_OFS(reg)+2)<<16 | (val)) -#define CWAIT(x, y) (((y) & 0x1fe)<<23 | ((x) & 0x7f0)<<13 | 0x0001fffe) -#define CEND (0xfffffffe) - - -typedef union { - u_long l; - u_short w[2]; -} copins; - -static struct copdisplay { - copins *init; - copins *wait; - copins *list[2][2]; - copins *rebuild[2]; -} copdisplay; - -static u_short currentcop = 0; - - /* - * Hardware Cursor - */ - -static int cursorrate = 20; /* Number of frames/flash toggle */ -static u_short cursorstate = -1; -static u_short cursormode = FB_CURSOR_OFF; - -static u_short *lofsprite, *shfsprite, *dummysprite; - - /* - * Current Video Mode - */ - -static struct amiga_fb_par { - - /* General Values */ - - int xres; /* vmode */ - int yres; /* vmode */ - int vxres; /* vmode */ - int vyres; /* vmode */ - int xoffset; /* vmode */ - int yoffset; /* vmode */ - u_short bpp; /* vmode */ - u_short clk_shift; /* vmode */ - u_short line_shift; /* vmode */ - int vmode; /* vmode */ - u_short diwstrt_h; /* vmode */ - u_short diwstop_h; /* vmode */ - u_short diwstrt_v; /* vmode */ - u_short diwstop_v; /* vmode */ - u_long next_line; /* modulo for next line */ - u_long next_plane; /* modulo for next plane */ - - /* Cursor Values */ - - struct { - short crsr_x; /* movecursor */ - short crsr_y; /* movecursor */ - short spot_x; - short spot_y; - u_short height; - u_short width; - u_short fmode; - } crsr; - - /* OCS Hardware Registers */ - - u_long bplpt0; /* vmode, pan (Note: physical address) */ - u_long bplpt0wrap; /* vmode, pan (Note: physical address) */ - u_short ddfstrt; - u_short ddfstop; - u_short bpl1mod; - u_short bpl2mod; - u_short bplcon0; /* vmode */ - u_short bplcon1; /* vmode */ - u_short htotal; /* vmode */ - u_short vtotal; /* vmode */ - - /* Additional ECS Hardware Registers */ - - u_short bplcon3; /* vmode */ - u_short beamcon0; /* vmode */ - u_short hsstrt; /* vmode */ - u_short hsstop; /* vmode */ - u_short hbstrt; /* vmode */ - u_short hbstop; /* vmode */ - u_short vsstrt; /* vmode */ - u_short vsstop; /* vmode */ - u_short vbstrt; /* vmode */ - u_short vbstop; /* vmode */ - u_short hcenter; /* vmode */ - - /* Additional AGA Hardware Registers */ - - u_short fmode; /* vmode */ -} currentpar; - -static int currcon = 0; - -static struct display disp[MAX_NR_CONSOLES]; -static struct fb_info fb_info; - -static int node; /* node of the /dev/fb?current file */ - - /* - * The minimum period for audio depends on htotal (for OCS/ECS/AGA) - * (Imported from arch/m68k/amiga/amisound.c) - */ - -extern volatile u_short amiga_audio_min_period; - - /* - * Since we can't read the palette on OCS/ECS, and since reading one - * single color palette entry require 5 expensive custom chip bus accesses - * on AGA, we keep a copy of the current palette. - */ - -#if defined(CONFIG_AMIFB_AGA) -static struct { u_char red, green, blue, pad; } palette[256]; -#else -static struct { u_char red, green, blue, pad; } palette[32]; -#endif - -#if defined(CONFIG_AMIFB_ECS) -static u_short ecs_palette[32]; -#endif - - /* - * Latches for Display Changes during VBlank - */ - -static u_short do_vmode_full = 0; /* Change the Video Mode */ -static u_short do_vmode_pan = 0; /* Update the Video Mode */ -static short do_blank = 0; /* (Un)Blank the Screen (±1) */ -static u_short do_cursor = 0; /* Move the Cursor */ - - - /* - * Various Flags - */ - -static u_short is_blanked = 0; /* Screen is Blanked */ -static u_short is_lace = 0; /* Screen is laced */ - - /* - * Frame Buffer Name - * - * The rest of the name is filled in during initialization - */ - -static char amiga_fb_name[16] = "Amiga "; - - /* - * Predefined Video Mode Names - * - * The a2024-?? modes don't work yet because there's no A2024 driver. - */ - -static char *amiga_fb_modenames[] = { - - /* - * Autodetect (Default) Video Mode - */ - - "default", - - /* - * AmigaOS Video Modes - */ - - "ntsc", /* 640x200, 15 kHz, 60 Hz (NTSC) */ - "ntsc-lace", /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */ - "pal", /* 640x256, 15 kHz, 50 Hz (PAL) */ - "pal-lace", /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */ - "multiscan", /* 640x480, 29 kHz, 57 Hz */ - "multiscan-lace", /* 640x960, 29 kHz, 57 Hz interlaced */ - "a2024-10", /* 1024x800, 10 Hz (Not yet supported) */ - "a2024-15", /* 1024x800, 15 Hz (Not yet supported) */ - "euro36", /* 640x200, 15 kHz, 72 Hz */ - "euro36-lace", /* 640x400, 15 kHz, 72 Hz interlaced */ - "euro72", /* 640x400, 29 kHz, 68 Hz */ - "euro72-lace", /* 640x800, 29 kHz, 68 Hz interlaced */ - "super72", /* 800x300, 23 kHz, 70 Hz */ - "super72-lace", /* 800x600, 23 kHz, 70 Hz interlaced */ - "dblntsc", /* 640x200, 27 kHz, 57 Hz doublescan */ - "dblntsc-ff", /* 640x400, 27 kHz, 57 Hz */ - "dblntsc-lace", /* 640x800, 27 kHz, 57 Hz interlaced */ - "dblpal", /* 640x256, 27 kHz, 47 Hz doublescan */ - "dblpal-ff", /* 640x512, 27 kHz, 47 Hz */ - "dblpal-lace", /* 640x1024, 27 kHz, 47 Hz interlaced */ - - /* - * VGA Video Modes - */ - - "vga", /* 640x480, 31 kHz, 60 Hz (VGA) */ - "vga70", /* 640x400, 31 kHz, 70 Hz (VGA) */ - - /* - * User Defined Video Modes: to be set after boot up using e.g. fbset - */ - - "user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7" -}; - -static struct fb_var_screeninfo amiga_fb_predefined[] = { - - /* - * Autodetect (Default) Video Mode - */ - - { 0, }, - - /* - * AmigaOS Video Modes - */ - - { - /* ntsc */ - 640, 200, 640, 200, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 44, 16, 76, 2, - FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* ntsc-lace */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 88, 33, 76, 4, - FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, { - /* pal */ - 640, 256, 640, 256, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 40, 14, 76, 2, - FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* pal-lace */ - 640, 512, 640, 512, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 80, 29, 76, 4, - FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, { - /* multiscan */ - 640, 480, 640, 480, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 96, 112, 29, 8, 72, 8, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - - }, { - /* multiscan-lace */ - 640, 960, 640, 960, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 96, 112, 58, 16, 72, 16, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, { - /* a2024-10 (Not yet supported) */ - 1024, 800, 1024, 800, 0, 0, 2, 0, - {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 0, 0, 0, 0, 0, 0, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* a2024-15 (Not yet supported) */ - 1024, 800, 1024, 800, 0, 0, 2, 0, - {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 0, 0, 0, 0, 0, 0, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* euro36 */ - 640, 200, 640, 200, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 92, 124, 6, 6, 52, 5, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* euro36-lace */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 92, 124, 12, 12, 52, 10, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, { - /* euro72 */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 164, 92, 9, 9, 80, 8, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* euro72-lace */ - 640, 800, 640, 800, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 164, 92, 18, 18, 80, 16, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, { - /* super72 */ - 800, 300, 800, 300, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 212, 140, 10, 11, 80, 7, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* super72-lace */ - 800, 600, 800, 600, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 212, 140, 20, 22, 80, 14, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, { - /* dblntsc */ - 640, 200, 640, 200, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 18, 17, 80, 4, - 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP - }, { - /* dblntsc-ff */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 36, 35, 80, 7, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* dblntsc-lace */ - 640, 800, 640, 800, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 72, 70, 80, 14, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, { - /* dblpal */ - 640, 256, 640, 256, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 14, 13, 80, 4, - 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP - }, { - /* dblpal-ff */ - 640, 512, 640, 512, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 28, 27, 80, 7, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* dblpal-lace */ - 640, 1024, 640, 1024, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 56, 54, 80, 14, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, - - /* - * VGA Video Modes - */ - - { - /* vga */ - 640, 480, 640, 480, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 64, 96, 30, 9, 112, 2, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, { - /* vga70 */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 64, 96, 35, 12, 112, 2, - FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - }, - - /* - * User Defined Video Modes - */ - - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, } -}; - -#define NUM_USER_MODES (8) -#define NUM_TOTAL_MODES arraysize(amiga_fb_predefined) -#define NUM_PREDEF_MODES (NUM_TOTAL_MODES-NUM_USER_MODES) - -static int amifb_ilbm = 0; /* interleaved or normal bitplanes */ - -static int amifb_inverse = 0; -static int amifb_usermode = 0; - - /* - * Some default modes - */ - -#define DEFMODE_PAL "pal" /* for PAL OCS/ECS */ -#define DEFMODE_NTSC "ntsc" /* for NTSC OCS/ECS */ -#define DEFMODE_AMBER_PAL "pal-lace" /* for flicker fixed PAL (A3000) */ -#define DEFMODE_AMBER_NTSC "ntsc-lace" /* for flicker fixed NTSC (A3000) */ -#define DEFMODE_AGA "vga70" /* for AGA */ - - /* - * Macros for the conversion from real world values to hardware register - * values - * - * This helps us to keep our attention on the real stuff... - * - * Hardware limits for AGA: - * - * parameter min max step - * --------- --- ---- ---- - * diwstrt_h 0 2047 1 - * diwstrt_v 0 2047 1 - * diwstop_h 0 4095 1 - * diwstop_v 0 4095 1 - * - * ddfstrt 0 2032 16 - * ddfstop 0 2032 16 - * - * htotal 8 2048 8 - * hsstrt 0 2040 8 - * hsstop 0 2040 8 - * vtotal 1 4096 1 - * vsstrt 0 4095 1 - * vsstop 0 4095 1 - * hcenter 0 2040 8 - * - * hbstrt 0 2047 1 - * hbstop 0 2047 1 - * vbstrt 0 4095 1 - * vbstop 0 4095 1 - * - * Horizontal values are in 35 ns (SHRES) pixels - * Vertical values are in half scanlines - */ - -/* bplcon1 (smooth scrolling) */ - -#define hscroll2hw(hscroll) \ - (((hscroll)<<12 & 0x3000) | ((hscroll)<<8 & 0xc300) | \ - ((hscroll)<<4 & 0x0c00) | ((hscroll)<<2 & 0x00f0) | ((hscroll)>>2 & 0x000f)) - -/* diwstrt/diwstop/diwhigh (visible display window) */ - -#define diwstrt2hw(diwstrt_h, diwstrt_v) \ - (((diwstrt_v)<<7 & 0xff00) | ((diwstrt_h)>>2 & 0x00ff)) -#define diwstop2hw(diwstop_h, diwstop_v) \ - (((diwstop_v)<<7 & 0xff00) | ((diwstop_h)>>2 & 0x00ff)) -#define diwhigh2hw(diwstrt_h, diwstrt_v, diwstop_h, diwstop_v) \ - (((diwstop_h)<<3 & 0x2000) | ((diwstop_h)<<11 & 0x1800) | \ - ((diwstop_v)>>1 & 0x0700) | ((diwstrt_h)>>5 & 0x0020) | \ - ((diwstrt_h)<<3 & 0x0018) | ((diwstrt_v)>>9 & 0x0007)) - -/* ddfstrt/ddfstop (display DMA) */ - -#define ddfstrt2hw(ddfstrt) div8(ddfstrt) -#define ddfstop2hw(ddfstop) div8(ddfstop) - -/* hsstrt/hsstop/htotal/vsstrt/vsstop/vtotal/hcenter (sync timings) */ - -#define hsstrt2hw(hsstrt) (div8(hsstrt)) -#define hsstop2hw(hsstop) (div8(hsstop)) -#define htotal2hw(htotal) (div8(htotal)-1) -#define vsstrt2hw(vsstrt) (div2(vsstrt)) -#define vsstop2hw(vsstop) (div2(vsstop)) -#define vtotal2hw(vtotal) (div2(vtotal)-1) -#define hcenter2hw(htotal) (div8(htotal)) - -/* hbstrt/hbstop/vbstrt/vbstop (blanking timings) */ - -#define hbstrt2hw(hbstrt) (((hbstrt)<<8 & 0x0700) | ((hbstrt)>>3 & 0x00ff)) -#define hbstop2hw(hbstop) (((hbstop)<<8 & 0x0700) | ((hbstop)>>3 & 0x00ff)) -#define vbstrt2hw(vbstrt) (div2(vbstrt)) -#define vbstop2hw(vbstop) (div2(vbstop)) - -/* colour */ - -#define rgb2hw8_high(red, green, blue) \ - (((red)<<4 & 0xf00) | ((green) & 0x0f0) | ((blue)>>4 & 0x00f)) -#define rgb2hw8_low(red, green, blue) \ - (((red)<<8 & 0xf00) | ((green)<<4 & 0x0f0) | ((blue) & 0x00f)) -#define rgb2hw4(red, green, blue) \ - (((red)<<8 & 0xf00) | ((green)<<4 & 0x0f0) | ((blue) & 0x00f)) -#define rgb2hw2(red, green, blue) \ - (((red)<<10 & 0xc00) | ((green)<<6 & 0x0c0) | ((blue)<<2 & 0x00c)) - -/* sprpos/sprctl (sprite positioning) */ - -#define spr2hw_pos(start_v, start_h) \ - (((start_v)<<7&0xff00) | ((start_h)>>3&0x00ff)) -#define spr2hw_ctl(start_v, start_h, stop_v) \ - (((stop_v)<<7&0xff00) | ((start_v)>>4&0x0040) | ((stop_v)>>5&0x0020) | \ - ((start_h)<<3&0x0018) | ((start_v)>>7&0x0004) | ((stop_v)>>8&0x0002) | \ - ((start_h)>>2&0x0001)) - -/* get current vertical position of beam */ -#define get_vbpos() ((u_short)((*(u_long volatile *)&custom.vposr >> 7) & 0xffe)) - - /* - * Copper Initialisation List - */ - -#define COPINITSIZE (sizeof(copins)*40) - -enum { - cip_bplcon0 -}; - - /* - * Long Frame/Short Frame Copper List - * Don't change the order, build_copper()/rebuild_copper() rely on this - */ - -#define COPLISTSIZE (sizeof(copins)*64) - -enum { - cop_wait, cop_bplcon0, - cop_spr0ptrh, cop_spr0ptrl, - cop_diwstrt, cop_diwstop, - cop_diwhigh, -}; - - /* - * Pixel modes for Bitplanes and Sprites - */ - -static u_short bplpixmode[3] = { - BPC0_SHRES, /* 35 ns */ - BPC0_HIRES, /* 70 ns */ - 0 /* 140 ns */ -}; - -static u_short sprpixmode[3] = { - BPC3_SPRES1 | BPC3_SPRES0, /* 35 ns */ - BPC3_SPRES1, /* 70 ns */ - BPC3_SPRES0 /* 140 ns */ -}; - - /* - * Fetch modes for Bitplanes and Sprites - */ - -static u_short bplfetchmode[3] = { - 0, /* 1x */ - FMODE_BPL32, /* 2x */ - FMODE_BPAGEM | FMODE_BPL32 /* 4x */ -}; - -static u_short sprfetchmode[3] = { - 0, /* 1x */ - FMODE_SPR32, /* 2x */ - FMODE_SPAGEM | FMODE_SPR32 /* 4x */ -}; - - /* - * Default Colormaps - */ - -static u_short red2[] = - { 0x0000, 0xc000 }; -static u_short green2[] = - { 0x0000, 0xc000 }; -static u_short blue2[] = - { 0x0000, 0xc000 }; - -static u_short red4[] = - { 0x0000, 0xc000, 0x8000, 0xffff }; -static u_short green4[] = - { 0x0000, 0xc000, 0x8000, 0xffff }; -static u_short blue4[] = - { 0x0000, 0xc000, 0x8000, 0xffff }; - -static u_short red8[] = - { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000 }; -static u_short green8[] = - { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000 }; -static u_short blue8[] = - { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000 }; - -static u_short red16[] = - { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000, - 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff }; -static u_short green16[] = - { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000, - 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff }; -static u_short blue16[] = - { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, - 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff }; - - -static struct fb_cmap default_2_colors = - { 0, 2, red2, green2, blue2, NULL }; -static struct fb_cmap default_8_colors = - { 0, 8, red8, green8, blue8, NULL }; -static struct fb_cmap default_4_colors = - { 0, 4, red4, green4, blue4, NULL }; -static struct fb_cmap default_16_colors = - { 0, 16, red16, green16, blue16, NULL }; - - /* - * Interface used by the world - */ - -void amiga_video_setup(char *options, int *ints); - -static int amiga_fb_get_fix(struct fb_fix_screeninfo *fix, int con); -static int amiga_fb_get_var(struct fb_var_screeninfo *var, int con); -static int amiga_fb_set_var(struct fb_var_screeninfo *var, int con); -static int amiga_fb_pan_display(struct fb_var_screeninfo *var, int con); -static int amiga_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con); -static int amiga_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con); -static int amiga_fb_ioctl(struct inode *inode, struct file *file, u_int cmd, - u_long arg, int con); - -static int amiga_fb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con); -static int amiga_fb_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con); -static int amiga_fb_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con); -static int amiga_fb_get_cursorstate(struct fb_cursorstate *state, int con); -static int amiga_fb_set_cursorstate(struct fb_cursorstate *state, int con); - - /* - * Interface to the low level console driver - */ - -struct fb_info *amiga_fb_init(long *mem_start); -static int amifbcon_switch(int con); -static int amifbcon_updatevar(int con); -static void amifbcon_blank(int blank); -static int amifbcon_setcmap(struct fb_cmap *cmap, int con); - - /* - * Internal routines - */ - -static struct fb_cmap *get_default_colormap(int bpp); -static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc); -static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc); -static void do_install_cmap(int con); -static void memcpy_fs(int fsfromto, void *to, void *from, int len); -static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto); -static int alloc_cmap(struct fb_cmap *cmap, int len, int transp); -static int flash_cursor(void); -static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp); -static void get_video_mode(const char *name); -static void check_default_mode(void); -static u_long chipalloc(u_long size); -static char *strtoke(char *s,const char *ct); - - /* - * Hardware routines - */ - -static int ami_encode_fix(struct fb_fix_screeninfo *fix, - struct amiga_fb_par *par); -static int ami_decode_var(struct fb_var_screeninfo *var, - struct amiga_fb_par *par); -static int ami_encode_var(struct fb_var_screeninfo *var, - struct amiga_fb_par *par); -static void ami_get_par(struct amiga_fb_par *par); -static void ami_set_var(struct fb_var_screeninfo *var); -#ifdef DEBUG -static void ami_set_par(struct amiga_fb_par *par); -#endif -static void ami_pan_var(struct fb_var_screeninfo *var); -static int ami_update_par(void); -static int ami_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, - u_int *transp); -static int ami_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp); -static void ami_update_display(void); -static void ami_init_display(void); -static void ami_do_blank(void); -static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con); -static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con); -static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con); -static int ami_get_cursorstate(struct fb_cursorstate *state, int con); -static int ami_set_cursorstate(struct fb_cursorstate *state, int con); -static void ami_set_sprite(void); -static void ami_init_copper(void); -static void ami_reinit_copper(void); -static void ami_build_copper(void); -static void ami_rebuild_copper(void); - - - /* - * External references - */ - -extern unsigned short ami_intena_vals[]; - - /* - * Support for Graphics Boards - */ - -#ifdef CONFIG_FB_CYBER /* Cybervision */ -extern int Cyber_probe(void); -extern void Cyber_video_setup(char *options, int *ints); -extern struct fb_info *Cyber_fb_init(long *mem_start); - -static int amifb_Cyber = 0; -#endif - -#ifdef CONFIG_FB_RETINAZ3 /* RetinaZ3 */ -extern int retz3_probe(void); -extern void retz3_video_setup(char *options, int *ints); -extern struct fb_info *retz3_fb_init(long *mem_start); - -static int amifb_retz3 = 0; -#endif - -#ifdef CONFIG_GSP_RESOLVER /* DMI Resolver */ -extern int resolver_probe(void); -extern void resolver_video_setup(char *options, int *ints); -extern struct fb_info *resolver_fb_init(long *mem_start); - -static int amifb_resolver = 0; -#endif - -static struct fb_ops amiga_fb_ops = { - amiga_fb_get_fix, amiga_fb_get_var, amiga_fb_set_var, amiga_fb_get_cmap, - amiga_fb_set_cmap, amiga_fb_pan_display, amiga_fb_ioctl -}; - -void amiga_video_setup(char *options, int *ints) -{ - char *this_opt; - int i; - char mcap_spec[80]; - - /* - * Check for a Graphics Board - */ - -#ifdef CONFIG_FB_CYBER - if (options && *options) - if (!strncmp(options, "cyber", 5) && Cyber_probe()) { - amifb_Cyber = 1; - Cyber_video_setup(options, ints); - return; - } -#endif -#ifdef CONFIG_FB_RETINAZ3 - if (options && *options) - if (!strncmp(options, "retz3", 5) && retz3_probe()) { - amifb_retz3 = 1; - retz3_video_setup(options, ints); - return; - } -#endif -#ifdef CONFIG_GSP_RESOLVER - if (options && *options) - if (!strncmp(options, "resolver", 5) && resolver_probe()) { - amifb_resolver = 1; - resolver_video_setup(options, ints); - return; - } -#endif - - mcap_spec[0] = '\0'; - fb_info.fontname[0] = '\0'; - - if (!options || !*options) - return; - - for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) { - char *p; - - if (!strcmp(this_opt, "inverse")) { - amifb_inverse = 1; - for (i = 0; i < 16; i++) { - red16[i] = ~red16[i]; - green16[i] = ~green16[i]; - blue16[i] = ~blue16[i]; - } - for (i = 0; i < 8; i++) { - red8[i] = ~red8[i]; - green8[i] = ~green8[i]; - blue8[i] = ~blue8[i]; - } - for (i = 0; i < 4; i++) { - red4[i] = ~red4[i]; - green4[i] = ~green4[i]; - blue4[i] = ~blue4[i]; - } - for (i = 0; i < 2; i++) { - red2[i] = ~red2[i]; - green2[i] = ~green2[i]; - blue2[i] = ~blue2[i]; - } - } else if (!strcmp(this_opt, "ilbm")) - amifb_ilbm = 1; - else if (!strncmp(this_opt, "monitorcap:", 11)) - strcpy(mcap_spec, this_opt+11); - else if (!strncmp(this_opt, "font:", 5)) - strcpy(fb_info.fontname, this_opt+5); - else if (!strncmp(this_opt, "fstart:", 7)) - min_fstrt = simple_strtoul(this_opt+7, NULL, 0); - else if (!strncmp(this_opt, "depth:", 6)) - amiga_fb_predefined[0].bits_per_pixel = - simple_strtoul(this_opt+6, NULL, 0); - else if (!strncmp(this_opt, "size:", 5)) { - p = this_opt + 5; - if (*p != ';') - amiga_fb_predefined[0].xres = - simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amiga_fb_predefined[0].yres = - simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amiga_fb_predefined[0].xres_virtual = - simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amiga_fb_predefined[0].yres_virtual = - simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p) - amiga_fb_predefined[0].bits_per_pixel = - simple_strtoul(p, NULL, 0); - } else if (!strncmp(this_opt, "timing:", 7)) { - p = this_opt + 7; - if (*p != ';') - amiga_fb_predefined[0].left_margin = - simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amiga_fb_predefined[0].right_margin = - simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amiga_fb_predefined[0].upper_margin = - simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p) - amiga_fb_predefined[0].lower_margin = - simple_strtoul(p, NULL, 0); - } else if (!strncmp(this_opt, "sync:", 5)) { - p = this_opt + 5; - if (*p != ';') - amiga_fb_predefined[0].hsync_len = - simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p) - amiga_fb_predefined[0].vsync_len = - simple_strtoul(p, NULL, 0); - } else - get_video_mode(this_opt); - } - - if (min_fstrt < 48) - min_fstrt = 48; - - if (*mcap_spec) { - char *p; - int vmin, vmax, hmin, hmax; - - /* Format for monitor capabilities is: <Vmin>;<Vmax>;<Hmin>;<Hmax> - * <V*> vertical freq. in Hz - * <H*> horizontal freq. in kHz - */ - - if (!(p = strtoke(mcap_spec, ";")) || !*p) - goto cap_invalid; - vmin = simple_strtoul(p, NULL, 10); - if (vmin <= 0) - goto cap_invalid; - if (!(p = strtoke(NULL, ";")) || !*p) - goto cap_invalid; - vmax = simple_strtoul(p, NULL, 10); - if (vmax <= 0 || vmax <= vmin) - goto cap_invalid; - if (!(p = strtoke(NULL, ";")) || !*p) - goto cap_invalid; - hmin = 1000 * simple_strtoul(p, NULL, 10); - if (hmin <= 0) - goto cap_invalid; - if (!(p = strtoke(NULL, "")) || !*p) - goto cap_invalid; - hmax = 1000 * simple_strtoul(p, NULL, 10); - if (hmax <= 0 || hmax <= hmin) - goto cap_invalid; - - vfmin = vmin; - vfmax = vmax; - hfmin = hmin; - hfmax = hmax; -cap_invalid: - ; - } -} - - /* - * Get the Fixed Part of the Display - */ - -static int amiga_fb_get_fix(struct fb_fix_screeninfo *fix, int con) -{ - struct amiga_fb_par par; - - if (con == -1) - ami_get_par(&par); - else { - int err; - - if ((err = ami_decode_var(&disp[con].var, &par))) - return err; - } - return ami_encode_fix(fix, &par); -} - - /* - * Get the User Defined Part of the Display - */ - -static int amiga_fb_get_var(struct fb_var_screeninfo *var, int con) -{ - int err = 0; - - if (con == -1) { - struct amiga_fb_par par; - - ami_get_par(&par); - err = ami_encode_var(var, &par); - } else - *var = disp[con].var; - return err; -} - - /* - * Set the User Defined Part of the Display - */ - -static int amiga_fb_set_var(struct fb_var_screeninfo *var, int con) -{ - int err, activate = var->activate; - int oldxres, oldyres, oldvxres, oldvyres, oldbpp; - struct amiga_fb_par par; - - - /* - * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! - * as FB_VMODE_SMOOTH_XPAN is only used internally - */ - - if (var->vmode & FB_VMODE_CONUPDATE) { - var->vmode |= FB_VMODE_YWRAP; - var->xoffset = disp[con].var.xoffset; - var->yoffset = disp[con].var.yoffset; - } - if ((err = ami_decode_var(var, &par))) - return err; - ami_encode_var(var, &par); - if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { - oldxres = disp[con].var.xres; - oldyres = disp[con].var.yres; - oldvxres = disp[con].var.xres_virtual; - oldvyres = disp[con].var.yres_virtual; - oldbpp = disp[con].var.bits_per_pixel; - disp[con].var = *var; - if (oldxres != var->xres || oldyres != var->yres || - oldvxres != var->xres_virtual || oldvyres != var->yres_virtual || - oldbpp != var->bits_per_pixel) { - struct fb_fix_screeninfo fix; - - ami_encode_fix(&fix, &par); - disp[con].screen_base = (u_char *)fix.smem_start; - disp[con].visual = fix.visual; - disp[con].type = fix.type; - disp[con].type_aux = fix.type_aux; - disp[con].ypanstep = fix.ypanstep; - disp[con].ywrapstep = fix.ywrapstep; - disp[con].line_length = fix.line_length; - disp[con].can_soft_blank = 1; - disp[con].inverse = amifb_inverse; - if (fb_info.changevar) - (*fb_info.changevar)(con); - } - if (oldbpp != var->bits_per_pixel) { - if ((err = alloc_cmap(&disp[con].cmap, 0, 0))) - return err; - do_install_cmap(con); - } - if (con == currcon) - ami_set_var(&disp[con].var); - } - return 0; -} - - /* - * Pan or Wrap the Display - * - * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag - */ - -static int amiga_fb_pan_display(struct fb_var_screeninfo *var, int con) -{ - if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset<0 || var->yoffset >= disp[con].var.yres_virtual || var->xoffset) - return -EINVAL; - } else { - /* - * TODO: There will be problems when xpan!=1, so some columns - * on the right side will never be seen - */ - if (var->xoffset+disp[con].var.xres > upx(16<<maxfmode, disp[con].var.xres_virtual) || - var->yoffset+disp[con].var.yres > disp[con].var.yres_virtual) - return -EINVAL; - } - if (con == currcon) - ami_pan_var(var); - disp[con].var.xoffset = var->xoffset; - disp[con].var.yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - disp[con].var.vmode |= FB_VMODE_YWRAP; - else - disp[con].var.vmode &= ~FB_VMODE_YWRAP; - return 0; -} - - /* - * Get the Colormap - */ - -static int amiga_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) -{ - if (con == currcon) /* current console? */ - return do_fb_get_cmap(cmap, &disp[con].var, kspc); - else if (disp[con].cmap.len) /* non default colormap? */ - copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2); - else - copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), - cmap, kspc ? 0 : 2); - return 0; -} - - /* - * Set the Colormap - */ - -static int amiga_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) -{ - int err; - - if (!disp[con].cmap.len) { /* no colormap allocated? */ - if ((err = alloc_cmap(&disp[con].cmap, - 1<<disp[con].var.bits_per_pixel, 0))) - return err; - } - if (con == currcon) /* current console? */ - return do_fb_set_cmap(cmap, &disp[con].var, kspc); - else - copy_cmap(cmap, &disp[con].cmap, kspc ? 0 : 1); - return 0; -} - - /* - * Amiga Frame Buffer Specific ioctls - */ - -static int amiga_fb_ioctl(struct inode *inode, struct file *file, - u_int cmd, u_long arg, int con) -{ - int i; - - switch (cmd) { - case FBIOGET_FCURSORINFO : { - struct fb_fix_cursorinfo crsrfix; - - i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrfix)); - if (!i) { - i = amiga_fb_get_fix_cursorinfo(&crsrfix, con); - copy_to_user((void *)arg, &crsrfix, sizeof(crsrfix)); - } - return i; - } - case FBIOGET_VCURSORINFO : { - struct fb_var_cursorinfo crsrvar; - - i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrvar)); - if (!i) { - i = amiga_fb_get_var_cursorinfo(&crsrvar, - ((struct fb_var_cursorinfo *)arg)->data, con); - copy_to_user((void *)arg, &crsrvar, sizeof(crsrvar)); - } - return i; - } - case FBIOPUT_VCURSORINFO : { - struct fb_var_cursorinfo crsrvar; - - i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrvar)); - if (!i) { - copy_from_user(&crsrvar, (void *)arg, sizeof(crsrvar)); - i = amiga_fb_set_var_cursorinfo(&crsrvar, - ((struct fb_var_cursorinfo *)arg)->data, con); - } - return i; - } - case FBIOGET_CURSORSTATE : { - struct fb_cursorstate crsrstate; - - i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrstate)); - if (!i) { - i = amiga_fb_get_cursorstate(&crsrstate, con); - copy_to_user((void *)arg, &crsrstate, sizeof(crsrstate)); - } - return i; - } - case FBIOPUT_CURSORSTATE : { - struct fb_cursorstate crsrstate; - - i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrstate)); - if (!i) { - copy_from_user(&crsrstate, (void *)arg, sizeof(crsrstate)); - i = amiga_fb_set_cursorstate(&crsrstate, con); - } - return i; - } -#ifdef DEBUG - case FBCMD_GET_CURRENTPAR : { - struct amiga_fb_par par; - - i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct amiga_fb_par)); - if (!i) { - ami_get_par(&par); - copy_to_user((void *)arg, &par, sizeof(struct amiga_fb_par)); - } - return i; - } - case FBCMD_SET_CURRENTPAR : { - struct amiga_fb_par par; - - i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct amiga_fb_par)); - if (!i) { - copy_from_user(&par, (void *)arg, sizeof(struct amiga_fb_par)); - ami_set_par(&par); - } - return i; - } -#endif */ DEBUG */ - } - return -EINVAL; -} - - /* - * Hardware Cursor - */ - -static int amiga_fb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con) -{ - return ami_get_fix_cursorinfo(fix, con); -} - -static int amiga_fb_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con) -{ - return ami_get_var_cursorinfo(var, data, con); -} - -static int amiga_fb_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con) -{ - return ami_set_var_cursorinfo(var, data, con); -} - -static int amiga_fb_get_cursorstate(struct fb_cursorstate *state, int con) -{ - return ami_get_cursorstate(state, con); -} - -static int amiga_fb_set_cursorstate(struct fb_cursorstate *state, int con) -{ - return ami_set_cursorstate(state, con); -} - - /* - * Initialisation - */ - -__initfunc(struct fb_info *amiga_fb_init(long *mem_start)) -{ - int err, tag, i; - u_long chipptr; - - /* - * Check for a Graphics Board - */ - -#ifdef CONFIG_FB_CYBER - if (amifb_Cyber) - return Cyber_fb_init(mem_start); -#endif -#ifdef CONFIG_FB_RETINAZ3 - if (amifb_retz3){ - custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | - DMAF_BLITTER | DMAF_SPRITE; - return retz3_fb_init(mem_start); - } -#endif -#ifdef CONFIG_GSP_RESOLVER - if (amifb_resolver){ - custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | - DMAF_BLITTER | DMAF_SPRITE; - return NULL; - } -#endif - - /* - * Use the Builtin Chipset - */ - - if (!AMIGAHW_PRESENT(AMI_VIDEO)) - return NULL; - - custom.dmacon = DMAF_ALL | DMAF_MASTER; - - switch (amiga_chipset) { -#ifdef CONFIG_AMIFB_OCS - case CS_OCS: - strcat(amiga_fb_name, "OCS"); -default_chipset: - chipset = TAG_OCS; - maxdepth[TAG_SHRES] = 0; /* OCS means no SHRES */ - maxdepth[TAG_HIRES] = 4; - maxdepth[TAG_LORES] = 6; - maxfmode = TAG_FMODE_1; - if (!amifb_usermode) /* Set the Default Video Mode */ - get_video_mode(amiga_vblank == 50 ? - DEFMODE_PAL : DEFMODE_NTSC); - videomemorysize = VIDEOMEMSIZE_OCS; - break; -#endif /* CONFIG_AMIFB_OCS */ - -#ifdef CONFIG_AMIFB_ECS - case CS_ECS: - strcat(amiga_fb_name, "ECS"); - chipset = TAG_ECS; - maxdepth[TAG_SHRES] = 2; - maxdepth[TAG_HIRES] = 4; - maxdepth[TAG_LORES] = 6; - maxfmode = TAG_FMODE_1; - if (!amifb_usermode) { /* Set the Default Video Mode */ - if (AMIGAHW_PRESENT(AMBER_FF)) - get_video_mode(amiga_vblank == 50 ? - DEFMODE_AMBER_PAL : DEFMODE_AMBER_NTSC); - else - get_video_mode(amiga_vblank == 50 ? - DEFMODE_PAL : DEFMODE_NTSC); - } - if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT > - VIDEOMEMSIZE_ECS_1M) - videomemorysize = VIDEOMEMSIZE_ECS_2M; - else - videomemorysize = VIDEOMEMSIZE_ECS_1M; - break; -#endif /* CONFIG_AMIFB_ECS */ - -#ifdef CONFIG_AMIFB_AGA - case CS_AGA: - strcat(amiga_fb_name, "AGA"); - chipset = TAG_AGA; - maxdepth[TAG_SHRES] = 8; - maxdepth[TAG_HIRES] = 8; - maxdepth[TAG_LORES] = 8; - maxfmode = TAG_FMODE_4; - if (!amifb_usermode) /* Set the Default Video Mode */ - get_video_mode(DEFMODE_AGA); - if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT > - VIDEOMEMSIZE_AGA_1M) - videomemorysize = VIDEOMEMSIZE_AGA_2M; - else - videomemorysize = VIDEOMEMSIZE_AGA_1M; - break; -#endif /* CONFIG_AMIFB_AGA */ - - default: -#ifdef CONFIG_AMIFB_OCS - printk("Unknown graphics chipset, defaulting to OCS\n"); - strcat(amiga_fb_name, "Unknown"); - goto default_chipset; -#else /* CONFIG_AMIFB_OCS */ - panic("Unknown graphics chipset, no default driver"); -#endif /* CONFIG_AMIFB_OCS */ - break; - } - - /* - * Calculate the Pixel Clock Values for this Machine - */ - - pixclock[TAG_SHRES] = DIVUL(25E9, amiga_eclock); /* SHRES: 35 ns / 28 MHz */ - pixclock[TAG_HIRES] = DIVUL(50E9, amiga_eclock); /* HIRES: 70 ns / 14 MHz */ - pixclock[TAG_LORES] = DIVUL(100E9, amiga_eclock); /* LORES: 140 ns / 7 MHz */ - - /* - * Replace the Tag Values with the Real Pixel Clock Values - */ - - for (i = 0; i < NUM_PREDEF_MODES; i++) { - tag = amiga_fb_predefined[i].pixclock; - if (tag == TAG_SHRES || tag == TAG_HIRES || tag == TAG_LORES) { - amiga_fb_predefined[i].pixclock = pixclock[tag]; - if (amiga_fb_predefined[i].bits_per_pixel > maxdepth[tag]) - amiga_fb_predefined[i].bits_per_pixel = maxdepth[tag]; - } - } - - err = register_framebuffer(amiga_fb_name, &node, &amiga_fb_ops, - NUM_TOTAL_MODES, amiga_fb_predefined); - if (err < 0) - panic("Cannot register frame buffer"); - - chipptr = chipalloc(videomemorysize+ - SPRITEMEMSIZE+ - DUMMYSPRITEMEMSIZE+ - COPINITSIZE+ - 4*COPLISTSIZE); - - assignchunk(videomemory, u_long, chipptr, videomemorysize); - assignchunk(spritememory, u_long, chipptr, SPRITEMEMSIZE); - assignchunk(dummysprite, u_short *, chipptr, DUMMYSPRITEMEMSIZE); - assignchunk(copdisplay.init, copins *, chipptr, COPINITSIZE); - assignchunk(copdisplay.list[0][0], copins *, chipptr, COPLISTSIZE); - assignchunk(copdisplay.list[0][1], copins *, chipptr, COPLISTSIZE); - assignchunk(copdisplay.list[1][0], copins *, chipptr, COPLISTSIZE); - assignchunk(copdisplay.list[1][1], copins *, chipptr, COPLISTSIZE); - - memset(dummysprite, 0, DUMMYSPRITEMEMSIZE); - - /* - * Enable Display DMA - */ - - custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | - DMAF_BLITTER | DMAF_SPRITE; - - /* - * Make sure the Copper has something to do - */ - - ami_init_copper(); - - check_default_mode(); - - if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, IRQ_FLG_LOCK, - "fb vertb handler", NULL)) - panic("Couldn't add vblank interrupt\n"); - ami_intena_vals[IRQ_AMIGA_VERTB] = IF_COPER; - ami_intena_vals[IRQ_AMIGA_COPPER] = 0; - custom.intena = IF_VERTB; - custom.intena = IF_SETCLR | IF_COPER; - - strcpy(fb_info.modename, amiga_fb_name); - fb_info.changevar = NULL; - fb_info.disp = disp; - fb_info.switch_con = &amifbcon_switch; - fb_info.updatevar = &amifbcon_updatevar; - fb_info.blank = &amifbcon_blank; - fb_info.setcmap = &amifbcon_setcmap; - - amiga_fb_set_var(&amiga_fb_predefined[0], 0); - - return &fb_info; -} - -static int amifbcon_switch(int con) -{ - /* Do we have to save the colormap? */ - if (disp[currcon].cmap.len) - do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1); - - currcon = con; - ami_set_var(&disp[con].var); - /* Install new colormap */ - do_install_cmap(con); - return 0; -} - - /* - * Update the `var' structure (called by amicon.c) - */ - -static int amifbcon_updatevar(int con) -{ - ami_pan_var(&disp[con].var); - return 0; -} - - /* - * Blank the display. - */ - -static void amifbcon_blank(int blank) -{ - do_blank = blank ? blank : -1; -} - - /* - * Set the colormap - */ - -static int amifbcon_setcmap(struct fb_cmap *cmap, int con) -{ - return(amiga_fb_set_cmap(cmap, 1, con)); -} - -/* ---------------------------- Generic routines ---------------------------- */ - -static struct fb_cmap *get_default_colormap(int bpp) -{ - switch (bpp) { - case 1: - return &default_2_colors; - break; - case 2: - return &default_4_colors; - break; - case 3: - return &default_8_colors; - break; - default: - return &default_16_colors; - break; - } -} - -#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16) -#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \ - ((1<<(width))-1)) : 0)) - -static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc) -{ - int i, start; - u_short *red, *green, *blue, *transp; - u_int hred, hgreen, hblue, htransp; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - start = cmap->start; - if (start < 0) - return -EINVAL; - for (i = 0; i < cmap->len; i++) { - if (ami_getcolreg(start++, &hred, &hgreen, &hblue, &htransp)) - return 0; - hred = CNVT_FROMHW(hred, var->red.length); - hgreen = CNVT_FROMHW(hgreen, var->green.length); - hblue = CNVT_FROMHW(hblue, var->blue.length); - htransp = CNVT_FROMHW(htransp, var->transp.length); - if (kspc) { - *red = hred; - *green = hgreen; - *blue = hblue; - if (transp) - *transp = htransp; - } else { - put_user(hred, red); - put_user(hgreen, green); - put_user(hblue, blue); - if (transp) - put_user(htransp, transp); - } - red++; - green++; - blue++; - if (transp) - transp++; - } - return 0; -} - -static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc) -{ - int i, start; - u_short *red, *green, *blue, *transp; - u_int hred, hgreen, hblue, htransp; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - start = cmap->start; - - if (start < 0) - return -EINVAL; - for (i = 0; i < cmap->len; i++) { - if (kspc) { - hred = *red; - hgreen = *green; - hblue = *blue; - htransp = transp ? *transp : 0; - } else { - get_user(hred, red); - get_user(hgreen, green); - get_user(hblue, blue); - if (transp) - get_user(htransp, transp); - else - htransp = 0; - } - hred = CNVT_TOHW(hred, var->red.length); - hgreen = CNVT_TOHW(hgreen, var->green.length); - hblue = CNVT_TOHW(hblue, var->blue.length); - htransp = CNVT_TOHW(htransp, var->transp.length); - red++; - green++; - blue++; - if (transp) - transp++; - if (ami_setcolreg(start++, hred, hgreen, hblue, htransp)) - return 0; - } - return 0; -} - -static void do_install_cmap(int con) -{ - if (con != currcon) - return; - if (disp[con].cmap.len) - do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1); - else - do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel), - &disp[con].var, 1); -} - -static void memcpy_fs(int fsfromto, void *to, void *from, int len) -{ - switch (fsfromto) { - case 0: - memcpy(to, from, len); - return; - case 1: - copy_from_user(to, from, len); - return; - case 2: - copy_to_user(to, from, len); - return; - } -} - -static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto) -{ - int size; - int tooff = 0, fromoff = 0; - - if (to->start > from->start) - fromoff = to->start-from->start; - else - tooff = from->start-to->start; - size = to->len-tooff; - if (size > from->len-fromoff) - size = from->len-fromoff; - if (size < 0) - return; - size *= sizeof(u_short); - memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size); - memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size); - memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size); - if (from->transp && to->transp) - memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size); -} - -static int alloc_cmap(struct fb_cmap *cmap, int len, int transp) -{ - int size = len*sizeof(u_short); - - if (cmap->len != len) { - if (cmap->red) - kfree(cmap->red); - if (cmap->green) - kfree(cmap->green); - if (cmap->blue) - kfree(cmap->blue); - if (cmap->transp) - kfree(cmap->transp); - cmap->red = cmap->green = cmap->blue = cmap->transp = NULL; - cmap->len = 0; - if (!len) - return 0; - if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) - return -1; - if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) - return -1; - if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) - return -1; - if (transp) { - if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) - return -1; - } else - cmap->transp = NULL; - } - cmap->start = 0; - cmap->len = len; - copy_cmap(get_default_colormap(len), cmap, 0); - return 0; -} - -static int flash_cursor(void) -{ - static int cursorcount = 1; - - if (cursormode == FB_CURSOR_FLASH) { - if (!--cursorcount) { - cursorstate = -cursorstate; - cursorcount = cursorrate; - if (!is_blanked) - return 1; - } - } - return 0; -} - - /* - * VBlank Display Interrupt - */ - -static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp) -{ - u_short ints = custom.intreqr & custom.intenar; - static struct irq_server server = {0, 0}; - unsigned long flags; - - if (ints & IF_BLIT) { - custom.intreq = IF_BLIT; - amiga_do_irq(IRQ_AMIGA_BLIT, fp); - } - - if (ints & IF_COPER) { - custom.intreq = IF_COPER; - if (do_vmode_pan || do_vmode_full) - ami_update_display(); - - if (do_vmode_full) - ami_init_display(); - - if (do_vmode_pan) { - flash_cursor(); - ami_rebuild_copper(); - do_cursor = do_vmode_pan = 0; - } else if (do_cursor) { - flash_cursor(); - ami_set_sprite(); - do_cursor = 0; - } else { - if (flash_cursor()) - ami_set_sprite(); - } - - save_flags(flags); - cli(); - if (get_vbpos() < down2(currentpar.diwstrt_v - 6)) - custom.copjmp2 = 0; - restore_flags(flags); - - if (do_blank) { - ami_do_blank(); - do_blank = 0; - } - - if (do_vmode_full) { - ami_reinit_copper(); - do_vmode_full = 0; - } - amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server); - } - - if (ints & IF_VERTB) { - printk("%s: Warning: IF_VERTB was enabled\n", __FUNCTION__); - custom.intena = IF_VERTB; - } -} - - /* - * Get a Video Mode - */ - -static void get_video_mode(const char *name) -{ - int i; - - for (i = 1; i < NUM_PREDEF_MODES; i++) { - if (!strcmp(name, amiga_fb_modenames[i])) { - amiga_fb_predefined[0] = amiga_fb_predefined[i]; - amifb_usermode = i; - return; - } - } -} - - /* - * Probe the Video Modes - */ - -static void check_default_mode(void) -{ - struct amiga_fb_par par; - int mode; - - for (mode = 0; mode < NUM_PREDEF_MODES; mode++) { - if (!ami_decode_var(&amiga_fb_predefined[mode], &par)) { - if (mode) - amiga_fb_predefined[0] = amiga_fb_predefined[mode]; - return; - } - if (!mode) - printk("Can't use default video mode. Probing video modes...\n"); - } - panic("Can't find any usable video mode"); -} - - /* - * Allocate, Clear and Align a Block of Chip Memory - */ - -static u_long chipalloc(u_long size) -{ - u_long ptr; - - size += PAGE_SIZE-1; - if (!(ptr = (u_long)amiga_chip_alloc(size))) - panic("No Chip RAM for frame buffer"); - memset((void *)ptr, 0, size); - ptr = PAGE_ALIGN(ptr); - - return ptr; -} - - /* - * A strtok which returns empty strings, too - */ - -static char *strtoke(char *s,const char *ct) -{ - char *sbegin, *send; - static char *ssave = NULL; - - sbegin = s ? s : ssave; - if (!sbegin) - return NULL; - if (*sbegin == '\0') { - ssave = NULL; - return NULL; - } - send = strpbrk(sbegin, ct); - if (send && *send != '\0') - *send++ = '\0'; - ssave = send; - return sbegin; -} - -/* --------------------------- Hardware routines --------------------------- */ - - /* - * This function should fill in the `fix' structure based on the - * values in the `par' structure. - */ - -static int ami_encode_fix(struct fb_fix_screeninfo *fix, - struct amiga_fb_par *par) -{ - int i; - - strcpy(fix->id, amiga_fb_name); - fix->smem_start = videomemory; - fix->smem_len = videomemorysize; - - if (amifb_ilbm) { - fix->type = FB_TYPE_INTERLEAVED_PLANES; - fix->type_aux = par->next_line; - } else { - fix->type = FB_TYPE_PLANES; - fix->type_aux = 0; - } - fix->line_length = div8(upx(16<<maxfmode, par->vxres)); - fix->visual = FB_VISUAL_PSEUDOCOLOR; - - if (par->vmode & FB_VMODE_YWRAP) { - fix->ywrapstep = 1; - fix->xpanstep = fix->ypanstep = 0; - } else { - fix->ywrapstep = 0; - if (par->vmode &= FB_VMODE_SMOOTH_XPAN) - fix->xpanstep = 1; - else - fix->xpanstep = 16<<maxfmode; - fix->ypanstep = 1; - } - - for (i = 0; i < arraysize(fix->reserved); i++) - fix->reserved[i] = 0; - - return 0; -} - - /* - * Get the video params out of `var'. If a value doesn't fit, round - * it up, if it's too big, return -EINVAL. - */ - -static int ami_decode_var(struct fb_var_screeninfo *var, - struct amiga_fb_par *par) -{ - u_short clk_shift, line_shift; - u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n; - u_long hrate = 0, vrate = 0; - - /* - * Find a matching Pixel Clock - */ - - for (clk_shift = TAG_SHRES; clk_shift < TAG_LORES; clk_shift++) - if (var->pixclock <= pixclock[clk_shift]) - break; - if (clk_shift >= TAG_LORES) - return -EINVAL; - par->clk_shift = clk_shift; - - /* - * Check the Geometry Values - */ - - if ((par->xres = var->xres) < 64) - return -EINVAL; - if ((par->yres = var->yres) < 64) - return -EINVAL; - if ((par->vxres = var->xres_virtual) < 64) - return -EINVAL; - if ((par->vyres = var->yres_virtual) < 64) - return -EINVAL; - - par->bpp = var->bits_per_pixel; - if (!var->nonstd) { - if (par->bpp <= 0 || par->bpp > maxdepth[clk_shift]) - return -EINVAL; - } else if (var->nonstd == FB_NONSTD_HAM) { - if (par->bpp != 6) - if (par->bpp != 8 || !IS_AGA) - return -EINVAL; - } else - return -EINVAL; - - /* - * FB_VMODE_SMOOTH_XPAN will be cleared, if one of the folloing - * checks failed and smooth scrolling is not possible - */ - - par->vmode = var->vmode | FB_VMODE_SMOOTH_XPAN; - switch (par->vmode & FB_VMODE_MASK) { - case FB_VMODE_INTERLACED: - line_shift = 0; - break; - case FB_VMODE_NONINTERLACED: - line_shift = 1; - break; - case FB_VMODE_DOUBLE: - if (!IS_AGA) - return -EINVAL; - line_shift = 2; - break; - default: - return -EINVAL; - break; - } - par->line_shift = line_shift; - - /* - * Vertical and Horizontal Timings - */ - - xres_n = par->xres<<clk_shift; - yres_n = par->yres<<line_shift; - par->htotal = down8((var->left_margin+par->xres+var->right_margin+var->hsync_len)<<clk_shift); - par->vtotal = down2(((var->upper_margin+par->yres+var->lower_margin+var->vsync_len)<<line_shift)+1); - - if (IS_AGA) - par->bplcon3 = sprpixmode[clk_shift]; - else - par->bplcon3 = 0; - if (var->sync & FB_SYNC_BROADCAST) { - par->diwstop_h = par->htotal-((var->right_margin-var->hsync_len)<<clk_shift); - if (IS_AGA) - par->diwstop_h += mod4(var->hsync_len); - else - par->diwstop_h = down4(par->diwstop_h); - par->diwstrt_h = par->diwstop_h - xres_n; - par->diwstop_v = par->vtotal-((var->lower_margin-var->vsync_len)<<line_shift); - par->diwstrt_v = par->diwstop_v - yres_n; - if (par->diwstop_h >= par->htotal+8 || par->diwstop_v > par->vtotal) - return -EINVAL; - if (!IS_OCS) { - /* Initialize sync with some reasonable values for pwrsave */ - par->hsstrt = 160; - par->hsstop = 320; - par->vsstrt = 30; - par->vsstop = 34; - } else { - par->hsstrt = 0; - par->hsstop = 0; - par->vsstrt = 0; - par->vsstop = 0; - } - if (par->vtotal > (PAL_VTOTAL+NTSC_VTOTAL)/2) { - /* PAL video mode */ - if (par->htotal != PAL_HTOTAL) - return -EINVAL; - if (par->diwstrt_h < PAL_DIWSTRT_H) - return -EINVAL; - if (par->diwstrt_v < PAL_DIWSTRT_V) - return -EINVAL; - hrate = 15625; - vrate = 50; - if (!IS_OCS) { - par->beamcon0 = BMC0_PAL; - par->bplcon3 |= BPC3_BRDRBLNK; - } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) || - AMIGAHW_PRESENT(AGNUS_HR_NTSC)) { - par->beamcon0 = BMC0_PAL; - par->hsstop = 1; - } else if (amiga_vblank != 50) - return -EINVAL; - } else { - /* NTSC video mode - * In the AGA chipset seems to be hardware bug with BPC3_BRDRBLNK - * and NTSC activated, so than better let diwstop_h <= 1812 - */ - if (par->htotal != NTSC_HTOTAL) - return -EINVAL; - if (par->diwstrt_h < NTSC_DIWSTRT_H) - return -EINVAL; - if (par->diwstrt_v < NTSC_DIWSTRT_V) - return -EINVAL; - hrate = 15750; - vrate = 60; - if (!IS_OCS) { - par->beamcon0 = 0; - par->bplcon3 |= BPC3_BRDRBLNK; - } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) || - AMIGAHW_PRESENT(AGNUS_HR_NTSC)) { - par->beamcon0 = 0; - par->hsstop = 1; - } else if (amiga_vblank != 60) - return -EINVAL; - } - if (IS_OCS) { - if (par->diwstrt_h >= 1024 || par->diwstop_h < 1024 || - par->diwstrt_v >= 512 || par->diwstop_v < 256) - return -EINVAL; - } - } else if (!IS_OCS) { - /* Programmable video mode */ - par->hsstrt = var->right_margin<<clk_shift; - par->hsstop = (var->right_margin+var->hsync_len)<<clk_shift; - par->diwstop_h = par->htotal - mod8(par->hsstrt) + 8 - (1 << clk_shift); - if (!IS_AGA) - par->diwstop_h = down4(par->diwstop_h) - 16; - par->diwstrt_h = par->diwstop_h - xres_n; - par->hbstop = par->diwstrt_h + 4; - par->hbstrt = par->diwstop_h + 4; - if (par->hbstrt >= par->htotal + 8) - par->hbstrt -= par->htotal; - par->hcenter = par->hsstrt + (par->htotal >> 1); - par->vsstrt = var->lower_margin<<line_shift; - par->vsstop = (var->lower_margin+var->vsync_len)<<line_shift; - par->diwstop_v = par->vtotal; - if ((par->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) - par->diwstop_v -= 2; - par->diwstrt_v = par->diwstop_v - yres_n; - par->vbstop = par->diwstrt_v - 2; - par->vbstrt = par->diwstop_v - 2; - if (par->vtotal > 2048 || par->htotal > 2048) - return -EINVAL; - par->bplcon3 |= BPC3_EXTBLKEN; - par->beamcon0 = BMC0_HARDDIS | BMC0_VARVBEN | BMC0_LOLDIS | - BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN | - BMC0_PAL | BMC0_VARCSYEN; - if (var->sync & FB_SYNC_HOR_HIGH_ACT) - par->beamcon0 |= BMC0_HSYTRUE; - if (var->sync & FB_SYNC_VERT_HIGH_ACT) - par->beamcon0 |= BMC0_VSYTRUE; - if (var->sync & FB_SYNC_COMP_HIGH_ACT) - par->beamcon0 |= BMC0_CSYTRUE; - hrate = (amiga_masterclock+par->htotal/2)/par->htotal; - vrate = div2(par->vtotal) * par->htotal; - vrate = (amiga_masterclock+vrate/2)/vrate; - } else - return -EINVAL; - - /* - * Checking the DMA timing - */ - - fconst = 16<<maxfmode<<clk_shift; - - /* - * smallest window start value without turn off other dma cycles - * than sprite1-7, unless you change min_fstrt - */ - - - fsize = ((maxfmode+clk_shift <= 1) ? fconst : 64); - fstrt = downx(fconst, par->diwstrt_h-4) - fsize; - if (fstrt < min_fstrt) - return -EINVAL; - - /* - * smallest window start value where smooth scrolling is possible - */ - - fstrt = downx(fconst, par->diwstrt_h-fconst+(1<<clk_shift)-4) - fsize; - if (fstrt < min_fstrt) - par->vmode &= ~FB_VMODE_SMOOTH_XPAN; - - maxfetchstop = down16(par->htotal - 80); - - fstrt = downx(fconst, par->diwstrt_h-4) - 64 - fconst; - fsize = upx(fconst, xres_n + modx(fconst, downx(1<<clk_shift, par->diwstrt_h-4))); - if (fstrt + fsize > maxfetchstop) - par->vmode &= ~FB_VMODE_SMOOTH_XPAN; - - fsize = upx(fconst, xres_n); - if (fstrt + fsize > maxfetchstop) - return -EINVAL; - - if (maxfmode + clk_shift <= 1) { - fsize = up64(xres_n + fconst - 1); - if (min_fstrt + fsize - 64 > maxfetchstop) - par->vmode &= ~FB_VMODE_SMOOTH_XPAN; - - fsize = up64(xres_n); - if (min_fstrt + fsize - 64 > maxfetchstop) - return -EINVAL; - - fsize -= 64; - } else - fsize -= fconst; - - /* - * Check if there is enough time to update the bitplane pointers for ywrap - */ - - if (par->htotal-fsize-64 < par->bpp*64) - par->vmode &= ~FB_VMODE_YWRAP; - - /* - * Bitplane calculations and check the Memory Requirements - */ - - if (amifb_ilbm) { - par->next_plane = div8(upx(16<<maxfmode, par->vxres)); - par->next_line = par->bpp*par->next_plane; - if (par->next_line * par->vyres > videomemorysize) - return -EINVAL; - } else { - par->next_line = div8(upx(16<<maxfmode, par->vxres)); - par->next_plane = par->vyres*par->next_line; - if (par->next_plane * par->bpp > videomemorysize) - return -EINVAL; - } - - /* - * Hardware Register Values - */ - - par->bplcon0 = BPC0_COLOR | bplpixmode[clk_shift]; - if (!IS_OCS) - par->bplcon0 |= BPC0_ECSENA; - if (par->bpp == 8) - par->bplcon0 |= BPC0_BPU3; - else - par->bplcon0 |= par->bpp<<12; - if (var->nonstd == FB_NONSTD_HAM) - par->bplcon0 |= BPC0_HAM; - if (var->sync & FB_SYNC_EXT) - par->bplcon0 |= BPC0_ERSY; - - if (IS_AGA) - par->fmode = bplfetchmode[maxfmode]; - - switch (par->vmode & FB_VMODE_MASK) { - case FB_VMODE_INTERLACED: - par->bplcon0 |= BPC0_LACE; - break; - case FB_VMODE_DOUBLE: - if (IS_AGA) - par->fmode |= FMODE_SSCAN2 | FMODE_BSCAN2; - break; - } - - if (!((par->vmode ^ var->vmode) & FB_VMODE_YWRAP)) { - par->xoffset = var->xoffset; - par->yoffset = var->yoffset; - if (par->vmode & FB_VMODE_YWRAP) { - if (par->xoffset || par->yoffset < 0 || par->yoffset >= par->vyres) - par->xoffset = par->yoffset = 0; - } else { - if (par->xoffset < 0 || par->xoffset > upx(16<<maxfmode, par->vxres-par->xres) || - par->yoffset < 0 || par->yoffset > par->vyres-par->yres) - par->xoffset = par->yoffset = 0; - } - } else - par->xoffset = par->yoffset = 0; - - par->crsr.crsr_x = par->crsr.crsr_y = 0; - par->crsr.spot_x = par->crsr.spot_y = 0; - par->crsr.height = par->crsr.width = 0; - - if (hrate < hfmin || hrate > hfmax || vrate < vfmin || vrate > vfmax) - return -EINVAL; - - return 0; -} - - /* - * Fill the `var' structure based on the values in `par' and maybe - * other values read out of the hardware. - */ - -static int ami_encode_var(struct fb_var_screeninfo *var, - struct amiga_fb_par *par) -{ - u_short clk_shift, line_shift; - int i; - - clk_shift = par->clk_shift; - line_shift = par->line_shift; - - var->xres = par->xres; - var->yres = par->yres; - var->xres_virtual = par->vxres; - var->yres_virtual = par->vyres; - var->xoffset = par->xoffset; - var->yoffset = par->yoffset; - - var->bits_per_pixel = par->bpp; - var->grayscale = 0; - - if (IS_AGA) { - var->red.offset = 0; - var->red.length = 8; - var->red.msb_right = 0; - } else { - if (clk_shift == TAG_SHRES) { - var->red.offset = 0; - var->red.length = 2; - var->red.msb_right = 0; - } else { - var->red.offset = 0; - var->red.length = 4; - var->red.msb_right = 0; - } - } - var->blue = var->green = var->red; - var->transp.offset = 0; - var->transp.length = 0; - var->transp.msb_right = 0; - - if (par->bplcon0 & BPC0_HAM) - var->nonstd = FB_NONSTD_HAM; - else - var->nonstd = 0; - var->activate = 0; - - var->height = -1; - var->width = -1; - var->accel = 0; - - var->pixclock = pixclock[clk_shift]; - - if (IS_AGA && par->fmode & FMODE_BSCAN2) - var->vmode = FB_VMODE_DOUBLE; - else if (par->bplcon0 & BPC0_LACE) - var->vmode = FB_VMODE_INTERLACED; - else - var->vmode = FB_VMODE_NONINTERLACED; - - if (!IS_OCS && par->beamcon0 & BMC0_VARBEAMEN) { - var->hsync_len = (par->hsstop-par->hsstrt)>>clk_shift; - var->right_margin = par->hsstrt>>clk_shift; - var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len; - var->vsync_len = (par->vsstop-par->vsstrt)>>line_shift; - var->lower_margin = par->vsstrt>>line_shift; - var->upper_margin = (par->vtotal>>line_shift) - var->yres - var->lower_margin - var->vsync_len; - var->sync = 0; - if (par->beamcon0 & BMC0_HSYTRUE) - var->sync |= FB_SYNC_HOR_HIGH_ACT; - if (par->beamcon0 & BMC0_VSYTRUE) - var->sync |= FB_SYNC_VERT_HIGH_ACT; - if (par->beamcon0 & BMC0_CSYTRUE) - var->sync |= FB_SYNC_COMP_HIGH_ACT; - } else { - var->sync = FB_SYNC_BROADCAST; - var->hsync_len = (152>>clk_shift) + mod4(par->diwstop_h); - var->right_margin = ((par->htotal - down4(par->diwstop_h))>>clk_shift) + var->hsync_len; - var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len; - var->vsync_len = 4>>line_shift; - var->lower_margin = ((par->vtotal - par->diwstop_v)>>line_shift) + var->vsync_len; - var->upper_margin = (((par->vtotal - 2)>>line_shift) + 1) - var->yres - - var->lower_margin - var->vsync_len; - } - - if (par->bplcon0 & BPC0_ERSY) - var->sync |= FB_SYNC_EXT; - if (par->vmode & FB_VMODE_YWRAP) - var->vmode |= FB_VMODE_YWRAP; - - for (i = 0; i < arraysize(var->reserved); i++) - var->reserved[i] = 0; - - return 0; -} - - /* - * Get current hardware setting - */ - -static void ami_get_par(struct amiga_fb_par *par) -{ - *par = currentpar; -} - - /* - * Set new videomode - */ - -static void ami_set_var(struct fb_var_screeninfo *var) -{ - do_vmode_pan = 0; - do_vmode_full = 0; - ami_decode_var(var, ¤tpar); - ami_build_copper(); - do_vmode_full = 1; -} - -#ifdef DEBUG -static void ami_set_par(struct amiga_fb_par *par) -{ - do_vmode_pan = 0; - do_vmode_full = 0; - currentpar = *par; - ami_build_copper(); - do_vmode_full = 1; -} -#endif - - /* - * Pan or Wrap the Display - * - * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag - * in `var'. - */ - -static void ami_pan_var(struct fb_var_screeninfo *var) -{ - struct amiga_fb_par *par = ¤tpar; - - par->xoffset = var->xoffset; - par->yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - par->vmode |= FB_VMODE_YWRAP; - else - par->vmode &= ~FB_VMODE_YWRAP; - - do_vmode_pan = 0; - ami_update_par(); - do_vmode_pan = 1; -} - - /* - * Update hardware - */ - -static int ami_update_par(void) -{ - struct amiga_fb_par *par = ¤tpar; - short clk_shift, vshift, fstrt, fsize, fstop, fconst, shift, move, mod; - - clk_shift = par->clk_shift; - - if (!(par->vmode & FB_VMODE_SMOOTH_XPAN)) - par->xoffset = upx(16<<maxfmode, par->xoffset); - - fconst = 16<<maxfmode<<clk_shift; - vshift = modx(16<<maxfmode, par->xoffset); - fstrt = par->diwstrt_h - (vshift<<clk_shift) - 4; - fsize = (par->xres+vshift)<<clk_shift; - shift = modx(fconst, fstrt); - move = downx(2<<maxfmode, div8(par->xoffset)); - if (maxfmode + clk_shift > 1) { - fstrt = downx(fconst, fstrt) - 64; - fsize = upx(fconst, fsize); - fstop = fstrt + fsize - fconst; - } else { - mod = fstrt = downx(fconst, fstrt) - fconst; - fstop = fstrt + upx(fconst, fsize) - 64; - fsize = up64(fsize); - fstrt = fstop - fsize + 64; - if (fstrt < min_fstrt) { - fstop += min_fstrt - fstrt; - fstrt = min_fstrt; - } - move = move - div8((mod-fstrt)>>clk_shift); - } - mod = par->next_line - div8(fsize>>clk_shift); - par->ddfstrt = fstrt; - par->ddfstop = fstop; - par->bplcon1 = hscroll2hw(shift); - par->bpl2mod = mod; - if (par->bplcon0 & BPC0_LACE) - par->bpl2mod += par->next_line; - if (IS_AGA && (par->fmode & FMODE_BSCAN2)) - par->bpl1mod = -div8(fsize>>clk_shift); - else - par->bpl1mod = par->bpl2mod; - - if (par->yoffset) { - par->bplpt0 = ZTWO_PADDR((u_long)videomemory + par->next_line*par->yoffset + move); - if (par->vmode & FB_VMODE_YWRAP) { - if (par->yoffset > par->vyres-par->yres) { - par->bplpt0wrap = ZTWO_PADDR((u_long)videomemory + move); - if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v+par->vyres-par->yoffset)) - par->bplpt0wrap += par->next_line; - } - } - } else - par->bplpt0 = ZTWO_PADDR((u_long)videomemory + move); - - if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v)) - par->bplpt0 += par->next_line; - - return 0; -} - - /* - * Read a single color register and split it into - * colors/transparent. Return != 0 for invalid regno. - */ - -static int ami_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, - u_int *transp) -{ - if (IS_AGA) { - if (regno > 255) - return 1; - } else { - if (regno > 31) - return 1; - } - - *red = palette[regno].red; - *green = palette[regno].green; - *blue = palette[regno].blue; - return 0; -} - - - /* - * Set a single color register. The values supplied are already - * rounded down to the hardware's capabilities (according to the - * entries in the var structure). Return != 0 for invalid regno. - */ - -static int ami_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp) -{ -#if defined(CONFIG_AMIFB_AGA) - u_short bplcon3 = currentpar.bplcon3; - - if (IS_AGA) { - if (regno > 255) - return 1; - } else -#endif - if (regno > 31) - return 1; - - /* - * Update the corresponding Hardware Color Register, unless it's Color - * Register 0 and the screen is blanked. - * - * VBlank is switched off to protect bplcon3 or ecs_palette[] from - * being changed by ami_do_blank() during the VBlank. - */ - - palette[regno].red = red; - palette[regno].green = green; - palette[regno].blue = blue; - - if (regno || !is_blanked) { -#if defined(CONFIG_AMIFB_AGA) - if (IS_AGA) { - VBlankOff(); - custom.bplcon3 = bplcon3 | (regno<<8 & 0xe000); - custom.color[regno&31] = rgb2hw8_high(red, green, blue); - custom.bplcon3 = bplcon3 | (regno<<8 & 0xe000) | BPC3_LOCT; - custom.color[regno&31] = rgb2hw8_low(red, green, blue); - custom.bplcon3 = bplcon3; - VBlankOn(); - } else -#endif - { -#if defined(CONFIG_AMIFB_ECS) - if (currentpar.bplcon0 & BPC0_SHRES) { - u_short color, mask; - int i; - - mask = 0x3333; - color = rgb2hw2(red, green, blue); - VBlankOff(); - for (i = regno+12; i >= (int)regno; i -= 4) - custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color; - mask <<=2; color >>= 2; - regno = down16(regno)+mul4(mod4(regno)); - for (i = regno+3; i >= (int)regno; i--) - custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color; - VBlankOn(); - } else -#endif - custom.color[regno] = rgb2hw4(red, green, blue); - } - } - return 0; -} - -static void ami_update_display(void) -{ - struct amiga_fb_par *par = ¤tpar; - - custom.bplcon1 = par->bplcon1; - custom.bpl1mod = par->bpl1mod; - custom.bpl2mod = par->bpl2mod; - custom.ddfstrt = ddfstrt2hw(par->ddfstrt); - custom.ddfstop = ddfstop2hw(par->ddfstop); -} - - /* - * Change the video mode (called by VBlank interrupt) - */ - -static void ami_init_display(void) -{ - struct amiga_fb_par *par = ¤tpar; - - custom.bplcon0 = par->bplcon0 & ~BPC0_LACE; - custom.bplcon2 = (IS_OCS ? 0 : BPC2_KILLEHB) | BPC2_PF2P2 | BPC2_PF1P2; - if (!IS_OCS) { - custom.bplcon3 = par->bplcon3; - if (IS_AGA) - custom.bplcon4 = BPC4_ESPRM4 | BPC4_OSPRM4; - if (par->beamcon0 & BMC0_VARBEAMEN) { - custom.htotal = htotal2hw(par->htotal); - custom.hbstrt = hbstrt2hw(par->hbstrt); - custom.hbstop = hbstop2hw(par->hbstop); - custom.hsstrt = hsstrt2hw(par->hsstrt); - custom.hsstop = hsstop2hw(par->hsstop); - custom.hcenter = hcenter2hw(par->hcenter); - custom.vtotal = vtotal2hw(par->vtotal); - custom.vbstrt = vbstrt2hw(par->vbstrt); - custom.vbstop = vbstop2hw(par->vbstop); - custom.vsstrt = vsstrt2hw(par->vsstrt); - custom.vsstop = vsstop2hw(par->vsstop); - } - } - if (!IS_OCS || par->hsstop) - custom.beamcon0 = par->beamcon0; - if (IS_AGA) - custom.fmode = par->fmode; - - /* - * The minimum period for audio depends on htotal - */ - - amiga_audio_min_period = div16(par->htotal); - - is_lace = par->bplcon0 & BPC0_LACE ? 1 : 0; -#if 1 - if (is_lace) { - if (custom.vposr & 0x8000) - custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][1]); - else - custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][0]); - } else { - custom.vposw = custom.vposr | 0x8000; - custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][1]); - } -#else - custom.vposw = custom.vposr | 0x8000; - custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][1]); -#endif -} - - /* - * (Un)Blank the screen (called by VBlank interrupt) - */ - -static void ami_do_blank(void) -{ - struct amiga_fb_par *par = ¤tpar; -#if defined(CONFIG_AMIFB_AGA) - u_short bplcon3 = par->bplcon3; -#endif - u_char red, green, blue; - - if (do_blank > 0) { - custom.dmacon = DMAF_RASTER | DMAF_SPRITE; - red = green = blue = 0; - if (!IS_OCS && do_blank > 1) { - switch (do_blank) { - case 2 : /* suspend vsync */ - custom.hsstrt = hsstrt2hw(par->hsstrt); - custom.hsstop = hsstop2hw(par->hsstop); - custom.vsstrt = vsstrt2hw(par->vtotal+4); - custom.vsstop = vsstop2hw(par->vtotal+4); - break; - case 3 : /* suspend hsync */ - custom.hsstrt = hsstrt2hw(par->htotal+16); - custom.hsstop = hsstop2hw(par->htotal+16); - custom.vsstrt = vsstrt2hw(par->vsstrt); - custom.vsstop = vsstrt2hw(par->vsstop); - break; - case 4 : /* powerdown */ - custom.hsstrt = hsstrt2hw(par->htotal+16); - custom.hsstop = hsstop2hw(par->htotal+16); - custom.vsstrt = vsstrt2hw(par->vtotal+4); - custom.vsstop = vsstop2hw(par->vtotal+4); - break; - } - if (!(par->beamcon0 & BMC0_VARBEAMEN)) { - custom.htotal = htotal2hw(par->htotal); - custom.vtotal = vtotal2hw(par->vtotal); - custom.beamcon0 = BMC0_HARDDIS | BMC0_VARBEAMEN | - BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARCSYEN; - } - } - } else { - custom.dmacon = DMAF_SETCLR | DMAF_RASTER | DMAF_SPRITE; - red = palette[0].red; - green = palette[0].green; - blue = palette[0].blue; - if (!IS_OCS) { - custom.hsstrt = hsstrt2hw(par->hsstrt); - custom.hsstop = hsstop2hw(par->hsstop); - custom.vsstrt = vsstrt2hw(par->vsstrt); - custom.vsstop = vsstop2hw(par->vsstop); - custom.beamcon0 = par->beamcon0; - } - } -#if defined(CONFIG_AMIFB_AGA) - if (IS_AGA) { - custom.bplcon3 = bplcon3; - custom.color[0] = rgb2hw8_high(red, green, blue); - custom.bplcon3 = bplcon3 | BPC3_LOCT; - custom.color[0] = rgb2hw8_low(red, green, blue); - custom.bplcon3 = bplcon3; - } else -#endif - { -#if defined(CONFIG_AMIFB_ECS) - if (par->bplcon0 & BPC0_SHRES) { - u_short color, mask; - int i; - - mask = 0x3333; - color = rgb2hw2(red, green, blue); - for (i = 12; i >= 0; i -= 4) - custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color; - mask <<=2; color >>= 2; - for (i = 3; i >= 0; i--) - custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color; - } else -#endif - custom.color[0] = rgb2hw4(red, green, blue); - } - is_blanked = do_blank > 0 ? do_blank : 0; -} - - /* - * Flash the cursor (called by VBlank interrupt) - */ - -static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con) -{ - struct amiga_fb_par *par = ¤tpar; - - fix->crsr_width = fix->crsr_xsize = par->crsr.width; - fix->crsr_height = fix->crsr_ysize = par->crsr.height; - fix->crsr_color1 = 17; - fix->crsr_color2 = 18; - return 0; -} - -static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con) -{ - struct amiga_fb_par *par = ¤tpar; - register u_short *lspr, *sspr; - register u_long datawords asm ("d2"); - register short delta; - register u_char color; - short height, width, bits, words; - int i, size, alloc; - - size = par->crsr.height*par->crsr.width; - alloc = var->height*var->width; - var->height = par->crsr.height; - var->width = par->crsr.width; - var->xspot = par->crsr.spot_x; - var->yspot = par->crsr.spot_y; - if (size > var->height*var->width) - return -ENAMETOOLONG; - if ((i = verify_area(VERIFY_WRITE, (void *)data, size))) - return i; - delta = 1<<par->crsr.fmode; - lspr = lofsprite + (delta<<1); - if (par->bplcon0 & BPC0_LACE) - sspr = shfsprite + (delta<<1); - else - sspr = 0; - for (height = (short)var->height-1; height >= 0; height--) { - bits = 0; words = delta; datawords = 0; - for (width = (short)var->width-1; width >= 0; width--) { - if (bits == 0) { - bits = 16; --words; - asm volatile ("movew %1@(%3:w:2),%0 ; swap %0 ; movew %1@+,%0" - : "=d" (datawords), "=a" (lspr) : "1" (lspr), "d" (delta)); - } - --bits; - asm volatile ( - "clrb %0 ; swap %1 ; lslw #1,%1 ; roxlb #1,%0 ; " - "swap %1 ; lslw #1,%1 ; roxlb #1,%0" - : "=d" (color), "=d" (datawords) : "1" (datawords)); - put_user(color, data++); - } - if (bits > 0) { - --words; ++lspr; - } - while (--words >= 0) - ++lspr; - asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:" - : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta)); - } - return 0; -} - -static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con) -{ - struct amiga_fb_par *par = ¤tpar; - register u_short *lspr, *sspr; - register u_long datawords asm ("d2"); - register short delta; - u_short fmode; - short height, width, bits, words; - int i; - - if (!var->width) - return -EINVAL; - else if (var->width <= 16) - fmode = TAG_FMODE_1; - else if (var->width <= 32) - fmode = TAG_FMODE_2; - else if (var->width <= 64) - fmode = TAG_FMODE_4; - else - return -EINVAL; - if (fmode > maxfmode) - return -EINVAL; - if (!var->height) - return -EINVAL; - if ((i = verify_area(VERIFY_READ, (void *)data, var->width*var->height))) - return i; - delta = 1<<fmode; - lofsprite = shfsprite = (u_short *)spritememory; - lspr = lofsprite + (delta<<1); - if (par->bplcon0 & BPC0_LACE) { - if (((var->height+4)<<fmode<<2) > SPRITEMEMSIZE) - return -EINVAL; - memset(lspr, 0, (var->height+4)<<fmode<<2); - shfsprite += ((var->height+5)&-2)<<fmode; - sspr = shfsprite + (delta<<1); - } else { - if (((var->height+2)<<fmode<<2) > SPRITEMEMSIZE) - return -EINVAL; - memset(lspr, 0, (var->height+2)<<fmode<<2); - sspr = 0; - } - for (height = (short)var->height-1; height >= 0; height--) { - bits = 16; words = delta; datawords = 0; - for (width = (short)var->width-1; width >= 0; width--) { - unsigned long tdata = 0; - get_user(tdata, (char *)data); - data++; - asm volatile ( - "lsrb #1,%2 ; roxlw #1,%0 ; swap %0 ; " - "lsrb #1,%2 ; roxlw #1,%0 ; swap %0" - : "=d" (datawords) - : "0" (datawords), "d" (tdata)); - if (--bits == 0) { - bits = 16; --words; - asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+" - : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta)); - } - } - if (bits < 16) { - --words; - asm volatile ( - "swap %2 ; lslw %4,%2 ; movew %2,%0@(%3:w:2) ; " - "swap %2 ; lslw %4,%2 ; movew %2,%0@+" - : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta), "d" (bits)); - } - while (--words >= 0) - asm volatile ("moveql #0,%%d0 ; movew %%d0,%0@(%2:w:2) ; movew %%d0,%0@+" - : "=a" (lspr) : "0" (lspr), "d" (delta) : "d0"); - asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:" - : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta)); - } - par->crsr.height = var->height; - par->crsr.width = var->width; - par->crsr.spot_x = var->xspot; - par->crsr.spot_y = var->yspot; - par->crsr.fmode = fmode; - if (IS_AGA) { - par->fmode &= ~(FMODE_SPAGEM | FMODE_SPR32); - par->fmode |= sprfetchmode[fmode]; - custom.fmode = par->fmode; - } - return 0; -} - -static int ami_get_cursorstate(struct fb_cursorstate *state, int con) -{ - struct amiga_fb_par *par = ¤tpar; - - state->xoffset = par->crsr.crsr_x; - state->yoffset = par->crsr.crsr_y; - state->mode = cursormode; - return 0; -} - -static int ami_set_cursorstate(struct fb_cursorstate *state, int con) -{ - struct amiga_fb_par *par = ¤tpar; - - par->crsr.crsr_x = state->xoffset; - par->crsr.crsr_y = state->yoffset; - if ((cursormode = state->mode) == FB_CURSOR_OFF) - cursorstate = -1; - do_cursor = 1; - return 0; -} - -static void ami_set_sprite(void) -{ - struct amiga_fb_par *par = ¤tpar; - copins *copl, *cops; - u_short hs, vs, ve; - u_long pl, ps, pt; - short mx, my; - - cops = copdisplay.list[currentcop][0]; - copl = copdisplay.list[currentcop][1]; - ps = pl = ZTWO_PADDR(dummysprite); - mx = par->crsr.crsr_x-par->crsr.spot_x; - my = par->crsr.crsr_y-par->crsr.spot_y; - if (!(par->vmode & FB_VMODE_YWRAP)) { - mx -= par->xoffset; - my -= par->yoffset; - } - if (!is_blanked && cursorstate > 0 && par->crsr.height > 0 && - mx > -(short)par->crsr.width && mx < par->xres && - my > -(short)par->crsr.height && my < par->yres) { - pl = ZTWO_PADDR(lofsprite); - hs = par->diwstrt_h + (mx<<par->clk_shift) - 4; - vs = par->diwstrt_v + (my<<par->line_shift); - ve = vs + (par->crsr.height<<par->line_shift); - if (par->bplcon0 & BPC0_LACE) { - ps = ZTWO_PADDR(shfsprite); - lofsprite[0] = spr2hw_pos(vs, hs); - shfsprite[0] = spr2hw_pos(vs+1, hs); - if (mod2(vs)) { - lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve); - shfsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs+1, hs, ve+1); - pt = pl; pl = ps; ps = pt; - } else { - lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve+1); - shfsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs+1, hs, ve); - } - } else { - lofsprite[0] = spr2hw_pos(vs, hs) | (IS_AGA && (par->fmode & FMODE_BSCAN2) ? 0x80 : 0); - lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve); - } - } - copl[cop_spr0ptrh].w[1] = highw(pl); - copl[cop_spr0ptrl].w[1] = loww(pl); - if (par->bplcon0 & BPC0_LACE) { - cops[cop_spr0ptrh].w[1] = highw(ps); - cops[cop_spr0ptrl].w[1] = loww(ps); - } -} - - /* - * Initialise the Copper Initialisation List - */ - -static void ami_init_copper(void) -{ - copins *cop = copdisplay.init; - u_long p; - int i; - - if (!IS_OCS) { - (cop++)->l = CMOVE(BPC0_COLOR | BPC0_SHRES | BPC0_ECSENA, bplcon0); - (cop++)->l = CMOVE(0x0181, diwstrt); - (cop++)->l = CMOVE(0x0281, diwstop); - (cop++)->l = CMOVE(0x0000, diwhigh); - } else - (cop++)->l = CMOVE(BPC0_COLOR, bplcon0); - p = ZTWO_PADDR(dummysprite); - for (i = 0; i < 8; i++) { - (cop++)->l = CMOVE(0, spr[i].pos); - (cop++)->l = CMOVE(highw(p), sprpt[i]); - (cop++)->l = CMOVE2(loww(p), sprpt[i]); - } - - (cop++)->l = CMOVE(IF_SETCLR | IF_COPER, intreq); - copdisplay.wait = cop; - (cop++)->l = CEND; - (cop++)->l = CMOVE(0, copjmp2); - cop->l = CEND; - - custom.cop1lc = (u_short *)ZTWO_PADDR(copdisplay.init); - custom.copjmp1 = 0; -} - -static void ami_reinit_copper(void) -{ - struct amiga_fb_par *par = ¤tpar; - - copdisplay.init[cip_bplcon0].w[1] = ~(BPC0_BPU3 | BPC0_BPU2 | BPC0_BPU1 | BPC0_BPU0) & par->bplcon0; - copdisplay.wait->l = CWAIT(32, par->diwstrt_v-4); -} - - /* - * Build the Copper List - */ - -static void ami_build_copper(void) -{ - struct amiga_fb_par *par = ¤tpar; - copins *copl, *cops; - u_long p; - - currentcop = 1 - currentcop; - - copl = copdisplay.list[currentcop][1]; - - (copl++)->l = CWAIT(0, 10); - (copl++)->l = CMOVE(par->bplcon0, bplcon0); - (copl++)->l = CMOVE(0, sprpt[0]); - (copl++)->l = CMOVE2(0, sprpt[0]); - - if (par->bplcon0 & BPC0_LACE) { - cops = copdisplay.list[currentcop][0]; - - (cops++)->l = CWAIT(0, 10); - (cops++)->l = CMOVE(par->bplcon0, bplcon0); - (cops++)->l = CMOVE(0, sprpt[0]); - (cops++)->l = CMOVE2(0, sprpt[0]); - - (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v+1), diwstrt); - (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v+1), diwstop); - (cops++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt); - (cops++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop); - if (!IS_OCS) { - (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v+1, - par->diwstop_h, par->diwstop_v+1), diwhigh); - (cops++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v, - par->diwstop_h, par->diwstop_v), diwhigh); -#if 0 - if (par->beamcon0 & BMC0_VARBEAMEN) { - (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal); - (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt+1), vbstrt); - (copl++)->l = CMOVE(vbstop2hw(par->vbstop+1), vbstop); - (cops++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal); - (cops++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt); - (cops++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop); - } -#endif - } - p = ZTWO_PADDR(copdisplay.list[currentcop][0]); - (copl++)->l = CMOVE(highw(p), cop2lc); - (copl++)->l = CMOVE2(loww(p), cop2lc); - p = ZTWO_PADDR(copdisplay.list[currentcop][1]); - (cops++)->l = CMOVE(highw(p), cop2lc); - (cops++)->l = CMOVE2(loww(p), cop2lc); - copdisplay.rebuild[0] = cops; - } else { - (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt); - (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop); - if (!IS_OCS) { - (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v, - par->diwstop_h, par->diwstop_v), diwhigh); -#if 0 - if (par->beamcon0 & BMC0_VARBEAMEN) { - (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal); - (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt); - (copl++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop); - } -#endif - } - } - copdisplay.rebuild[1] = copl; - - ami_update_par(); - ami_rebuild_copper(); -} - - /* - * Rebuild the Copper List - * - * We only change the things that are not static - */ - -static void ami_rebuild_copper(void) -{ - struct amiga_fb_par *par = ¤tpar; - copins *copl, *cops; - u_short line, h_end1, h_end2; - short i; - u_long p; - - if (IS_AGA && maxfmode + par->clk_shift == 0) - h_end1 = par->diwstrt_h-64; - else - h_end1 = par->htotal-32; - h_end2 = par->ddfstop+64; - - ami_set_sprite(); - - copl = copdisplay.rebuild[1]; - p = par->bplpt0; - if (par->vmode & FB_VMODE_YWRAP) { - if ((par->vyres-par->yoffset) != 1 || !mod2(par->diwstrt_v)) { - if (par->yoffset > par->vyres-par->yres) { - for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) { - (copl++)->l = CMOVE(highw(p), bplpt[i]); - (copl++)->l = CMOVE2(loww(p), bplpt[i]); - } - line = par->diwstrt_v + ((par->vyres-par->yoffset)<<par->line_shift) - 1; - while (line >= 512) { - (copl++)->l = CWAIT(h_end1, 510); - line -= 512; - } - if (line >= 510 && IS_AGA && maxfmode + par->clk_shift == 0) - (copl++)->l = CWAIT(h_end1, line); - else - (copl++)->l = CWAIT(h_end2, line); - p = par->bplpt0wrap; - } - } else p = par->bplpt0wrap; - } - for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) { - (copl++)->l = CMOVE(highw(p), bplpt[i]); - (copl++)->l = CMOVE2(loww(p), bplpt[i]); - } - copl->l = CEND; - - if (par->bplcon0 & BPC0_LACE) { - cops = copdisplay.rebuild[0]; - p = par->bplpt0; - if (mod2(par->diwstrt_v)) - p -= par->next_line; - else - p += par->next_line; - if (par->vmode & FB_VMODE_YWRAP) { - if ((par->vyres-par->yoffset) != 1 || mod2(par->diwstrt_v)) { - if (par->yoffset > par->vyres-par->yres+1) { - for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) { - (cops++)->l = CMOVE(highw(p), bplpt[i]); - (cops++)->l = CMOVE2(loww(p), bplpt[i]); - } - line = par->diwstrt_v + ((par->vyres-par->yoffset)<<par->line_shift) - 2; - while (line >= 512) { - (cops++)->l = CWAIT(h_end1, 510); - line -= 512; - } - if (line > 510 && IS_AGA && maxfmode + par->clk_shift == 0) - (cops++)->l = CWAIT(h_end1, line); - else - (cops++)->l = CWAIT(h_end2, line); - p = par->bplpt0wrap; - if (mod2(par->diwstrt_v+par->vyres-par->yoffset)) - p -= par->next_line; - else - p += par->next_line; - } - } else p = par->bplpt0wrap - par->next_line; - } - for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) { - (cops++)->l = CMOVE(highw(p), bplpt[i]); - (cops++)->l = CMOVE2(loww(p), bplpt[i]); - } - cops->l = CEND; - } -} diff --git a/arch/m68k/amiga/amikeyb.c b/arch/m68k/amiga/amikeyb.c deleted file mode 100644 index 5a102a12c..000000000 --- a/arch/m68k/amiga/amikeyb.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * linux/arch/m68k/amiga/amikeyb.c - * - * Amiga Keyboard driver for Linux/m68k - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -/* - * Amiga support by Hamish Macdonald - */ - -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/errno.h> -#include <linux/keyboard.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/kd.h> -#include <linux/random.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/kbd_ll.h> - -#include <asm/amigaints.h> -#include <asm/amigahw.h> -#include <asm/irq.h> - -#define AMIKEY_CAPS (0x62) -#define BREAK_MASK (0x80) -#define RESET_WARNING (0xf0) /* before rotation */ - -static u_short amiplain_map[NR_KEYS] __initdata = { - 0xf060, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, - 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf05c, 0xf200, 0xf300, - 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, - 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf200, 0xf301, 0xf302, 0xf303, - 0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, - 0xfb6c, 0xf03b, 0xf027, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306, - 0xf200, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, 0xfb62, 0xfb6e, 0xfb6d, - 0xf02c, 0xf02e, 0xf02f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309, - 0xf020, 0xf07f, 0xf009, 0xf30e, 0xf201, 0xf01b, 0xf07f, 0xf200, - 0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601, - 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107, - 0xf108, 0xf109, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf30a, 0xf11b, - 0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short amishift_map[NR_KEYS] = { - 0xf07e, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026, - 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07c, 0xf200, 0xf300, - 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, - 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf200, 0xf301, 0xf302, 0xf303, - 0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, - 0xfb4c, 0xf03a, 0xf022, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306, - 0xf200, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, 0xfb42, 0xfb4e, 0xfb4d, - 0xf03c, 0xf03e, 0xf03f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309, - 0xf020, 0xf07f, 0xf009, 0xf30e, 0xf201, 0xf01b, 0xf07f, 0xf200, - 0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601, - 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, 0xf111, - 0xf112, 0xf113, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf203, - 0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short amialtgr_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, 0xf07b, - 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200, 0xf300, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf07e, 0xf200, 0xf301, 0xf302, 0xf303, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309, - 0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601, - 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, 0xf511, 0xf512, 0xf513, - 0xf514, 0xf515, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf204, - 0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short amictrl_map[NR_KEYS] = { - 0xf000, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, - 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf01c, 0xf200, 0xf300, - 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, - 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf200, 0xf301, 0xf302, 0xf303, - 0xf001, 0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, - 0xf00c, 0xf200, 0xf007, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306, - 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, 0xf002, 0xf00e, 0xf00d, - 0xf200, 0xf200, 0xf07f, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309, - 0xf000, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601, - 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106, 0xf107, - 0xf108, 0xf109, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf202, - 0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short amishift_ctrl_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302, 0xf303, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf310, 0xf307, 0xf308, 0xf309, - 0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf200, - 0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short amialt_map[NR_KEYS] = { - 0xf860, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, 0xf837, - 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf85c, 0xf200, 0xf900, - 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, - 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf200, 0xf901, 0xf902, 0xf903, - 0xf861, 0xf873, 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, - 0xf86c, 0xf83b, 0xf827, 0xf200, 0xf200, 0xf904, 0xf905, 0xf906, - 0xf200, 0xf87a, 0xf878, 0xf863, 0xf876, 0xf862, 0xf86e, 0xf86d, - 0xf82c, 0xf82e, 0xf82f, 0xf200, 0xf310, 0xf907, 0xf908, 0xf909, - 0xf820, 0xf87f, 0xf809, 0xf30e, 0xf80d, 0xf81b, 0xf87f, 0xf200, - 0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601, - 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506, 0xf507, - 0xf508, 0xf509, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf204, - 0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short amictrl_alt_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf301, 0xf302, 0xf303, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf304, 0xf305, 0xf306, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf20c, 0xf307, 0xf308, 0xf309, - 0xf200, 0xf07f, 0xf200, 0xf30e, 0xf201, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf30b, 0xf200, 0xf603, 0xf600, 0xf602, 0xf601, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf208, 0xf209, 0xf30d, 0xf30c, 0xf30a, 0xf200, - 0xf700, 0xf700, 0xf207, 0xf702, 0xf703, 0xf701, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -#define DEFAULT_KEYB_REP_DELAY (HZ/4) -#define DEFAULT_KEYB_REP_RATE (HZ/25) - -/* These could be settable by some ioctl() in future... */ -static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY; -static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE; - -static unsigned char rep_scancode; -static void amikeyb_rep(unsigned long ignore); -static struct timer_list amikeyb_rep_timer = {NULL, NULL, 0, 0, amikeyb_rep}; - -static void amikeyb_rep(unsigned long ignore) -{ - unsigned long flags; - save_flags(flags); - cli(); - - kbd_pt_regs = NULL; - - amikeyb_rep_timer.expires = jiffies + key_repeat_rate; - amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL; - add_timer(&amikeyb_rep_timer); - handle_scancode(rep_scancode); - - restore_flags(flags); -} - -static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp) -{ - unsigned char scancode, break_flag, keycode; - static int reset_warning = 0; - - /* save frame for register dump */ - kbd_pt_regs = fp; - - /* get and invert scancode (keyboard is active low) */ - scancode = ~ciaa.sdr; - - /* switch SP pin to output for handshake */ - ciaa.cra |= 0x40; - -#if 0 // No longer used - /* - * On receipt of the second RESET_WARNING, we must not pull KDAT high - * again to delay the hard reset as long as possible. - * - * Note that not all keyboards send reset warnings... - */ - if (reset_warning) - if (scancode == RESET_WARNING) { - printk(KERN_ALERT "amikeyb: Ctrl-Amiga-Amiga reset warning!!\n" - "The system will be reset within 10 seconds!!\n"); - /* Panic doesn't sync from within an interrupt, so we do nothing */ - return; - } else - /* Probably a mistake, cancel the alert */ - reset_warning = 0; -#endif - - /* wait until 85 us have expired */ - udelay(85); - /* switch CIA serial port to input mode */ - ciaa.cra &= ~0x40; - - mark_bh(KEYBOARD_BH); - - /* rotate scan code to get up/down bit in proper position */ - __asm__ __volatile__ ("rorb #1,%0" : "=g" (scancode) : "0" (scancode)); - - /* - * Check make/break first - */ - break_flag = scancode & BREAK_MASK; - keycode = scancode & (unsigned char)~BREAK_MASK; - - if (keycode == AMIKEY_CAPS) { - /* if the key is CAPS, fake a press/release. */ - handle_scancode(AMIKEY_CAPS); - handle_scancode(BREAK_MASK | AMIKEY_CAPS); - } else if (keycode < 0x78) { - /* handle repeat */ - if (break_flag) { - del_timer(&amikeyb_rep_timer); - rep_scancode = 0; - } else { - del_timer(&amikeyb_rep_timer); - rep_scancode = keycode; - amikeyb_rep_timer.expires = jiffies + key_repeat_delay; - amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL; - add_timer(&amikeyb_rep_timer); - } - handle_scancode(scancode); - } else - switch (keycode) { - case 0x78: - reset_warning = 1; - break; - case 0x79: - printk(KERN_WARNING "amikeyb: keyboard lost sync\n"); - break; - case 0x7a: - printk(KERN_WARNING "amikeyb: keyboard buffer overflow\n"); - break; -#if 0 /* obsolete according to the HRM */ - case 0x7b: - printk(KERN_WARNING "amikeyb: keyboard controller failure\n"); - break; -#endif - case 0x7c: - printk(KERN_ERR "amikeyb: keyboard selftest failure\n"); - break; - case 0x7d: - printk(KERN_INFO "amikeyb: initiate power-up key stream\n"); - break; - case 0x7e: - printk(KERN_INFO "amikeyb: terminate power-up key stream\n"); - break; -#if 0 /* obsolete according to the HRM */ - case 0x7f: - printk(KERN_WARNING "amikeyb: keyboard interrupt\n"); - break; -#endif - default: - printk(KERN_WARNING "amikeyb: unknown keyboard communication code 0x%02x\n", - scancode); - break; - } -} - -__initfunc(int amiga_keyb_init(void)) -{ - if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) - return -EIO; - - /* setup key map */ - memcpy(plain_map, amiplain_map, sizeof(plain_map)); - key_maps[1] = amishift_map; - key_maps[2] = amialtgr_map; - key_maps[4] = amictrl_map; - key_maps[5] = amishift_ctrl_map; - key_maps[8] = amialt_map; - key_maps[12] = amictrl_alt_map; - - /* - * Initialize serial data direction. - */ - ciaa.cra &= ~0x41; /* serial data in, turn off TA */ - - /* - * arrange for processing of keyboard interrupt - */ - request_irq(IRQ_AMIGA_CIAA_SP, keyboard_interrupt, 0, "keyboard", NULL); - - return 0; -} - -int amiga_kbdrate( struct kbd_repeat *k ) -{ - if (k->delay > 0) { - /* convert from msec to jiffies */ - key_repeat_delay = (k->delay * HZ + 500) / 1000; - if (key_repeat_delay < 1) - key_repeat_delay = 1; - } - if (k->rate > 0) { - key_repeat_rate = (k->rate * HZ + 500) / 1000; - if (key_repeat_rate < 1) - key_repeat_rate = 1; - } - - k->delay = key_repeat_delay * 1000 / HZ; - k->rate = key_repeat_rate * 1000 / HZ; - - return( 0 ); -} diff --git a/arch/m68k/amiga/cyberfb.c b/arch/m68k/amiga/cyberfb.c deleted file mode 100644 index b7802a67c..000000000 --- a/arch/m68k/amiga/cyberfb.c +++ /dev/null @@ -1,1253 +0,0 @@ -/* - * linux/arch/m68k/amiga/cyberfb.c -- Low level implementation of the - * Cybervision frame buffer device - * - * Copyright (C) 1996 Martin Apel - * Geert Uytterhoeven - * - * - * This file is based on the Amiga frame buffer device (amifb.c): - * - * Copyright (C) 1995 Geert Uytterhoeven - * - * - * History: - * - 22 Dec 95: Original version by Martin Apel - * - 05 Jan 96: Geert: integration into the current source tree - * - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/malloc.h> -#include <linux/delay.h> -#include <linux/zorro.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <asm/uaccess.h> -#include <asm/system.h> -#include <asm/irq.h> -#include <asm/pgtable.h> -#include "s3blit.h" - - -#define arraysize(x) (sizeof(x)/sizeof(*(x))) - -struct Cyber_fb_par { - int xres; - int yres; - int bpp; -}; - -static struct Cyber_fb_par current_par; - -static int current_par_valid = 0; -static int currcon = 0; - -static struct display disp[MAX_NR_CONSOLES]; -static struct fb_info fb_info; - -static int node; /* node of the /dev/fb?current file */ - - - /* - * Switch for Chipset Independency - */ - -static struct fb_hwswitch { - - /* Initialisation */ - - int (*init)(void); - - /* Display Control */ - - int (*encode_fix)(struct fb_fix_screeninfo *fix, struct Cyber_fb_par *par); - int (*decode_var)(struct fb_var_screeninfo *var, struct Cyber_fb_par *par); - int (*encode_var)(struct fb_var_screeninfo *var, struct Cyber_fb_par *par); - int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue, - u_int *transp); - int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue, - u_int transp); - void (*blank)(int blank); -} *fbhw; - - - /* - * Frame Buffer Name - */ - -static char Cyber_fb_name[16] = "Cybervision"; - - - /* - * Cybervision Graphics Board - */ - -#define CYBER8_WIDTH 1152 -#define CYBER8_HEIGHT 886 -#define CYBER8_PIXCLOCK 12500 /* ++Geert: Just a guess */ - -#define CYBER16_WIDTH 800 -#define CYBER16_HEIGHT 600 -#define CYBER16_PIXCLOCK 25000 /* ++Geert: Just a guess */ - - -static int CyberKey = 0; -static u_char Cyber_colour_table [256][4]; -static unsigned long CyberMem; -static unsigned long CyberSize; -static volatile char *CyberRegs; - -static long *memstart; - - - /* - * Predefined Video Mode Names - */ - -static char *Cyber_fb_modenames[] = { - - /* - * Autodetect (Default) Video Mode - */ - - "default", - - /* - * Predefined Video Modes - */ - - "cyber8", /* Cybervision 8 bpp */ - "cyber16", /* Cybervision 16 bpp */ - - /* - * Dummy Video Modes - */ - - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", "dummy", "dummy", "dummy", - - /* - * User Defined Video Modes - * - * This doesn't work yet!! - */ - - "user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7" -}; - - - /* - * Predefined Video Mode Definitions - */ - -static struct fb_var_screeninfo Cyber_fb_predefined[] = { - - /* - * Autodetect (Default) Video Mode - */ - - { 0, }, - - /* - * Predefined Video Modes - */ - - { - /* Cybervision 8 bpp */ - CYBER8_WIDTH, CYBER8_HEIGHT, CYBER8_WIDTH, CYBER8_HEIGHT, 0, 0, 8, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2, - FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, { - /* Cybervision 16 bpp */ - CYBER16_WIDTH, CYBER16_HEIGHT, CYBER16_WIDTH, CYBER16_HEIGHT, 0, 0, 16, 0, - {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_NONE, CYBER16_PIXCLOCK, 64, 96, 35, 12, 112, 2, - FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - - /* - * Dummy Video Modes - */ - - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, - { 0, }, { 0, }, - - /* - * User Defined Video Modes - */ - - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, } -}; - - -#define NUM_TOTAL_MODES arraysize(Cyber_fb_predefined) -#define NUM_PREDEF_MODES (3) - - -static int Cyberfb_inverse = 0; -static int Cyberfb_Cyber8 = 0; /* Use Cybervision board */ -static int Cyberfb_Cyber16 = 0; /* Use Cybervision board */ -static int Cyberfb_mode = 0; - - - /* - * Some default modes - */ - -#define CYBER8_DEFMODE (1) -#define CYBER16_DEFMODE (2) - - - /* - * Interface used by the world - */ - -int Cyber_probe(void); -void Cyber_video_setup(char *options, int *ints); - -static int Cyber_fb_get_fix(struct fb_fix_screeninfo *fix, int con); -static int Cyber_fb_get_var(struct fb_var_screeninfo *var, int con); -static int Cyber_fb_set_var(struct fb_var_screeninfo *var, int con); -static int Cyber_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con); -static int Cyber_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con); -static int Cyber_fb_pan_display(struct fb_var_screeninfo *var, int con); -static int Cyber_fb_ioctl(struct inode *inode, struct file *file, u_int cmd, - u_long arg, int con); - - - /* - * Interface to the low level console driver - */ - -struct fb_info *Cyber_fb_init(long *mem_start); /* Through amiga_fb_init() */ -static int Cyberfb_switch(int con); -static int Cyberfb_updatevar(int con); -static void Cyberfb_blank(int blank); -static int Cyberfb_setcmap(struct fb_cmap *cmap, int con); - - - /* - * Accelerated Functions used by the low level console driver - */ - -void Cyber_WaitQueue(u_short fifo); -void Cyber_WaitBlit(void); -void Cyber_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty, - u_short width, u_short height, u_short mode); -void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height, - u_short mode, u_short color); -void Cyber_MoveCursor(u_short x, u_short y); - - - /* - * Hardware Specific Routines - */ - -static int Cyber_init(void); -static int Cyber_encode_fix(struct fb_fix_screeninfo *fix, - struct Cyber_fb_par *par); -static int Cyber_decode_var(struct fb_var_screeninfo *var, - struct Cyber_fb_par *par); -static int Cyber_encode_var(struct fb_var_screeninfo *var, - struct Cyber_fb_par *par); -static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, - u_int *transp); -static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp); -static void Cyber_blank(int blank); - - - /* - * Internal routines - */ - -static void Cyber_fb_get_par(struct Cyber_fb_par *par); -static void Cyber_fb_set_par(struct Cyber_fb_par *par); -static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive); -static struct fb_cmap *get_default_colormap(int bpp); -static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc); -static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc); -static void do_install_cmap(int con); -static void memcpy_fs(int fsfromto, void *to, void *from, int len); -static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto); -static int alloc_cmap(struct fb_cmap *cmap, int len, int transp); -static void Cyber_fb_set_disp(int con); -static int get_video_mode(const char *name); - - -/* -------------------- Hardware specific routines -------------------------- */ - - - /* - * Initialization - * - * Set the default video mode for this chipset. If a video mode was - * specified on the command line, it will override the default mode. - */ - -static int Cyber_init(void) -{ -int i; -char size; -volatile u_long *CursorBase; -unsigned long board_addr; -struct ConfigDev *cd; - -if (Cyberfb_mode == -1) - { - if (Cyberfb_Cyber8) - Cyberfb_mode = CYBER8_DEFMODE; - else - Cyberfb_mode = CYBER16_DEFMODE; - } - -cd = zorro_get_board (CyberKey); -zorro_config_board (CyberKey, 0); -board_addr = (unsigned long)cd->cd_BoardAddr; - -for (i = 0; i < 256; i++) - -for (i = 0; i < 256; i++) - { - Cyber_colour_table [i][0] = i; - Cyber_colour_table [i][1] = i; - Cyber_colour_table [i][2] = i; - Cyber_colour_table [i][3] = 0; - } - -*memstart = (*memstart + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); -/* This includes the video memory as well as the S3 register set */ -CyberMem = kernel_map (board_addr + 0x01400000, 0x01000000, - KERNELMAP_NOCACHE_SER, memstart); - -if (Cyberfb_Cyber8) - memset ((char*)CyberMem, 0, CYBER8_WIDTH * CYBER8_HEIGHT); -else - memset ((char*)CyberMem, 0, CYBER16_WIDTH * CYBER16_HEIGHT); - -CyberRegs = (char*) (CyberMem + 0x00c00000); - -/* Disable hardware cursor */ -*(CyberRegs + S3_CRTC_ADR) = S3_REG_LOCK2; -*(CyberRegs + S3_CRTC_DATA) = 0xa0; -*(CyberRegs + S3_CRTC_ADR) = S3_HGC_MODE; -*(CyberRegs + S3_CRTC_DATA) = 0x00; -*(CyberRegs + S3_CRTC_ADR) = S3_HWGC_DX; -*(CyberRegs + S3_CRTC_DATA) = 0x00; -*(CyberRegs + S3_CRTC_ADR) = S3_HWGC_DY; -*(CyberRegs + S3_CRTC_DATA) = 0x00; - -/* Set clipping rectangle to current screen size */ -*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x1000; -*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x2000; -if (Cyberfb_Cyber8) - { - *((u_short volatile *)(CyberRegs + 0xbee8)) = 0x3000 | (CYBER8_HEIGHT - 1); - *((u_short volatile *)(CyberRegs + 0xbee8)) = 0x4000 | (CYBER8_WIDTH - 1); - } -else - { - *((u_short volatile *)(CyberRegs + 0xbee8)) = 0x3000 | (CYBER16_HEIGHT - 1); - *((u_short volatile *)(CyberRegs + 0xbee8)) = 0x4000 | (CYBER16_WIDTH - 1); - } - -/* Get memory size (if not 2MB it is 4MB) */ -*(CyberRegs + S3_CRTC_ADR) = S3_LAW_CTL; -size = *(CyberRegs + S3_CRTC_DATA); -if ((size & 0x03) == 0x02) - CyberSize = 0x00200000; /* 2 MB */ -else - CyberSize = 0x00400000; /* 4 MB */ - -/* Initialize hardware cursor */ -CursorBase = (u_long *)((char *)(CyberMem) + CyberSize - 0x400); -for (i=0; i < 8; i++) - { - *(CursorBase +(i*4)) = 0xffffff00; - *(CursorBase+1+(i*4)) = 0xffff0000; - *(CursorBase+2+(i*4)) = 0xffff0000; - *(CursorBase+3+(i*4)) = 0xffff0000; - } -for (i=8; i < 64; i++) - { - *(CursorBase +(i*4)) = 0xffff0000; - *(CursorBase+1+(i*4)) = 0xffff0000; - *(CursorBase+2+(i*4)) = 0xffff0000; - *(CursorBase+3+(i*4)) = 0xffff0000; - } - -Cyber_setcolreg (255, 56, 100, 160, 0); -Cyber_setcolreg (254, 0, 0, 0, 0); - -return (0); -} - - - /* - * This function should fill in the `fix' structure based on the - * values in the `par' structure. - */ - -static int Cyber_encode_fix(struct fb_fix_screeninfo *fix, - struct Cyber_fb_par *par) -{ - int i; - - strcpy(fix->id, Cyber_fb_name); - fix->smem_start = CyberMem; -#if 0 - fix->smem_len = CyberSize; -#else - fix->smem_len = 0x01000000; -#endif - - fix->type = FB_TYPE_PACKED_PIXELS; - fix->type_aux = 0; - if (par->bpp == 8) - fix->visual = FB_VISUAL_PSEUDOCOLOR; - else - fix->visual = FB_VISUAL_DIRECTCOLOR; - - fix->xpanstep = 0; - fix->ypanstep = 0; - fix->ywrapstep = 0; - fix->line_length = 0; - - for (i = 0; i < arraysize(fix->reserved); i++) - fix->reserved[i] = 0; - - return(0); -} - - - /* - * Get the video params out of `var'. If a value doesn't fit, round - * it up, if it's too big, return -EINVAL. - */ - -static int Cyber_decode_var(struct fb_var_screeninfo *var, - struct Cyber_fb_par *par) -{ - if (Cyberfb_Cyber8) { - par->xres = CYBER8_WIDTH; - par->yres = CYBER8_HEIGHT; - par->bpp = 8; - } else { - par->xres = CYBER16_WIDTH; - par->yres = CYBER16_HEIGHT; - par->bpp = 16; - } - return(0); -} - - - /* - * Fill the `var' structure based on the values in `par' and maybe - * other values read out of the hardware. - */ - -static int Cyber_encode_var(struct fb_var_screeninfo *var, - struct Cyber_fb_par *par) -{ - int i; - - var->xres = par->xres; - var->yres = par->yres; - var->xres_virtual = par->xres; - var->yres_virtual = par->yres; - var->xoffset = 0; - var->yoffset = 0; - - var->bits_per_pixel = par->bpp; - var->grayscale = 0; - - if (par->bpp == 8) { - var->red.offset = 0; - var->red.length = 8; - var->red.msb_right = 0; - var->blue = var->green = var->red; - } else { - var->red.offset = 11; - var->red.length = 5; - var->red.msb_right = 0; - var->green.offset = 5; - var->green.length = 6; - var->green.msb_right = 0; - var->blue.offset = 0; - var->blue.length = 5; - var->blue.msb_right = 0; - } - var->transp.offset = 0; - var->transp.length = 0; - var->transp.msb_right = 0; - - var->nonstd = 0; - var->activate = 0; - - var->height = -1; - var->width = -1; - var->accel = FB_ACCEL_CYBERVISION; - var->vmode = FB_VMODE_NONINTERLACED; - - /* Dummy values */ - - if (par->bpp == 8) - var->pixclock = CYBER8_PIXCLOCK; - else - var->pixclock = CYBER16_PIXCLOCK; - var->sync = 0; - var->left_margin = 64; - var->right_margin = 96; - var->upper_margin = 35; - var->lower_margin = 12; - var->hsync_len = 112; - var->vsync_len = 2; - - for (i = 0; i < arraysize(var->reserved); i++) - var->reserved[i] = 0; - - return(0); -} - - - /* - * Set a single color register. The values supplied are already - * rounded down to the hardware's capabilities (according to the - * entries in the var structure). Return != 0 for invalid regno. - */ - -static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp) -{ -if (regno > 255) - return (1); - -*(CyberRegs + 0x3c8) = (char)regno; -Cyber_colour_table [regno][0] = red & 0xff; -Cyber_colour_table [regno][1] = green & 0xff; -Cyber_colour_table [regno][2] = blue & 0xff; -Cyber_colour_table [regno][3] = transp; - -*(CyberRegs + 0x3c9) = (red & 0xff) >> 2; -*(CyberRegs + 0x3c9) = (green & 0xff) >> 2; -*(CyberRegs + 0x3c9) = (blue & 0xff) >> 2; - -return (0); -} - - - /* - * Read a single color register and split it into - * colors/transparent. Return != 0 for invalid regno. - */ - -static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, - u_int *transp) -{ -if (regno >= 256) - return (1); -*red = Cyber_colour_table [regno][0]; -*green = Cyber_colour_table [regno][1]; -*blue = Cyber_colour_table [regno][2]; -*transp = Cyber_colour_table [regno][3]; -return (0); -} - - - /* - * (Un)Blank the screen - */ - -void Cyber_blank(int blank) -{ -int i; - -if (blank) - for (i = 0; i < 256; i++) - { - *(CyberRegs + 0x3c8) = i; - *(CyberRegs + 0x3c9) = 0; - *(CyberRegs + 0x3c9) = 0; - *(CyberRegs + 0x3c9) = 0; - } -else - for (i = 0; i < 256; i++) - { - *(CyberRegs + 0x3c8) = i; - *(CyberRegs + 0x3c9) = Cyber_colour_table [i][0] >> 2; - *(CyberRegs + 0x3c9) = Cyber_colour_table [i][1] >> 2; - *(CyberRegs + 0x3c9) = Cyber_colour_table [i][2] >> 2; - } -} - - -/************************************************************** - * We are waiting for "fifo" FIFO-slots empty - */ -void Cyber_WaitQueue (u_short fifo) -{ -u_short status; - -do - { - status = *((u_short volatile *)(CyberRegs + S3_GP_STAT)); - } -while (status & fifo); -} - -/************************************************************** - * We are waiting for Hardware (Graphics Engine) not busy - */ -void Cyber_WaitBlit (void) -{ -u_short status; - -do - { - status = *((u_short volatile *)(CyberRegs + S3_GP_STAT)); - } -while (status & S3_HDW_BUSY); -} - -/************************************************************** - * BitBLT - Through the Plane - */ -void Cyber_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty, - u_short width, u_short height, u_short mode) -{ -u_short blitcmd = S3_BITBLT; - -/* Set drawing direction */ -/* -Y, X maj, -X (default) */ -if (curx > destx) - blitcmd |= 0x0020; /* Drawing direction +X */ -else - { - curx += (width - 1); - destx += (width - 1); - } - -if (cury > desty) - blitcmd |= 0x0080; /* Drawing direction +Y */ -else - { - cury += (height - 1); - desty += (height - 1); - } - -Cyber_WaitQueue (0x8000); - -*((u_short volatile *)(CyberRegs + S3_PIXEL_CNTL)) = 0xa000; -*((u_short volatile *)(CyberRegs + S3_FRGD_MIX)) = (0x0060 | mode); - -*((u_short volatile *)(CyberRegs + S3_CUR_X)) = curx; -*((u_short volatile *)(CyberRegs + S3_CUR_Y)) = cury; - -*((u_short volatile *)(CyberRegs + S3_DESTX_DIASTP)) = destx; -*((u_short volatile *)(CyberRegs + S3_DESTY_AXSTP)) = desty; - -*((u_short volatile *)(CyberRegs + S3_MIN_AXIS_PCNT)) = height - 1; -*((u_short volatile *)(CyberRegs + S3_MAJ_AXIS_PCNT)) = width - 1; - -*((u_short volatile *)(CyberRegs + S3_CMD)) = blitcmd; -} - -/************************************************************** - * Rectangle Fill Solid - */ -void Cyber_RectFill (u_short x, u_short y, u_short width, u_short height, - u_short mode, u_short fcolor) -{ -u_short blitcmd = S3_FILLEDRECT; - -Cyber_WaitQueue (0x8000); - -*((u_short volatile *)(CyberRegs + S3_PIXEL_CNTL)) = 0xa000; -*((u_short volatile *)(CyberRegs + S3_FRGD_MIX)) = (0x0020 | mode); - -*((u_short volatile *)(CyberRegs + S3_MULT_MISC)) = 0xe000; -*((u_short volatile *)(CyberRegs + S3_FRGD_COLOR)) = color; - -*((u_short volatile *)(CyberRegs + S3_CUR_X)) = x; -*((u_short volatile *)(CyberRegs + S3_CUR_Y)) = y; - -*((u_short volatile *)(CyberRegs + S3_MIN_AXIS_PCNT)) = height - 1; -*((u_short volatile *)(CyberRegs + S3_MAJ_AXIS_PCNT)) = width - 1; - -*((u_short volatile *)(CyberRegs + S3_CMD)) = blitcmd; -} - - -/************************************************************** - * Move cursor to x, y - */ -void Cyber_MoveCursor (u_short x, u_short y) -{ -*(CyberRegs + S3_CRTC_ADR) = 0x39; -*(CyberRegs + S3_CRTC_DATA) = 0xa0; - -*(CyberRegs + S3_CRTC_ADR) = S3_HWGC_ORGX_H; -*(CyberRegs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8); -*(CyberRegs + S3_CRTC_ADR) = S3_HWGC_ORGX_L; -*(CyberRegs + S3_CRTC_DATA) = (char)(x & 0x00ff); - -*(CyberRegs + S3_CRTC_ADR) = S3_HWGC_ORGY_H; -*(CyberRegs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8); -*(CyberRegs + S3_CRTC_ADR) = S3_HWGC_ORGY_L; -*(CyberRegs + S3_CRTC_DATA) = (char)(y & 0x00ff); -} - - -/* -------------------- Interfaces to hardware functions -------------------- */ - - -static struct fb_hwswitch Cyber_switch = { - Cyber_init, Cyber_encode_fix, Cyber_decode_var, Cyber_encode_var, - Cyber_getcolreg, Cyber_setcolreg, Cyber_blank -}; - - -/* -------------------- Generic routines ------------------------------------ */ - - - /* - * Fill the hardware's `par' structure. - */ - -static void Cyber_fb_get_par(struct Cyber_fb_par *par) -{ - if (current_par_valid) - *par = current_par; - else - fbhw->decode_var(&Cyber_fb_predefined[Cyberfb_mode], par); -} - - -static void Cyber_fb_set_par(struct Cyber_fb_par *par) -{ - current_par = *par; - current_par_valid = 1; -} - - -static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) -{ - int err, activate; - struct Cyber_fb_par par; - - if ((err = fbhw->decode_var(var, &par))) - return(err); - activate = var->activate; - if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) - Cyber_fb_set_par(&par); - fbhw->encode_var(var, &par); - var->activate = activate; - return(0); -} - - - /* - * Default Colormaps - */ - -static u_short red16[] = - { 0xc000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0x0000, - 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff}; -static u_short green16[] = - { 0xc000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, - 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff}; -static u_short blue16[] = - { 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x0000, - 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff}; - - -static struct fb_cmap default_16_colors = - { 0, 16, red16, green16, blue16, NULL }; - - -static struct fb_cmap *get_default_colormap(int bpp) -{ - return(&default_16_colors); -} - - -#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16) -#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \ - ((1<<(width))-1)) : 0)) - -static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc) -{ - int i, start; - u_short *red, *green, *blue, *transp; - u_int hred, hgreen, hblue, htransp; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - start = cmap->start; - if (start < 0) - return(-EINVAL); - for (i = 0; i < cmap->len; i++) { - if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp)) - return(0); - hred = CNVT_FROMHW(hred, var->red.length); - hgreen = CNVT_FROMHW(hgreen, var->green.length); - hblue = CNVT_FROMHW(hblue, var->blue.length); - htransp = CNVT_FROMHW(htransp, var->transp.length); - if (kspc) { - *red = hred; - *green = hgreen; - *blue = hblue; - if (transp) - *transp = htransp; - } else { - put_user(hred, red); - put_user(hgreen, green); - put_user(hblue, blue); - if (transp) - put_user(htransp, transp); - } - red++; - green++; - blue++; - if (transp) - transp++; - } - return(0); -} - - -static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc) -{ - int i, start; - u_short *red, *green, *blue, *transp; - u_int hred, hgreen, hblue, htransp; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - start = cmap->start; - - if (start < 0) - return(-EINVAL); - for (i = 0; i < cmap->len; i++) { - if (kspc) { - hred = *red; - hgreen = *green; - hblue = *blue; - htransp = transp ? *transp : 0; - } else { - get_user(hred, red); - get_user(hgreen, green); - get_user(hblue, blue); - if (transp) - get_user(htransp, transp); - else - htransp = 0; - } - hred = CNVT_TOHW(hred, var->red.length); - hgreen = CNVT_TOHW(hgreen, var->green.length); - hblue = CNVT_TOHW(hblue, var->blue.length); - htransp = CNVT_TOHW(htransp, var->transp.length); - red++; - green++; - blue++; - if (transp) - transp++; - if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp)) - return(0); - } - return(0); -} - - -static void do_install_cmap(int con) -{ - if (con != currcon) - return; - if (disp[con].cmap.len) - do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1); - else - do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel), - &disp[con].var, 1); -} - - -static void memcpy_fs(int fsfromto, void *to, void *from, int len) -{ - switch (fsfromto) { - case 0: - memcpy(to, from, len); - return; - case 1: - copy_from_user(to, from, len); - return; - case 2: - copy_to_user(to, from, len); - return; - } -} - - -static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto) -{ - int size; - int tooff = 0, fromoff = 0; - - if (to->start > from->start) - fromoff = to->start-from->start; - else - tooff = from->start-to->start; - size = to->len-tooff; - if (size > from->len-fromoff) - size = from->len-fromoff; - if (size < 0) - return; - size *= sizeof(u_short); - memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size); - memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size); - memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size); - if (from->transp && to->transp) - memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size); -} - - -static int alloc_cmap(struct fb_cmap *cmap, int len, int transp) -{ - int size = len*sizeof(u_short); - - if (cmap->len != len) { - if (cmap->red) - kfree(cmap->red); - if (cmap->green) - kfree(cmap->green); - if (cmap->blue) - kfree(cmap->blue); - if (cmap->transp) - kfree(cmap->transp); - cmap->red = cmap->green = cmap->blue = cmap->transp = NULL; - cmap->len = 0; - if (!len) - return(0); - if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) - return(-1); - if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) - return(-1); - if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) - return(-1); - if (transp) { - if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) - return(-1); - } else - cmap->transp = NULL; - } - cmap->start = 0; - cmap->len = len; - copy_cmap(get_default_colormap(len), cmap, 0); - return(0); -} - - - /* - * Get the Fixed Part of the Display - */ - -static int Cyber_fb_get_fix(struct fb_fix_screeninfo *fix, int con) -{ - struct Cyber_fb_par par; - int error = 0; - - if (con == -1) - Cyber_fb_get_par(&par); - else - error = fbhw->decode_var(&disp[con].var, &par); - return(error ? error : fbhw->encode_fix(fix, &par)); -} - - - /* - * Get the User Defined Part of the Display - */ - -static int Cyber_fb_get_var(struct fb_var_screeninfo *var, int con) -{ - struct Cyber_fb_par par; - int error = 0; - - if (con == -1) { - Cyber_fb_get_par(&par); - error = fbhw->encode_var(var, &par); - } else - *var = disp[con].var; - return(error); -} - - -static void Cyber_fb_set_disp(int con) -{ - struct fb_fix_screeninfo fix; - - Cyber_fb_get_fix(&fix, con); - if (con == -1) - con = 0; - disp[con].screen_base = (u_char *)fix.smem_start; - disp[con].visual = fix.visual; - disp[con].type = fix.type; - disp[con].type_aux = fix.type_aux; - disp[con].ypanstep = fix.ypanstep; - disp[con].ywrapstep = fix.ywrapstep; - disp[con].can_soft_blank = 1; - disp[con].inverse = Cyberfb_inverse; -} - - - /* - * Set the User Defined Part of the Display - */ - -static int Cyber_fb_set_var(struct fb_var_screeninfo *var, int con) -{ - int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp; - - if ((err = do_fb_set_var(var, con == currcon))) - return(err); - if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { - oldxres = disp[con].var.xres; - oldyres = disp[con].var.yres; - oldvxres = disp[con].var.xres_virtual; - oldvyres = disp[con].var.yres_virtual; - oldbpp = disp[con].var.bits_per_pixel; - disp[con].var = *var; - if (oldxres != var->xres || oldyres != var->yres || - oldvxres != var->xres_virtual || oldvyres != var->yres_virtual || - oldbpp != var->bits_per_pixel) { - Cyber_fb_set_disp(con); - (*fb_info.changevar)(con); - alloc_cmap(&disp[con].cmap, 0, 0); - do_install_cmap(con); - } - } - var->activate = 0; - return(0); -} - - - /* - * Get the Colormap - */ - -static int Cyber_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) -{ - if (con == currcon) /* current console? */ - return(do_fb_get_cmap(cmap, &disp[con].var, kspc)); - else if (disp[con].cmap.len) /* non default colormap? */ - copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2); - else - copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), cmap, - kspc ? 0 : 2); - return(0); -} - - - /* - * Set the Colormap - */ - -static int Cyber_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) -{ - int err; - - if (!disp[con].cmap.len) { /* no colormap allocated? */ - if ((err = alloc_cmap(&disp[con].cmap, 1<<disp[con].var.bits_per_pixel, - 0))) - return(err); - } - if (con == currcon) /* current console? */ - return(do_fb_set_cmap(cmap, &disp[con].var, kspc)); - else - copy_cmap(cmap, &disp[con].cmap, kspc ? 0 : 1); - return(0); -} - - - /* - * Pan or Wrap the Display - * - * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag - */ - -static int Cyber_fb_pan_display(struct fb_var_screeninfo *var, int con) -{ - return(-EINVAL); -} - - - /* - * Cybervision Frame Buffer Specific ioctls - */ - -static int Cyber_fb_ioctl(struct inode *inode, struct file *file, - u_int cmd, u_long arg, int con) -{ - return(-EINVAL); -} - - -static struct fb_ops Cyber_fb_ops = { - Cyber_fb_get_fix, Cyber_fb_get_var, Cyber_fb_set_var, Cyber_fb_get_cmap, - Cyber_fb_set_cmap, Cyber_fb_pan_display, Cyber_fb_ioctl -}; - - -int Cyber_probe(void) -{ - CyberKey = zorro_find(MANUF_PHASE5, PROD_CYBERVISION, 0, 0); - return(CyberKey); -} - - -void Cyber_video_setup(char *options, int *ints) -{ - char *this_opt; - int i; - - fb_info.fontname[0] = '\0'; - - if (!options || !*options) - return; - - for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) - if (!strcmp(this_opt, "inverse")) { - Cyberfb_inverse = 1; - for (i = 0; i < 16; i++) { - red16[i] = ~red16[i]; - green16[i] = ~green16[i]; - blue16[i] = ~blue16[i]; - } - } else if (!strncmp(this_opt, "font:", 5)) - strcpy(fb_info.fontname, this_opt+5); - else if (!strcmp (this_opt, "cyber8")) - Cyberfb_Cyber8 = 1; - else if (!strcmp (this_opt, "cyber16")) - Cyberfb_Cyber16 = 1; - else - Cyberfb_mode = get_video_mode(this_opt); -} - - - /* - * Initialization - */ - -__initfunc(struct fb_info *Cyber_fb_init(long *mem_start)) -{ - int err; - struct Cyber_fb_par par; - - memstart = mem_start; - - fbhw = &Cyber_switch; - - err = register_framebuffer(Cyber_fb_name, &node, &Cyber_fb_ops, - NUM_TOTAL_MODES, Cyber_fb_predefined); - if (err < 0) - panic("Cannot register frame buffer\n"); - - fbhw->init(); - fbhw->decode_var(&Cyber_fb_predefined[Cyberfb_mode], &par); - fbhw->encode_var(&Cyber_fb_predefined[0], &par); - - strcpy(fb_info.modename, Cyber_fb_name); - fb_info.disp = disp; - fb_info.switch_con = &Cyberfb_switch; - fb_info.updatevar = &Cyberfb_updatevar; - fb_info.blank = &Cyberfb_blank; - fb_info.setcmap = &Cyberfb_setcmap; - - do_fb_set_var(&Cyber_fb_predefined[0], 1); - Cyber_fb_get_var(&disp[0].var, -1); - Cyber_fb_set_disp(-1); - do_install_cmap(0); - return(&fb_info); -} - - -static int Cyberfb_switch(int con) -{ - /* Do we have to save the colormap? */ - if (disp[currcon].cmap.len) - do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1); - - do_fb_set_var(&disp[con].var, 1); - currcon = con; - /* Install new colormap */ - do_install_cmap(con); - return(0); -} - - - /* - * Update the `var' structure (called by fbcon.c) - * - * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. - * Since it's called by a kernel driver, no range checking is done. - */ - -static int Cyberfb_updatevar(int con) -{ - return(0); -} - - - /* - * Blank the display. - */ - -static void Cyberfb_blank(int blank) -{ - fbhw->blank(blank); -} - - - /* - * Set the colormap - */ - -static int Cyberfb_setcmap(struct fb_cmap *cmap, int con) -{ - return(Cyber_fb_set_cmap(cmap, 1, con)); -} - - - /* - * Get a Video Mode - */ - -static int get_video_mode(const char *name) -{ - int i; - - for (i = 1; i < NUM_PREDEF_MODES; i++) - if (!strcmp(name, Cyber_fb_modenames[i])) - return(i); - return(0); -} diff --git a/arch/m68k/amiga/retz3fb.c b/arch/m68k/amiga/retz3fb.c deleted file mode 100644 index 49a0853bc..000000000 --- a/arch/m68k/amiga/retz3fb.c +++ /dev/null @@ -1,1754 +0,0 @@ -/* - * Linux/arch/m68k/amiga/retz3fb.c -- Low level implementation of the - * RetinaZ3 frame buffer device - * - * Copyright (C) 1997 Jes Sorensen - * - * This file is based on the CyberVision64 frame buffer device and - * the generic Cirrus Logic driver. - * - * cyberfb.c: Copyright (C) 1996 Martin Apel, - * Geert Uytterhoeven - * clgen.c: Copyright (C) 1996 Frank Neumann - * - * History: - * - 22 Jan 97: Initial work - * - 14 Feb 97: Screen initialization works somewhat, still only - * 8-bit packed pixel is supported. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/malloc.h> -#include <linux/delay.h> -#include <linux/fb.h> -#include <linux/zorro.h> -#include <linux/init.h> - -#include <asm/uaccess.h> -#include <asm/system.h> -#include <asm/irq.h> -#include <asm/pgtable.h> - -#include "retz3fb.h" - -/* #define DEBUG if(1) */ -#define DEBUG if(0) - -/* - * Reserve space for one pattern line. - * - * For the time being we only support 4MB boards! - */ - -#define PAT_MEM_SIZE 16*3 -#define PAT_MEM_OFF (4*1024*1024 - PAT_MEM_SIZE) - -#define arraysize(x) (sizeof(x)/sizeof(*(x))) - -struct retz3_fb_par { - int xres; - int yres; - int xres_vir; - int yres_vir; - int xoffset; - int yoffset; - int bpp; - - struct fb_bitfield red; - struct fb_bitfield green; - struct fb_bitfield blue; - struct fb_bitfield transp; - - int pixclock; - int left_margin; /* time from sync to picture */ - int right_margin; /* time from picture to sync */ - int upper_margin; /* time from sync to picture */ - int lower_margin; - int hsync_len; /* length of horizontal sync */ - int vsync_len; /* length of vertical sync */ - int vmode; -}; - -struct display_data { - long h_total; /* Horizontal Total */ - long h_sstart; /* Horizontal Sync Start */ - long h_sstop; /* Horizontal Sync Stop */ - long h_bstart; /* Horizontal Blank Start */ - long h_bstop; /* Horizontal Blank Stop */ - long h_dispend; /* Horizontal Display End */ - long v_total; /* Vertical Total */ - long v_sstart; /* Vertical Sync Start */ - long v_sstop; /* Vertical Sync Stop */ - long v_bstart; /* Vertical Blank Start */ - long v_bstop; /* Vertical Blank Stop */ - long v_dispend; /* Horizontal Display End */ -}; - -static struct retz3_fb_par current_par; - -static int current_par_valid = 0; -static int currcon = 0; - -static struct display disp[MAX_NR_CONSOLES]; -static struct fb_info fb_info; - -static int node; /* node of the /dev/fb?current file */ - - -/* - * Switch for Chipset Independency - */ - -static struct fb_hwswitch { - - /* Initialisation */ - - int (*init)(void); - - /* Display Control */ - - int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3_fb_par *par); - int (*decode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); - int (*encode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); - int (*getcolreg)(unsigned int regno, unsigned int *red, unsigned - int *green, unsigned int *blue, unsigned int *transp); - int (*setcolreg)(unsigned int regno, unsigned int red, unsigned int - green, unsigned int blue, unsigned int transp); - void (*blank)(int blank); -} *fbhw; - - -/* - * Frame Buffer Name - */ - -static char retz3_fb_name[16] = "RetinaZ3"; - - -static int z3_key = 0; -static unsigned char retz3_color_table [256][4]; -static unsigned long z3_mem; -static unsigned long z3_fbmem; -static unsigned long z3_size; -static volatile unsigned char *z3_regs; - -static long *memstart; - - -/* - * Predefined Video Mode Names - */ - -static char *retz3_fb_modenames[] = { - - /* - * Autodetect (Default) Video Mode - */ - - "default", - - /* - * Predefined Video Modes - */ - - "640x480", /* RetinaZ3 8 bpp */ - "800x600", /* RetinaZ3 8 bpp */ - "1024x768i", - "640x480-16", /* RetinaZ3 16 bpp */ - "640x480-24", /* RetinaZ3 24 bpp */ - - /* - * Dummy Video Modes - */ - - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - - /* - * User Defined Video Modes - * - * This doesn't work yet!! - */ - - "user0", "user1", "user2", "user3", - "user4", "user5", "user6", "user7" -}; - -/* - * A small info on how to convert XFree86 timing values into fb - * timings - by Frank Neumann: - * -An XFree86 mode line consists of the following fields: - "800x600" 50 800 856 976 1040 600 637 643 666 - < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL - -The fields in the fb_var_screeninfo structure are: - unsigned long pixclock; * pixel clock in ps (pico seconds) * - unsigned long left_margin; * time from sync to picture * - unsigned long right_margin; * time from picture to sync * - unsigned long upper_margin; * time from sync to picture * - unsigned long lower_margin; - unsigned long hsync_len; * length of horizontal sync * - unsigned long vsync_len; * length of vertical sync * - -1) Pixelclock: - xfree: in MHz - fb: In Picoseconds (ps) - - pixclock = 1000000 / DCF - -2) horizontal timings: - left_margin = HFL - SH2 - right_margin = SH1 - HR - hsync_len = SH2 - SH1 - -3) vertical timings: - upper_margin = VFL - SV2 - lower_margin = SV1 - VR - vsync_len = SV2 - SV1 - -Good examples for VESA timings can be found in the XFree86 source tree, -under "programs/Xserver/hw/xfree86/doc/modeDB.txt". -*/ - -/* - * Predefined Video Mode Definitions - */ - -static struct fb_var_screeninfo retz3_fb_predefined[] = { - - /* - * Autodetect (Default) Video Mode - */ - - { 0, }, - - /* - * Predefined Video Modes - */ - - /* - * NB: it is very important to adjust the pixel-clock to the color-depth. - */ - - { - 640, 480, 640, 480, 0, 0, 8, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461, 28, 32, 12, 10, 96, 2, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - /* - ModeLine "800x600" 36 800 824 896 1024 600 601 603 625 - < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL - */ - { - /* 800 x 600, 8 bpp */ - 800, 600, 800, 600, 0, 0, 8, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 27778, 64, 24, 22, 1, 120, 2, - FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - /* - ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace - < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL - */ - { - /* 1024 x 768, 8 bpp, interlaced */ - 1024, 768, 1024, 768, 0, 0, 8, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 22222, 40, 40, 32, 9, 160, 8, - FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED - }, - { - 640, 480, 640, 480, 0, 0, 16, 0, - {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/2, 28, 32, 12, 10, 96, 2, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - 640, 480, 640, 480, 0, 0, 24, 0, - {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/3, 28, 32, 12, 10, 96, 2, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - - /* - * Dummy Video Modes - */ - - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, - { 0, }, { 0, }, - - /* - * User Defined Video Modes - */ - - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, } -}; - - -#define NUM_TOTAL_MODES arraysize(retz3_fb_predefined) -#define NUM_PREDEF_MODES (5) - - -static int z3fb_inverse = 0; -static int z3fb_mode = 0; - - -/* - * Interface used by the world - */ - -int retz3_probe(void); -void retz3_video_setup(char *options, int *ints); - -static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con); -static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con); -static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con); -static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con); -static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con); -static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con); -static int retz3_fb_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, int con); - - -/* - * Interface to the low level console driver - */ - -struct fb_info *retz3_fb_init(long *mem_start); /* Through amiga_fb_init() */ -static int z3fb_switch(int con); -static int z3fb_updatevar(int con); -static void z3fb_blank(int blank); -static int z3fb_setcmap(struct fb_cmap *cmap, int con); - - -/* - * Accelerated Functions used by the low level console driver - */ - -void retz3_bitblt(struct fb_var_screeninfo *scr, - unsigned short curx, unsigned short cury, unsigned - short destx, unsigned short desty, unsigned short - width, unsigned short height, unsigned short cmd, - unsigned short mask); -void retz3_fill(unsigned short x, unsigned short y, unsigned short - width, unsigned short height, unsigned short mode, - unsigned short color); - -/* - * Hardware Specific Routines - */ - -static int retz3_init(void); -static int retz3_encode_fix(struct fb_fix_screeninfo *fix, - struct retz3_fb_par *par); -static int retz3_decode_var(struct fb_var_screeninfo *var, - struct retz3_fb_par *par); -static int retz3_encode_var(struct fb_var_screeninfo *var, - struct retz3_fb_par *par); -static int retz3_getcolreg(unsigned int regno, unsigned int *red, - unsigned int *green, unsigned int *blue, - unsigned int *transp); -static int retz3_setcolreg(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - unsigned int transp); -static void retz3_blank(int blank); - - -/* - * Internal routines - */ - -static void retz3_fb_get_par(struct retz3_fb_par *par); -static void retz3_fb_set_par(struct retz3_fb_par *par); -static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive); -static struct fb_cmap *get_default_colormap(int bpp); -static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc); -static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc); -static void do_install_cmap(int con); -static void memcpy_fs(int fsfromto, void *to, void *from, int len); -static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto); -static int alloc_cmap(struct fb_cmap *cmap, int len, int transp); -static void retz3_fb_set_disp(int con); -static int get_video_mode(const char *name); - - -/* -------------------- Hardware specific routines -------------------------- */ - -static unsigned short find_fq(unsigned int freq) -{ - unsigned long f; - long tmp; - long prev = 0x7fffffff; - long n2, n1 = 3; - unsigned long m; - unsigned short res = 0; - - if (freq <= 31250000) - n2 = 3; - else if (freq <= 62500000) - n2 = 2; - else if (freq <= 125000000) - n2 = 1; - else if (freq <= 250000000) - n2 = 0; - else - return(0); - - - do { - f = freq >> (10 - n2); - - m = (f * n1) / (14318180/1024); - - if (m > 129) - break; - - tmp = (((m * 14318180) >> n2) / n1) - freq; - if (tmp < 0) - tmp = -tmp; - - if (tmp < prev) { - prev = tmp; - res = (((n2 << 5) | (n1-2)) << 8) | (m-2); - } - - } while ( (++n1) <= 21); - - return res; -} - - -static int retz3_set_video(struct fb_var_screeninfo *var, - struct retz3_fb_par *par) -{ - float freq_f; - long freq; - - int xres, hfront, hsync, hback; - int yres, vfront, vsync, vback; - unsigned char tmp; - unsigned short best_freq; - struct display_data data; - - short clocksel = 0; /* Apparantly this is always zero */ - - int bpp = var->bits_per_pixel; - - /* - * XXX - */ - if (bpp == 24) - return 0; - - if ((bpp != 8) && (bpp != 16) && (bpp != 24)) - return -EFAULT; - - par->xoffset = 0; - par->yoffset = 0; - - xres = var->xres * bpp / 4; - hfront = var->right_margin * bpp / 4; - hsync = var->hsync_len * bpp / 4; - hback = var->left_margin * bpp / 4; - - if (var->vmode & FB_VMODE_DOUBLE) - { - yres = var->yres * 2; - vfront = var->lower_margin * 2; - vsync = var->vsync_len * 2; - vback = var->upper_margin * 2; - } - else if (var->vmode & FB_VMODE_INTERLACED) - { - yres = (var->yres + 1) / 2; - vfront = (var->lower_margin + 1) / 2; - vsync = (var->vsync_len + 1) / 2; - vback = (var->upper_margin + 1) / 2; - } - else - { - yres = var->yres; /* -1 ? */ - vfront = var->lower_margin; - vsync = var->vsync_len; - vback = var->upper_margin; - } - - data.h_total = (hback / 8) + (xres / 8) - + (hfront / 8) + (hsync / 8) - 1 /* + 1 */; - data.h_dispend = ((xres + bpp - 1)/ 8) - 1; - data.h_bstart = xres / 8 /* + 1 */; - - data.h_bstop = data.h_total+1 + 2 + 1; - data.h_sstart = (xres / 8) + (hfront / 8) + 1; - data.h_sstop = (xres / 8) + (hfront / 8) + (hsync / 8) + 1; - - data.v_total = yres + vfront + vsync + vback - 1; - - data.v_dispend = yres - 1; - data.v_bstart = yres; - - data.v_bstop = data.v_total; - data.v_sstart = yres + vfront - 1 - 2; - data.v_sstop = yres + vfront + vsync - 1; - -#if 0 /* testing */ - - printk("HBS: %i\n", data.h_bstart); - printk("HSS: %i\n", data.h_sstart); - printk("HSE: %i\n", data.h_sstop); - printk("HBE: %i\n", data.h_bstop); - printk("HT: %i\n", data.h_total); - - printk("hsync: %i\n", hsync); - printk("hfront: %i\n", hfront); - printk("hback: %i\n", hback); - - printk("VBS: %i\n", data.v_bstart); - printk("VSS: %i\n", data.v_sstart); - printk("VSE: %i\n", data.v_sstop); - printk("VBE: %i\n", data.v_bstop); - printk("VT: %i\n", data.v_total); - - printk("vsync: %i\n", vsync); - printk("vfront: %i\n", vfront); - printk("vback: %i\n", vback); -#endif - - if (data.v_total >= 1024) - printk("MAYDAY: v_total >= 1024; bailing out!\n"); - - reg_w(GREG_MISC_OUTPUT_W, 0xe3 | ((clocksel & 3) * 0x04)); - reg_w(GREG_FEATURE_CONTROL_W, 0x00); - - seq_w(SEQ_RESET, 0x00); - seq_w(SEQ_RESET, 0x03); /* reset sequencer logic */ - - /* - * CLOCKING_MODE bits: - * 2: This one is only set for certain text-modes, wonder if - * it may be for EGA-lines? (it was referred to as CLKDIV2) - * (The CL drivers sets it to 0x21 with the comment: - * FullBandwidth (video off) and 8/9 dot clock) - */ - seq_w(SEQ_CLOCKING_MODE, 0x01 | 0x00 /* 0x08 */); - - seq_w(SEQ_MAP_MASK, 0x0f); /* enable writing to plane 0-3 */ - seq_w(SEQ_CHAR_MAP_SELECT, 0x00); /* doesn't matter in gfx-mode */ - seq_w(SEQ_MEMORY_MODE, 0x06); /* CL driver says 0x0e for 256 col mode*/ - seq_w(SEQ_RESET, 0x01); - seq_w(SEQ_RESET, 0x03); - - seq_w(SEQ_EXTENDED_ENABLE, 0x05); - - seq_w(SEQ_CURSOR_CONTROL, 0x00); /* disable cursor */ - seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); - seq_w(SEQ_PRIM_HOST_OFF_HI, 0x00); - seq_w(SEQ_LINEAR_0, 0x4a); - seq_w(SEQ_LINEAR_1, 0x00); - - seq_w(SEQ_SEC_HOST_OFF_HI, 0x00); - seq_w(SEQ_SEC_HOST_OFF_LO, 0x00); - seq_w(SEQ_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40); - - /* - * The lower 4 bits (0-3) are used to set the font-width for - * text-mode - DON'T try to set this for gfx-mode. - */ - seq_w(SEQ_EXT_CLOCK_MODE, 0x10); - seq_w(SEQ_EXT_VIDEO_ADDR, 0x03); - - /* - * Extended Pixel Control: - * bit 0: text-mode=0, gfx-mode=1 (Graphics Byte ?) - * bit 1: (Packed/Nibble Pixel Format ?) - * bit 4-5: depth, 0=1-8bpp, 1=9-16bpp, 2=17-24bpp - */ - seq_w(SEQ_EXT_PIXEL_CNTL, 0x01 | (((bpp / 8) - 1) << 4)); - - seq_w(SEQ_BUS_WIDTH_FEEDB, 0x04); - seq_w(SEQ_COLOR_EXP_WFG, 0x01); - seq_w(SEQ_COLOR_EXP_WBG, 0x00); - seq_w(SEQ_EXT_RW_CONTROL, 0x00); - seq_w(SEQ_MISC_FEATURE_SEL, (0x51 | (clocksel & 8))); - seq_w(SEQ_COLOR_KEY_CNTL, 0x40); - seq_w(SEQ_COLOR_KEY_MATCH0, 0x00); - seq_w(SEQ_COLOR_KEY_MATCH1, 0x00); - seq_w(SEQ_COLOR_KEY_MATCH2, 0x00); - seq_w(SEQ_CRC_CONTROL, 0x00); - seq_w(SEQ_PERF_SELECT, 0x10); - seq_w(SEQ_ACM_APERTURE_1, 0x00); - seq_w(SEQ_ACM_APERTURE_2, 0x30); - seq_w(SEQ_ACM_APERTURE_3, 0x00); - seq_w(SEQ_MEMORY_MAP_CNTL, 0x03); - - - /* unlock register CRT0..CRT7 */ - crt_w(CRT_END_VER_RETR, (data.v_sstop & 0x0f) | 0x20); - - /* Zuerst zu schreibende Werte nur per printk ausgeben */ - DEBUG printk("CRT_HOR_TOTAL: %ld\n", data.h_total); - crt_w(CRT_HOR_TOTAL, data.h_total & 0xff); - - DEBUG printk("CRT_HOR_DISP_ENA_END: %ld\n", data.h_dispend); - crt_w(CRT_HOR_DISP_ENA_END, (data.h_dispend) & 0xff); - - DEBUG printk("CRT_START_HOR_BLANK: %ld\n", data.h_bstart); - crt_w(CRT_START_HOR_BLANK, data.h_bstart & 0xff); - - DEBUG printk("CRT_END_HOR_BLANK: 128+%ld\n", data.h_bstop % 32); - crt_w(CRT_END_HOR_BLANK, 0x80 | (data.h_bstop & 0x1f)); - - DEBUG printk("CRT_START_HOR_RETR: %ld\n", data.h_sstart); - crt_w(CRT_START_HOR_RETR, data.h_sstart & 0xff); - - tmp = (data.h_sstop & 0x1f); - if (data.h_bstop & 0x20) - tmp |= 0x80; - DEBUG printk("CRT_END_HOR_RETR: %d\n", tmp); - crt_w(CRT_END_HOR_RETR, tmp); - - DEBUG printk("CRT_VER_TOTAL: %ld\n", data.v_total & 0xff); - crt_w(CRT_VER_TOTAL, (data.v_total & 0xff)); - - tmp = 0x10; /* LineCompare bit #9 */ - if (data.v_total & 256) - tmp |= 0x01; - if (data.v_dispend & 256) - tmp |= 0x02; - if (data.v_sstart & 256) - tmp |= 0x04; - if (data.v_bstart & 256) - tmp |= 0x08; - if (data.v_total & 512) - tmp |= 0x20; - if (data.v_dispend & 512) - tmp |= 0x40; - if (data.v_sstart & 512) - tmp |= 0x80; - DEBUG printk("CRT_OVERFLOW: %d\n", tmp); - crt_w(CRT_OVERFLOW, tmp); - - crt_w(CRT_PRESET_ROW_SCAN, 0x00); /* not CL !!! */ - - tmp = 0x40; /* LineCompare bit #8 */ - if (data.v_bstart & 512) - tmp |= 0x20; - if (var->vmode & FB_VMODE_DOUBLE) - tmp |= 0x80; - DEBUG printk("CRT_MAX_SCAN_LINE: %d\n", tmp); - crt_w(CRT_MAX_SCAN_LINE, tmp); - - crt_w(CRT_CURSOR_START, 0x00); - crt_w(CRT_CURSOR_END, 8 & 0x1f); /* font height */ - - crt_w(CRT_START_ADDR_HIGH, 0x00); - crt_w(CRT_START_ADDR_LOW, 0x00); - - crt_w(CRT_CURSOR_LOC_HIGH, 0x00); - crt_w(CRT_CURSOR_LOC_LOW, 0x00); - - DEBUG printk("CRT_START_VER_RETR: %ld\n", data.v_sstart & 0xff); - crt_w(CRT_START_VER_RETR, (data.v_sstart & 0xff)); - -#if 1 - /* 5 refresh cycles per scanline */ - DEBUG printk("CRT_END_VER_RETR: 64+32+%ld\n", data.v_sstop % 16); - crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 0x40 | 0x20)); -#else - DEBUG printk("CRT_END_VER_RETR: 128+32+%ld\n", data.v_sstop % 16); - crt_w(CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 128 | 32)); -#endif - DEBUG printk("CRT_VER_DISP_ENA_END: %ld\n", data.v_dispend & 0xff); - crt_w(CRT_VER_DISP_ENA_END, (data.v_dispend & 0xff)); - - DEBUG printk("CRT_START_VER_BLANK: %ld\n", data.v_bstart & 0xff); - crt_w(CRT_START_VER_BLANK, (data.v_bstart & 0xff)); - - DEBUG printk("CRT_END_VER_BLANK: %ld\n", data.v_bstop & 0xff); - crt_w(CRT_END_VER_BLANK, (data.v_bstop & 0xff)); - - DEBUG printk("CRT_MODE_CONTROL: 0xe3\n"); - crt_w(CRT_MODE_CONTROL, 0xe3); - - DEBUG printk("CRT_LINE_COMPARE: 0xff\n"); - crt_w(CRT_LINE_COMPARE, 0xff); - - tmp = (var->xres_virtual / 8) * (bpp / 8); - crt_w(CRT_OFFSET, tmp); - - crt_w(CRT_UNDERLINE_LOC, 0x07); /* probably font-height - 1 */ - - tmp = 0x20; /* Enable extended end bits */ - if (data.h_total & 0x100) - tmp |= 0x01; - if ((data.h_dispend) & 0x100) - tmp |= 0x02; - if (data.h_bstart & 0x100) - tmp |= 0x04; - if (data.h_sstart & 0x100) - tmp |= 0x08; - if (var->vmode & FB_VMODE_INTERLACED) - tmp |= 0x10; - DEBUG printk("CRT_EXT_HOR_TIMING1: %d\n", tmp); - crt_w(CRT_EXT_HOR_TIMING1, tmp); - - tmp = 0x00; - if (((var->xres_virtual / 8) * (bpp / 8)) & 0x100) - tmp |= 0x10; - crt_w(CRT_EXT_START_ADDR, tmp); - - tmp = 0x00; - if (data.h_total & 0x200) - tmp |= 0x01; - if ((data.h_dispend) & 0x200) - tmp |= 0x02; - if (data.h_bstart & 0x200) - tmp |= 0x04; - if (data.h_sstart & 0x200) - tmp |= 0x08; - tmp |= ((data.h_bstop & 0xc0) >> 2); - tmp |= ((data.h_sstop & 0x60) << 1); - crt_w(CRT_EXT_HOR_TIMING2, tmp); - DEBUG printk("CRT_EXT_HOR_TIMING2: %d\n", tmp); - - tmp = 0x10; /* Line compare bit 10 */ - if (data.v_total & 0x400) - tmp |= 0x01; - if ((data.v_dispend) & 0x400) - tmp |= 0x02; - if (data.v_bstart & 0x400) - tmp |= 0x04; - if (data.v_sstart & 0x400) - tmp |= 0x08; - tmp |= ((data.v_bstop & 0x300) >> 3); - if (data.v_sstop & 0x10) - tmp |= 0x80; - crt_w(CRT_EXT_VER_TIMING, tmp); - DEBUG printk("CRT_EXT_VER_TIMING: %d\n", tmp); - - crt_w(CRT_MONITOR_POWER, 0x00); - - /* - * Convert from ps to Hz. - */ - freq_f = (1.0/(float)var->pixclock) * 1000000000; - freq = ((long)freq_f) * 1000; - - best_freq = find_fq(freq); - pll_w(0x02, best_freq); - best_freq = find_fq(61000000); - pll_w(0x0a, best_freq); - pll_w(0x0e, 0x22); - - gfx_w(GFX_SET_RESET, 0x00); - gfx_w(GFX_ENABLE_SET_RESET, 0x00); - gfx_w(GFX_COLOR_COMPARE, 0x00); - gfx_w(GFX_DATA_ROTATE, 0x00); - gfx_w(GFX_READ_MAP_SELECT, 0x00); - gfx_w(GFX_GRAPHICS_MODE, 0x00); - gfx_w(GFX_MISC, 0x05); - gfx_w(GFX_COLOR_XCARE, 0x0f); - gfx_w(GFX_BITMASK, 0xff); - - reg_r(ACT_ADDRESS_RESET); - attr_w(ACT_PALETTE0 , 0x00); - attr_w(ACT_PALETTE1 , 0x01); - attr_w(ACT_PALETTE2 , 0x02); - attr_w(ACT_PALETTE3 , 0x03); - attr_w(ACT_PALETTE4 , 0x04); - attr_w(ACT_PALETTE5 , 0x05); - attr_w(ACT_PALETTE6 , 0x06); - attr_w(ACT_PALETTE7 , 0x07); - attr_w(ACT_PALETTE8 , 0x08); - attr_w(ACT_PALETTE9 , 0x09); - attr_w(ACT_PALETTE10, 0x0a); - attr_w(ACT_PALETTE11, 0x0b); - attr_w(ACT_PALETTE12, 0x0c); - attr_w(ACT_PALETTE13, 0x0d); - attr_w(ACT_PALETTE14, 0x0e); - attr_w(ACT_PALETTE15, 0x0f); - reg_r(ACT_ADDRESS_RESET); - - attr_w(ACT_ATTR_MODE_CNTL, 0x09); /* 0x01 for CL */ - - attr_w(ACT_OVERSCAN_COLOR, 0x00); - attr_w(ACT_COLOR_PLANE_ENA, 0x0f); - attr_w(ACT_HOR_PEL_PANNING, 0x00); - attr_w(ACT_COLOR_SELECT, 0x00); - - reg_r(ACT_ADDRESS_RESET); - reg_w(ACT_DATA, 0x20); - - reg_w(VDAC_MASK, 0xff); - - /* - * Extended palette adressing ??? - */ - switch (bpp){ - case 8: - reg_w(0x83c6, 0x00); - break; - case 16: - reg_w(0x83c6, 0x60); - break; - case 24: - reg_w(0x83c6, 0xe0); - break; - default: - printk("Illegal color-depth: %i\n", bpp); - } - - reg_w(VDAC_ADDRESS, 0x00); - - seq_w(SEQ_MAP_MASK, 0x0f ); - - return 0; -} - -/* - * Initialization - * - * Set the default video mode for this chipset. If a video mode was - * specified on the command line, it will override the default mode. - */ - -static int retz3_init(void) -{ - int i; -#if 0 - volatile unsigned long *CursorBase; -#endif - unsigned long board_addr, board_size; - struct ConfigDev *cd; - - cd = zorro_get_board (z3_key); - zorro_config_board (z3_key, 0); - board_addr = (unsigned long)cd->cd_BoardAddr; - board_size = (unsigned long)cd->cd_BoardSize; - - for (i = 0; i < 256; i++){ - for (i = 0; i < 256; i++){ - retz3_color_table [i][0] = i; - retz3_color_table [i][1] = i; - retz3_color_table [i][2] = i; - retz3_color_table [i][3] = 0; - } - } - - *memstart = (*memstart + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - - z3_mem = kernel_map (board_addr, board_size, - KERNELMAP_NOCACHE_SER, memstart); - - z3_regs = (char*) z3_mem; - z3_fbmem = z3_mem + VIDEO_MEM_OFFSET; - - /* Get memory size - for now we asume its a 4MB board */ - - z3_size = 0x00400000; /* 4 MB */ - - memset ((char*)z3_fbmem, 0, z3_size); - - /* Disable hardware cursor */ - - seq_w(SEQ_CURSOR_Y_INDEX, 0x00); - - -#if 0 - /* Initialize hardware cursor */ - CursorBase = (unsigned long *)((char *)(z3_mem) + z3_size - 0x400); - for (i=0; i < 8; i++){ - *(CursorBase +(i*4)) = 0xffffff00; - *(CursorBase+1+(i*4)) = 0xffff0000; - *(CursorBase+2+(i*4)) = 0xffff0000; - *(CursorBase+3+(i*4)) = 0xffff0000; - } - for (i=8; i < 64; i++){ - *(CursorBase +(i*4)) = 0xffff0000; - *(CursorBase+1+(i*4)) = 0xffff0000; - *(CursorBase+2+(i*4)) = 0xffff0000; - *(CursorBase+3+(i*4)) = 0xffff0000; - } -#endif - - retz3_setcolreg (255, 56, 100, 160, 0); - retz3_setcolreg (254, 0, 0, 0, 0); - - return 0; -} - - -/* - * This function should fill in the `fix' structure based on the - * values in the `par' structure. - */ - -static int retz3_encode_fix(struct fb_fix_screeninfo *fix, - struct retz3_fb_par *par) -{ - int i; - - strcpy(fix->id, retz3_fb_name); - fix->smem_start = z3_fbmem; - fix->smem_len = z3_size; - - fix->type = FB_TYPE_PACKED_PIXELS; - fix->type_aux = 0; - if (par->bpp == 8) - fix->visual = FB_VISUAL_PSEUDOCOLOR; - else - fix->visual = FB_VISUAL_DIRECTCOLOR; - - fix->xpanstep = 0; - fix->ypanstep = 0; - fix->ywrapstep = 0; - fix->line_length = 0; - - for (i = 0; i < arraysize(fix->reserved); i++) - fix->reserved[i] = 0; - - return 0; -} - - -/* - * Get the video params out of `var'. If a value doesn't fit, round - * it up, if it's too big, return -EINVAL. - */ - -static int retz3_decode_var(struct fb_var_screeninfo *var, - struct retz3_fb_par *par) -{ - par->xres = var->xres; - par->yres = var->yres; - par->xres_vir = var->xres_virtual; - par->yres_vir = var->yres_virtual; - par->bpp = var->bits_per_pixel; - par->pixclock = var->pixclock; - par->vmode = var->vmode; - - par->red = var->red; - par->green = var->green; - par->blue = var->blue; - par->transp = var->transp; - - par->left_margin = var->left_margin; - par->right_margin = var->right_margin; - par->upper_margin = var->upper_margin; - par->lower_margin = var->lower_margin; - par->hsync_len = var->hsync_len; - par->vsync_len = var->vsync_len; - - return 0; -} - - -/* - * Fill the `var' structure based on the values in `par' and maybe - * other values read out of the hardware. - */ - -static int retz3_encode_var(struct fb_var_screeninfo *var, - struct retz3_fb_par *par) -{ - int i; - - var->xres = par->xres; - var->yres = par->yres; - var->xres_virtual = par->xres_vir; - var->yres_virtual = par->yres_vir; - var->xoffset = 0; - var->yoffset = 0; - - var->bits_per_pixel = par->bpp; - var->grayscale = 0; - - var->red = par->red; - var->green = par->green; - var->blue = par->blue; - var->transp = par->transp; - - var->nonstd = 0; - var->activate = 0; - - var->height = -1; - var->width = -1; - - var->accel = FB_ACCEL_RETINAZ3; - - var->pixclock = par->pixclock; - - var->sync = 0; /* ??? */ - var->left_margin = par->left_margin; - var->right_margin = par->right_margin; - var->upper_margin = par->upper_margin; - var->lower_margin = par->lower_margin; - var->hsync_len = par->hsync_len; - var->vsync_len = par->vsync_len; - - for (i = 0; i < arraysize(var->reserved); i++) - var->reserved[i] = 0; - - var->vmode = par->vmode; - return 0; -} - - -/* - * Set a single color register. The values supplied are already - * rounded down to the hardware's capabilities (according to the - * entries in the var structure). Return != 0 for invalid regno. - */ - -static int retz3_setcolreg(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - unsigned int transp) -{ - /* We'll get to this */ - - if (regno > 255) - return 1; - - retz3_color_table [regno][0] = red & 0xff; - retz3_color_table [regno][1] = green & 0xff; - retz3_color_table [regno][2] = blue & 0xff; - retz3_color_table [regno][3] = transp; - - reg_w(VDAC_ADDRESS_W, regno); - reg_w(VDAC_DATA, (red & 0xff) >> 2); - reg_w(VDAC_DATA, (green & 0xff) >> 2); - reg_w(VDAC_DATA, (blue & 0xff) >> 2); - - return 0; -} - - -/* - * Read a single color register and split it into - * colors/transparent. Return != 0 for invalid regno. - */ - -static int retz3_getcolreg(unsigned int regno, unsigned int *red, - unsigned int *green, unsigned int *blue, - unsigned int *transp) -{ - if (regno > 255) - return 1; - *red = retz3_color_table [regno][0]; - *green = retz3_color_table [regno][1]; - *blue = retz3_color_table [regno][2]; - *transp = retz3_color_table [regno][3]; - return 0; -} - - -/* - * (Un)Blank the screen - */ - -void retz3_blank(int blank) -{ - int i; - - if (blank) - for (i = 0; i < 256; i++){ - reg_w(VDAC_ADDRESS_W, i); - reg_w(VDAC_DATA, 0); - reg_w(VDAC_DATA, 0); - reg_w(VDAC_DATA, 0); - } - else - for (i = 0; i < 256; i++){ - reg_w(VDAC_ADDRESS_W, i); - reg_w(VDAC_DATA, retz3_color_table [i][0] >> 2); - reg_w(VDAC_DATA, retz3_color_table [i][1] >> 2); - reg_w(VDAC_DATA, retz3_color_table [i][2] >> 2); - } -} - - -void retz3_bitblt (struct fb_var_screeninfo *var, - unsigned short srcx, unsigned short srcy, unsigned - short destx, unsigned short desty, unsigned short - width, unsigned short height, unsigned short cmd, - unsigned short mask) -{ - - volatile unsigned long *acm = (unsigned long *) (z3_mem + ACM_OFFSET); - unsigned long *pattern = (unsigned long *)(z3_fbmem + PAT_MEM_OFF); - - unsigned short mod; - unsigned long tmp; - unsigned long pat, src, dst; - unsigned char blt_status; - - int i, xres_virtual = var->xres_virtual; - short bpp = (var->bits_per_pixel & 0xff); - - if (bpp < 8) - bpp = 8; - - tmp = mask | (mask << 16); - -#if 0 - /* - * Check for blitter finished before we start messing with the - * pattern. - */ - do{ - blt_status = *(((volatile unsigned char *)acm) + - (ACM_START_STATUS + 2)); - }while ((blt_status & 1) == 0); -#endif - - i = 0; - do{ - *pattern++ = tmp; - }while(i++ < bpp/4); - - tmp = cmd << 8; - *(acm + ACM_RASTEROP_ROTATION/4) = tmp; - - mod = 0xc0c2; - - pat = 8 * PAT_MEM_OFF; - dst = bpp * (destx + desty * xres_virtual); - - /* - * Source is not set for clear. - */ - if ((cmd != Z3BLTclear) && (cmd != Z3BLTset)) { - src = bpp * (srcx + srcy * xres_virtual); - - if (destx > srcx) { - mod &= ~0x8000; - src += bpp * (width - 1); - dst += bpp * (width - 1); - pat += bpp * 2; - } - if (desty > srcy) { - mod &= ~0x4000; - src += bpp * (height - 1) * xres_virtual; - dst += bpp * (height - 1) * xres_virtual; - pat += bpp * 4; - } - - *(acm + ACM_SOURCE/4) = cpu_to_le32(src); - } - - *(acm + ACM_PATTERN/4) = cpu_to_le32(pat); - - *(acm + ACM_DESTINATION/4) = cpu_to_le32(dst); - - tmp = mod << 16; - *(acm + ACM_CONTROL/4) = tmp; - - tmp = width | (height << 16); - - *(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp); - - *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; - *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; - - /* - * No reason to wait for the blitter to finish, it is better - * just to check if it has finished before we use it again. - */ -#if 1 -#if 0 - while ((*(((volatile unsigned char *)acm) + - (ACM_START_STATUS + 2)) & 1) == 0); -#else - do{ - blt_status = *(((volatile unsigned char *)acm) + - (ACM_START_STATUS + 2)); - } - while ((blt_status & 1) == 0); -#endif -#endif -} - -#if 0 -void retz3_fill (unsigned short x, unsigned short y, unsigned - short width, unsigned short height, - unsigned short mode, unsigned short color) -{ - -} -#endif - - -/************************************************************** - * Move cursor to x, y - */ -void retz3_MoveCursor (unsigned short x, unsigned short y) -{ - /* Guess we gotta deal with the cursor at some point */ -} - - -/* -------------------- Interfaces to hardware functions -------------------- */ - - -static struct fb_hwswitch retz3_switch = { - retz3_init, retz3_encode_fix, retz3_decode_var, retz3_encode_var, - retz3_getcolreg, retz3_setcolreg, retz3_blank -}; - - -/* -------------------- Generic routines ------------------------------------ */ - - -/* - * Fill the hardware's `par' structure. - */ - -static void retz3_fb_get_par(struct retz3_fb_par *par) -{ - if (current_par_valid) - *par = current_par; - else - fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], par); -} - - -static void retz3_fb_set_par(struct retz3_fb_par *par) -{ - current_par = *par; - current_par_valid = 1; -} - - -static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) -{ - int err, activate; - struct retz3_fb_par par; - - if ((err = fbhw->decode_var(var, &par))) - return err; - activate = var->activate; - if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) - retz3_fb_set_par(&par); - fbhw->encode_var(var, &par); - var->activate = activate; - -#if 1 - retz3_set_video(var, ¤t_par); -#endif - return 0; -} - - -/* - * Default Colormaps - */ - -static unsigned short red16[] = - { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000, - 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff }; -static unsigned short green16[] = - { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000, - 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff }; -static unsigned short blue16[] = - { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, - 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff }; - - -static struct fb_cmap default_16_colors = - { 0, 16, red16, green16, blue16, NULL }; - - -static struct fb_cmap *get_default_colormap(int bpp) -{ - return &default_16_colors; -} - - -#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16) -#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \ - ((1<<(width))-1)) : 0)) - -static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc) -{ - int i, start; - unsigned short *red, *green, *blue, *transp; - unsigned int hred, hgreen, hblue, htransp; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - start = cmap->start; - - if (start < 0) - return -EINVAL; - for (i = 0; i < cmap->len; i++) { - if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp)) - return 0; - hred = CNVT_FROMHW(hred, var->red.length); - hgreen = CNVT_FROMHW(hgreen, var->green.length); - hblue = CNVT_FROMHW(hblue, var->blue.length); - htransp = CNVT_FROMHW(htransp, var->transp.length); - if (kspc) { - *red = hred; - *green = hgreen; - *blue = hblue; - if (transp) - *transp = htransp; - } else { - put_user(hred, red); - put_user(hgreen, green); - put_user(hblue, blue); - if (transp) - put_user(htransp, transp); - } - red++; - green++; - blue++; - if (transp) - transp++; - } - return 0; -} - - -static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, - int kspc) -{ - int i, start; - unsigned short *red, *green, *blue, *transp; - unsigned int hred, hgreen, hblue, htransp; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - start = cmap->start; - - if (start < 0) - return -EINVAL; - for (i = 0; i < cmap->len; i++) { - if (kspc) { - hred = *red; - hgreen = *green; - hblue = *blue; - htransp = transp ? *transp : 0; - } else { - get_user(hred, red); - get_user(hgreen, green); - get_user(hblue, blue); - if (transp) - get_user(htransp, transp); - else - htransp = 0; - } - hred = CNVT_TOHW(hred, var->red.length); - hgreen = CNVT_TOHW(hgreen, var->green.length); - hblue = CNVT_TOHW(hblue, var->blue.length); - htransp = CNVT_TOHW(htransp, var->transp.length); - red++; - green++; - blue++; - if (transp) - transp++; - if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp)) - return 0; - } - return 0; -} - - -static void do_install_cmap(int con) -{ - if (con != currcon) - return; - if (disp[con].cmap.len) - do_fb_set_cmap(&disp[con].cmap, &disp[con].var, 1); - else - do_fb_set_cmap(get_default_colormap(disp[con].var.bits_per_pixel), - &disp[con].var, 1); -} - - -static void memcpy_fs(int fsfromto, void *to, void *from, int len) -{ - switch (fsfromto) { - case 0: - memcpy(to, from, len); - return; - case 1: - copy_from_user(to, from, len); - return; - case 2: - copy_to_user(to, from, len); - return; - } -} - - -static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto) -{ - int size; - int tooff = 0, fromoff = 0; - - if (to->start > from->start) - fromoff = to->start-from->start; - else - tooff = from->start-to->start; - size = to->len-tooff; - if (size > from->len-fromoff) - size = from->len-fromoff; - if (size < 0) - return; - size *= sizeof(unsigned short); - memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size); - memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size); - memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size); - if (from->transp && to->transp) - memcpy_fs(fsfromto, to->transp+tooff, - from->transp+fromoff, size); -} - - -static int alloc_cmap(struct fb_cmap *cmap, int len, int transp) -{ - int size = len*sizeof(unsigned short); - - if (cmap->len != len) { - if (cmap->red) - kfree(cmap->red); - if (cmap->green) - kfree(cmap->green); - if (cmap->blue) - kfree(cmap->blue); - if (cmap->transp) - kfree(cmap->transp); - cmap->red = cmap->green = cmap->blue = cmap->transp = NULL; - cmap->len = 0; - if (!len) - return 0; - if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) - return -1; - if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) - return -1; - if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) - return -1; - if (transp) { - if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) - return -1; - } else - cmap->transp = NULL; - } - cmap->start = 0; - cmap->len = len; - copy_cmap(get_default_colormap(len), cmap, 0); - return 0; -} - - -/* - * Get the Fixed Part of the Display - */ - -static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con) -{ - struct retz3_fb_par par; - int error = 0; - - if (con == -1) - retz3_fb_get_par(&par); - else - error = fbhw->decode_var(&disp[con].var, &par); - return(error ? error : fbhw->encode_fix(fix, &par)); -} - - -/* - * Get the User Defined Part of the Display - */ - -static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con) -{ - struct retz3_fb_par par; - int error = 0; - - if (con == -1) { - retz3_fb_get_par(&par); - error = fbhw->encode_var(var, &par); - } else - *var = disp[con].var; - return error; -} - - -static void retz3_fb_set_disp(int con) -{ - struct fb_fix_screeninfo fix; - - retz3_fb_get_fix(&fix, con); - if (con == -1) - con = 0; - disp[con].screen_base = (unsigned char *)fix.smem_start; - disp[con].visual = fix.visual; - disp[con].type = fix.type; - disp[con].type_aux = fix.type_aux; - disp[con].ypanstep = fix.ypanstep; - disp[con].ywrapstep = fix.ywrapstep; - disp[con].can_soft_blank = 1; - disp[con].inverse = z3fb_inverse; -} - - -/* - * Set the User Defined Part of the Display - */ - -static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) -{ - int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp; - - if ((err = do_fb_set_var(var, con == currcon))) - return err; - if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { - oldxres = disp[con].var.xres; - oldyres = disp[con].var.yres; - oldvxres = disp[con].var.xres_virtual; - oldvyres = disp[con].var.yres_virtual; - oldbpp = disp[con].var.bits_per_pixel; - disp[con].var = *var; - if (oldxres != var->xres || oldyres != var->yres || - oldvxres != var->xres_virtual || - oldvyres != var->yres_virtual || - oldbpp != var->bits_per_pixel) { - retz3_fb_set_disp(con); - (*fb_info.changevar)(con); - alloc_cmap(&disp[con].cmap, 0, 0); - do_install_cmap(con); - } - } - var->activate = 0; - return 0; -} - - -/* - * Get the Colormap - */ - -static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) -{ - if (con == currcon) /* current console? */ - return(do_fb_get_cmap(cmap, &disp[con].var, kspc)); - else if (disp[con].cmap.len) /* non default colormap? */ - copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2); - else - copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), - cmap, kspc ? 0 : 2); - return 0; -} - - -/* - * Set the Colormap - */ - -static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) -{ - int err; - - if (!disp[con].cmap.len) { /* no colormap allocated? */ - if ((err = alloc_cmap(&disp[con].cmap, - 1<<disp[con].var.bits_per_pixel, 0))) - return err; - } - if (con == currcon) /* current console? */ - return(do_fb_set_cmap(cmap, &disp[con].var, kspc)); - else - copy_cmap(cmap, &disp[con].cmap, kspc ? 0 : 1); - return 0; -} - - -/* - * Pan or Wrap the Display - * - * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag - */ - -static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con) -{ - return -EINVAL; -} - - -/* - * RetinaZ3 Frame Buffer Specific ioctls - */ - -static int retz3_fb_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, int con) -{ - return -EINVAL; -} - - -static struct fb_ops retz3_fb_ops = { - retz3_fb_get_fix, retz3_fb_get_var, retz3_fb_set_var, retz3_fb_get_cmap, - retz3_fb_set_cmap, retz3_fb_pan_display, retz3_fb_ioctl -}; - - -int retz3_probe(void) -{ - z3_key = zorro_find(MANUF_MACROSYSTEMS2, PROD_RETINA_Z3, 0, 0); - return(z3_key); -} - - -void retz3_video_setup(char *options, int *ints) -{ - char *this_opt; - int i; - - fb_info.fontname[0] = '\0'; - - if (!options || !*options) - return; - - for (this_opt = strtok(options, ","); this_opt; - this_opt = strtok(NULL, ",")){ - if (!strcmp(this_opt, "inverse")) { - z3fb_inverse = 1; - for (i = 0; i < 16; i++) { - red16[i] = ~red16[i]; - green16[i] = ~green16[i]; - blue16[i] = ~blue16[i]; - } - } else if (!strncmp(this_opt, "font:", 5)) - strcpy(fb_info.fontname, this_opt+5); - else - z3fb_mode = get_video_mode(this_opt); - } -} - - -/* - * Initialization - */ - -__initfunc(struct fb_info *retz3_fb_init(long *mem_start)) -{ - int err; - struct retz3_fb_par par; - - memstart = mem_start; - - fbhw = &retz3_switch; - - err = register_framebuffer(retz3_fb_name, &node, &retz3_fb_ops, - NUM_TOTAL_MODES, retz3_fb_predefined); - if (err < 0) - panic("Cannot register frame buffer\n"); - - fbhw->init(); - - if (z3fb_mode == -1) - z3fb_mode = 1; - - fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], &par); - fbhw->encode_var(&retz3_fb_predefined[0], &par); - - strcpy(fb_info.modename, retz3_fb_name); - fb_info.disp = disp; - fb_info.switch_con = &z3fb_switch; - fb_info.updatevar = &z3fb_updatevar; - fb_info.blank = &z3fb_blank; - fb_info.setcmap = &z3fb_setcmap; - - do_fb_set_var(&retz3_fb_predefined[0], 0); - retz3_fb_get_var(&disp[0].var, -1); - retz3_fb_set_disp(-1); - do_install_cmap(0); - - return &fb_info; -} - - -static int z3fb_switch(int con) -{ - /* Do we have to save the colormap? */ - if (disp[currcon].cmap.len) - do_fb_get_cmap(&disp[currcon].cmap, &disp[currcon].var, 1); - - do_fb_set_var(&disp[con].var, 1); - currcon = con; - /* Install new colormap */ - do_install_cmap(con); - return 0; -} - - -/* - * Update the `var' structure (called by fbcon.c) - * - * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. - * Since it's called by a kernel driver, no range checking is done. - */ - -static int z3fb_updatevar(int con) -{ - return 0; -} - - -/* - * Blank the display. - */ - -static void z3fb_blank(int blank) -{ - fbhw->blank(blank); -} - - -/* - * Set the colormap - */ - -static int z3fb_setcmap(struct fb_cmap *cmap, int con) -{ - return(retz3_fb_set_cmap(cmap, 1, con)); -} - - -/* - * Get a Video Mode - */ - -static int get_video_mode(const char *name) -{ - int i; - - for (i = 1; i <= NUM_PREDEF_MODES; i++) - if (!strcmp(name, retz3_fb_modenames[i])){ - retz3_fb_predefined[0] = retz3_fb_predefined[i]; - return i; - } - return -1; -} diff --git a/arch/m68k/amiga/retz3fb.h b/arch/m68k/amiga/retz3fb.h deleted file mode 100644 index 0cb03c324..000000000 --- a/arch/m68k/amiga/retz3fb.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Linux/arch/m68k/amiga/retz3fb.h -- Defines and macros for the - * RetinaZ3 frame buffer device - * - * Copyright (C) 1997 Jes Sorensen - * - * History: - * - 22 Jan 97: Initial work - * - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -/* - * Macros to read and write to registers. - */ -#define reg_w(reg,dat) (*(z3_regs + reg) = dat) -#define reg_r(reg) (*(z3_regs + reg)) - -/* - * Macro to access the sequencer. - */ -#define seq_w(sreg,sdat) \ - do{ reg_w(SEQ_IDX, sreg); reg_w(SEQ_DATA, sdat); } while(0) - -/* - * Macro to access the CRT controller. - */ -#define crt_w(creg,cdat) \ - do{ reg_w(CRT_IDX, creg); reg_w(CRT_DATA, cdat); } while(0) - -/* - * Macro to access the graphics controller. - */ -#define gfx_w(greg,gdat) \ - do{ reg_w(GFX_IDX, greg); reg_w(GFX_DATA, gdat); } while(0) - -/* - * Macro to access the attribute controller. - */ -#define attr_w(areg,adat) \ - do{ reg_w(ACT_IDX, areg); reg_w(ACT_DATA, adat); } while(0) - -/* - * Macro to access the pll. - */ -#define pll_w(preg,pdat) \ - do{ reg_w(PLL_IDX, preg); \ - reg_w(PLL_DATA, (pdat & 0xff)); \ - reg_w(PLL_DATA, (pdat >> 8));\ - } while(0) - -/* - * Offsets - */ -#define VIDEO_MEM_OFFSET 0x00c00000 -#define ACM_OFFSET 0x00b00000 - -/* - * Accelerator Control Menu - */ -#define ACM_PRIMARY_OFFSET 0x00 -#define ACM_SECONDARY_OFFSET 0x04 -#define ACM_MODE_CONTROL 0x08 -#define ACM_CURSOR_POSITION 0x0c -#define ACM_START_STATUS 0x30 -#define ACM_CONTROL 0x34 -#define ACM_RASTEROP_ROTATION 0x38 -#define ACM_BITMAP_DIMENSION 0x3c -#define ACM_DESTINATION 0x40 -#define ACM_SOURCE 0x44 -#define ACM_PATTERN 0x48 -#define ACM_FOREGROUND 0x4c -#define ACM_BACKGROUND 0x50 - -/* - * Video DAC addresses - */ -#define VDAC_ADDRESS 0x03c8 -#define VDAC_ADDRESS_W 0x03c8 -#define VDAC_ADDRESS_R 0x03c7 -#define VDAC_STATE 0x03c7 -#define VDAC_DATA 0x03c9 -#define VDAC_MASK 0x03c6 - -/* - * Sequencer - */ -#define SEQ_IDX 0x03c4 /* Sequencer Index */ -#define SEQ_DATA 0x03c5 -#define SEQ_RESET 0x00 -#define SEQ_CLOCKING_MODE 0x01 -#define SEQ_MAP_MASK 0x02 -#define SEQ_CHAR_MAP_SELECT 0x03 -#define SEQ_MEMORY_MODE 0x04 -#define SEQ_EXTENDED_ENABLE 0x05 /* NCR extensions */ -#define SEQ_UNKNOWN1 0x06 -#define SEQ_UNKNOWN2 0x07 -#define SEQ_CHIP_ID 0x08 -#define SEQ_UNKNOWN3 0x09 -#define SEQ_CURSOR_COLOR1 0x0a -#define SEQ_CURSOR_COLOR0 0x0b -#define SEQ_CURSOR_CONTROL 0x0c -#define SEQ_CURSOR_X_LOC_HI 0x0d -#define SEQ_CURSOR_X_LOC_LO 0x0e -#define SEQ_CURSOR_Y_LOC_HI 0x0f -#define SEQ_CURSOR_Y_LOC_LO 0x10 -#define SEQ_CURSOR_X_INDEX 0x11 -#define SEQ_CURSOR_Y_INDEX 0x12 -#define SEQ_CURSOR_STORE_HI 0x13 -#define SEQ_CURSOR_STORE_LO 0x14 -#define SEQ_CURSOR_ST_OFF_HI 0x15 -#define SEQ_CURSOR_ST_OFF_LO 0x16 -#define SEQ_CURSOR_PIXELMASK 0x17 -#define SEQ_PRIM_HOST_OFF_HI 0x18 -#define SEQ_PRIM_HOST_OFF_LO 0x19 -#define SEQ_LINEAR_0 0x1a -#define SEQ_LINEAR_1 0x1b -#define SEQ_SEC_HOST_OFF_HI 0x1c -#define SEQ_SEC_HOST_OFF_LO 0x1d -#define SEQ_EXTENDED_MEM_ENA 0x1e -#define SEQ_EXT_CLOCK_MODE 0x1f -#define SEQ_EXT_VIDEO_ADDR 0x20 -#define SEQ_EXT_PIXEL_CNTL 0x21 -#define SEQ_BUS_WIDTH_FEEDB 0x22 -#define SEQ_PERF_SELECT 0x23 -#define SEQ_COLOR_EXP_WFG 0x24 -#define SEQ_COLOR_EXP_WBG 0x25 -#define SEQ_EXT_RW_CONTROL 0x26 -#define SEQ_MISC_FEATURE_SEL 0x27 -#define SEQ_COLOR_KEY_CNTL 0x28 -#define SEQ_COLOR_KEY_MATCH0 0x29 -#define SEQ_COLOR_KEY_MATCH1 0x2a -#define SEQ_COLOR_KEY_MATCH2 0x2b -#define SEQ_UNKNOWN6 0x2c -#define SEQ_CRC_CONTROL 0x2d -#define SEQ_CRC_DATA_LOW 0x2e -#define SEQ_CRC_DATA_HIGH 0x2f -#define SEQ_MEMORY_MAP_CNTL 0x30 -#define SEQ_ACM_APERTURE_1 0x31 -#define SEQ_ACM_APERTURE_2 0x32 -#define SEQ_ACM_APERTURE_3 0x33 -#define SEQ_BIOS_UTILITY_0 0x3e -#define SEQ_BIOS_UTILITY_1 0x3f - -/* - * Graphics Controller - */ -#define GFX_IDX 0x03ce -#define GFX_DATA 0x03cf -#define GFX_SET_RESET 0x00 -#define GFX_ENABLE_SET_RESET 0x01 -#define GFX_COLOR_COMPARE 0x02 -#define GFX_DATA_ROTATE 0x03 -#define GFX_READ_MAP_SELECT 0x04 -#define GFX_GRAPHICS_MODE 0x05 -#define GFX_MISC 0x06 -#define GFX_COLOR_XCARE 0x07 -#define GFX_BITMASK 0x08 - -/* - * CRT Controller - */ -#define CRT_IDX 0x03d4 -#define CRT_DATA 0x03d5 -#define CRT_HOR_TOTAL 0x00 -#define CRT_HOR_DISP_ENA_END 0x01 -#define CRT_START_HOR_BLANK 0x02 -#define CRT_END_HOR_BLANK 0x03 -#define CRT_START_HOR_RETR 0x04 -#define CRT_END_HOR_RETR 0x05 -#define CRT_VER_TOTAL 0x06 -#define CRT_OVERFLOW 0x07 -#define CRT_PRESET_ROW_SCAN 0x08 -#define CRT_MAX_SCAN_LINE 0x09 -#define CRT_CURSOR_START 0x0a -#define CRT_CURSOR_END 0x0b -#define CRT_START_ADDR_HIGH 0x0c -#define CRT_START_ADDR_LOW 0x0d -#define CRT_CURSOR_LOC_HIGH 0x0e -#define CRT_CURSOR_LOC_LOW 0x0f -#define CRT_START_VER_RETR 0x10 -#define CRT_END_VER_RETR 0x11 -#define CRT_VER_DISP_ENA_END 0x12 -#define CRT_OFFSET 0x13 -#define CRT_UNDERLINE_LOC 0x14 -#define CRT_START_VER_BLANK 0x15 -#define CRT_END_VER_BLANK 0x16 -#define CRT_MODE_CONTROL 0x17 -#define CRT_LINE_COMPARE 0x18 -#define CRT_UNKNOWN1 0x19 -#define CRT_UNKNOWN2 0x1a -#define CRT_UNKNOWN3 0x1b -#define CRT_UNKNOWN4 0x1c -#define CRT_UNKNOWN5 0x1d -#define CRT_UNKNOWN6 0x1e -#define CRT_UNKNOWN7 0x1f -#define CRT_UNKNOWN8 0x20 -#define CRT_UNKNOWN9 0x21 -#define CRT_UNKNOWN10 0x22 -#define CRT_UNKNOWN11 0x23 -#define CRT_UNKNOWN12 0x24 -#define CRT_UNKNOWN13 0x25 -#define CRT_UNKNOWN14 0x26 -#define CRT_UNKNOWN15 0x27 -#define CRT_UNKNOWN16 0x28 -#define CRT_UNKNOWN17 0x29 -#define CRT_UNKNOWN18 0x2a -#define CRT_UNKNOWN19 0x2b -#define CRT_UNKNOWN20 0x2c -#define CRT_UNKNOWN21 0x2d -#define CRT_UNKNOWN22 0x2e -#define CRT_UNKNOWN23 0x2f -#define CRT_EXT_HOR_TIMING1 0x30 /* NCR crt extensions */ -#define CRT_EXT_START_ADDR 0x31 -#define CRT_EXT_HOR_TIMING2 0x32 -#define CRT_EXT_VER_TIMING 0x33 -#define CRT_MONITOR_POWER 0x34 - -/* - * General Registers - */ -#define GREG_STATUS0_R 0x03c2 -#define GREG_STATUS1_R 0x03da -#define GREG_MISC_OUTPUT_R 0x03cc -#define GREG_MISC_OUTPUT_W 0x03c2 -#define GREG_FEATURE_CONTROL_R 0x03ca -#define GREG_FEATURE_CONTROL_W 0x03da -#define GREG_POS 0x0102 - -/* - * Attribute Controller - */ -#define ACT_IDX 0x03C0 -#define ACT_ADDRESS_R 0x03C0 -#define ACT_DATA 0x03C0 -#define ACT_ADDRESS_RESET 0x03DA -#define ACT_PALETTE0 0x00 -#define ACT_PALETTE1 0x01 -#define ACT_PALETTE2 0x02 -#define ACT_PALETTE3 0x03 -#define ACT_PALETTE4 0x04 -#define ACT_PALETTE5 0x05 -#define ACT_PALETTE6 0x06 -#define ACT_PALETTE7 0x07 -#define ACT_PALETTE8 0x08 -#define ACT_PALETTE9 0x09 -#define ACT_PALETTE10 0x0A -#define ACT_PALETTE11 0x0B -#define ACT_PALETTE12 0x0C -#define ACT_PALETTE13 0x0D -#define ACT_PALETTE14 0x0E -#define ACT_PALETTE15 0x0F -#define ACT_ATTR_MODE_CNTL 0x10 -#define ACT_OVERSCAN_COLOR 0x11 -#define ACT_COLOR_PLANE_ENA 0x12 -#define ACT_HOR_PEL_PANNING 0x13 -#define ACT_COLOR_SELECT 0x14 - -/* - * PLL - */ -#define PLL_IDX 0x83c8 -#define PLL_DATA 0x83c9 - -/* - * Blitter operations - */ -#define Z3BLTclear 0x00 /* 0 */ -#define Z3BLTand 0x80 /* src AND dst */ -#define Z3BLTandReverse 0x40 /* src AND NOT dst */ -#define Z3BLTcopy 0xc0 /* src */ -#define Z3BLTandInverted 0x20 /* NOT src AND dst */ -#define Z3BLTnoop 0xa0 /* dst */ -#define Z3BLTxor 0x60 /* src XOR dst */ -#define Z3BLTor 0xe0 /* src OR dst */ -#define Z3BLTnor 0x10 /* NOT src AND NOT dst */ -#define Z3BLTequiv 0x90 /* NOT src XOR dst */ -#define Z3BLTinvert 0x50 /* NOT dst */ -#define Z3BLTorReverse 0xd0 /* src OR NOT dst */ -#define Z3BLTcopyInverted 0x30 /* NOT src */ -#define Z3BLTorInverted 0xb0 /* NOT src OR dst */ -#define Z3BLTnand 0x70 /* NOT src OR NOT dst */ -#define Z3BLTset 0xf0 /* 1 */ |