⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amifb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * linux/drivers/video/amifb.c -- Amiga builtin chipset frame buffer device * *    Copyright (C) 1995-2003 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/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/ioport.h>#include <linux/uaccess.h>#include <asm/system.h>#include <asm/irq.h>#include <asm/amigahw.h>#include <asm/amigaints.h>#include <asm/setup.h>#include "c2p.h"#define DEBUG#if !defined(CONFIG_FB_AMIGA_OCS) && !defined(CONFIG_FB_AMIGA_ECS) && !defined(CONFIG_FB_AMIGA_AGA)#define CONFIG_FB_AMIGA_OCS   /* define at least one fb driver, this will change later */#endif#if !defined(CONFIG_FB_AMIGA_OCS)#  define IS_OCS (0)#elif defined(CONFIG_FB_AMIGA_ECS) || defined(CONFIG_FB_AMIGA_AGA)#  define IS_OCS (chipset == TAG_OCS)#else#  define CONFIG_FB_AMIGA_OCS_ONLY#  define IS_OCS (1)#endif#if !defined(CONFIG_FB_AMIGA_ECS)#  define IS_ECS (0)#elif defined(CONFIG_FB_AMIGA_OCS) || defined(CONFIG_FB_AMIGA_AGA)#  define IS_ECS (chipset == TAG_ECS)#else#  define CONFIG_FB_AMIGA_ECS_ONLY#  define IS_ECS (1)#endif#if !defined(CONFIG_FB_AMIGA_AGA)#  define IS_AGA (0)#elif defined(CONFIG_FB_AMIGA_OCS) || defined(CONFIG_FB_AMIGA_ECS)#  define IS_AGA (chipset == TAG_AGA)#else#  define CONFIG_FB_AMIGA_AGA_ONLY#  define IS_AGA (1)#endif#ifdef DEBUG#  define DPRINTK(fmt, args...)	printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)#else#  define DPRINTK(fmt, args...)#endif/*******************************************************************************   Generic video timings   ---------------------   Timings used by the frame buffer interface:   +----------+---------------------------------------------+----------+-------+   |          |                ^                            |          |       |   |          |                |upper_margin                |          |       |   |          |                v                            |          |       |   +----------###############################################----------+-------+   |          #                ^                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |   left   #                |                            #  right   | hsync |   |  margin  #                |       xres                 #  margin  |  len  |   |<-------->#<---------------+--------------------------->#<-------->|<----->|   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |yres                        #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                |                            #          |       |   |          #                v                            #          |       |   +----------###############################################----------+-------+   |          |                ^                            |          |       |   |          |                |lower_margin                |          |       |   |          |                v                            |          |       |   +----------+---------------------------------------------+----------+-------+   |          |                ^                            |          |       |   |          |                |vsync_len                   |          |       |   |          |                v                            |          |       |   +----------+---------------------------------------------+----------+-------+   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 (useful 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 already 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 lose the ability to        do smooth horizontal panning (xpanstep 1 -> 64).      - if you want to go even further, you lose 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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -