PageRenderTime 67ms CodeModel.GetById 21ms app.highlight 32ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/video/amifb.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 3825 lines | 2620 code | 461 blank | 744 comment | 470 complexity | 9a79b73d8cd1f4f6d49f1a5145d7f9f7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * linux/drivers/video/amifb.c -- Amiga builtin chipset frame buffer device
   3 *
   4 *    Copyright (C) 1995-2003 Geert Uytterhoeven
   5 *
   6 *          with work by Roman Zippel
   7 *
   8 *
   9 * This file is based on the Atari frame buffer device (atafb.c):
  10 *
  11 *    Copyright (C) 1994 Martin Schaller
  12 *                       Roman Hodek
  13 *
  14 *          with work by Andreas Schwab
  15 *                       Guenther Kelleter
  16 *
  17 * and on the original Amiga console driver (amicon.c):
  18 *
  19 *    Copyright (C) 1993 Hamish Macdonald
  20 *                       Greg Harp
  21 *    Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
  22 *
  23 *          with work by William Rucklidge (wjr@cs.cornell.edu)
  24 *                       Geert Uytterhoeven
  25 *                       Jes Sorensen (jds@kom.auc.dk)
  26 *
  27 *
  28 * History:
  29 *
  30 *   - 24 Jul 96: Copper generates now vblank interrupt and
  31 *                VESA Power Saving Protocol is fully implemented
  32 *   - 14 Jul 96: Rework and hopefully last ECS bugs fixed
  33 *   -  7 Mar 96: Hardware sprite support by Roman Zippel
  34 *   - 18 Feb 96: OCS and ECS support by Roman Zippel
  35 *                Hardware functions completely rewritten
  36 *   -  2 Dec 95: AGA version by Geert Uytterhoeven
  37 *
  38 * This file is subject to the terms and conditions of the GNU General Public
  39 * License. See the file COPYING in the main directory of this archive
  40 * for more details.
  41 */
  42
  43#include <linux/module.h>
  44#include <linux/kernel.h>
  45#include <linux/errno.h>
  46#include <linux/string.h>
  47#include <linux/mm.h>
  48#include <linux/delay.h>
  49#include <linux/interrupt.h>
  50#include <linux/fb.h>
  51#include <linux/init.h>
  52#include <linux/ioport.h>
  53#include <linux/platform_device.h>
  54#include <linux/uaccess.h>
  55
  56#include <asm/system.h>
  57#include <asm/irq.h>
  58#include <asm/amigahw.h>
  59#include <asm/amigaints.h>
  60#include <asm/setup.h>
  61
  62#include "c2p.h"
  63
  64
  65#define DEBUG
  66
  67#if !defined(CONFIG_FB_AMIGA_OCS) && !defined(CONFIG_FB_AMIGA_ECS) && !defined(CONFIG_FB_AMIGA_AGA)
  68#define CONFIG_FB_AMIGA_OCS   /* define at least one fb driver, this will change later */
  69#endif
  70
  71#if !defined(CONFIG_FB_AMIGA_OCS)
  72#  define IS_OCS (0)
  73#elif defined(CONFIG_FB_AMIGA_ECS) || defined(CONFIG_FB_AMIGA_AGA)
  74#  define IS_OCS (chipset == TAG_OCS)
  75#else
  76#  define CONFIG_FB_AMIGA_OCS_ONLY
  77#  define IS_OCS (1)
  78#endif
  79
  80#if !defined(CONFIG_FB_AMIGA_ECS)
  81#  define IS_ECS (0)
  82#elif defined(CONFIG_FB_AMIGA_OCS) || defined(CONFIG_FB_AMIGA_AGA)
  83#  define IS_ECS (chipset == TAG_ECS)
  84#else
  85#  define CONFIG_FB_AMIGA_ECS_ONLY
  86#  define IS_ECS (1)
  87#endif
  88
  89#if !defined(CONFIG_FB_AMIGA_AGA)
  90#  define IS_AGA (0)
  91#elif defined(CONFIG_FB_AMIGA_OCS) || defined(CONFIG_FB_AMIGA_ECS)
  92#  define IS_AGA (chipset == TAG_AGA)
  93#else
  94#  define CONFIG_FB_AMIGA_AGA_ONLY
  95#  define IS_AGA (1)
  96#endif
  97
  98#ifdef DEBUG
  99#  define DPRINTK(fmt, args...)	printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
 100#else
 101#  define DPRINTK(fmt, args...)
 102#endif
 103
 104/*******************************************************************************
 105
 106
 107   Generic video timings
 108   ---------------------
 109
 110   Timings used by the frame buffer interface:
 111
 112   +----------+---------------------------------------------+----------+-------+
 113   |          |                ^                            |          |       |
 114   |          |                |upper_margin                |          |       |
 115   |          |                v                            |          |       |
 116   +----------###############################################----------+-------+
 117   |          #                ^                            #          |       |
 118   |          #                |                            #          |       |
 119   |          #                |                            #          |       |
 120   |          #                |                            #          |       |
 121   |   left   #                |                            #  right   | hsync |
 122   |  margin  #                |       xres                 #  margin  |  len  |
 123   |<-------->#<---------------+--------------------------->#<-------->|<----->|
 124   |          #                |                            #          |       |
 125   |          #                |                            #          |       |
 126   |          #                |                            #          |       |
 127   |          #                |yres                        #          |       |
 128   |          #                |                            #          |       |
 129   |          #                |                            #          |       |
 130   |          #                |                            #          |       |
 131   |          #                |                            #          |       |
 132   |          #                |                            #          |       |
 133   |          #                |                            #          |       |
 134   |          #                |                            #          |       |
 135   |          #                |                            #          |       |
 136   |          #                v                            #          |       |
 137   +----------###############################################----------+-------+
 138   |          |                ^                            |          |       |
 139   |          |                |lower_margin                |          |       |
 140   |          |                v                            |          |       |
 141   +----------+---------------------------------------------+----------+-------+
 142   |          |                ^                            |          |       |
 143   |          |                |vsync_len                   |          |       |
 144   |          |                v                            |          |       |
 145   +----------+---------------------------------------------+----------+-------+
 146
 147
 148   Amiga video timings
 149   -------------------
 150
 151   The Amiga native chipsets uses another timing scheme:
 152
 153      - hsstrt:   Start of horizontal synchronization pulse
 154      - hsstop:   End of horizontal synchronization pulse
 155      - htotal:   Last value on the line (i.e. line length = htotal+1)
 156      - vsstrt:   Start of vertical synchronization pulse
 157      - vsstop:   End of vertical synchronization pulse
 158      - vtotal:   Last line value (i.e. number of lines = vtotal+1)
 159      - hcenter:  Start of vertical retrace for interlace
 160
 161   You can specify the blanking timings independently. Currently I just set
 162   them equal to the respective synchronization values:
 163
 164      - hbstrt:   Start of horizontal blank
 165      - hbstop:   End of horizontal blank
 166      - vbstrt:   Start of vertical blank
 167      - vbstop:   End of vertical blank
 168
 169   Horizontal values are in color clock cycles (280 ns), vertical values are in
 170   scanlines.
 171
 172   (0, 0) is somewhere in the upper-left corner :-)
 173
 174
 175   Amiga visible window definitions
 176   --------------------------------
 177
 178   Currently I only have values for AGA, SHRES (28 MHz dotclock). Feel free to
 179   make corrections and/or additions.
 180
 181   Within the above synchronization specifications, the visible window is
 182   defined by the following parameters (actual register resolutions may be
 183   different; all horizontal values are normalized with respect to the pixel
 184   clock):
 185
 186      - diwstrt_h:   Horizontal start of the visible window
 187      - diwstop_h:   Horizontal stop+1(*) of the visible window
 188      - diwstrt_v:   Vertical start of the visible window
 189      - diwstop_v:   Vertical stop of the visible window
 190      - ddfstrt:     Horizontal start of display DMA
 191      - ddfstop:     Horizontal stop of display DMA
 192      - hscroll:     Horizontal display output delay
 193
 194   Sprite positioning:
 195
 196      - sprstrt_h:   Horizontal start-4 of sprite
 197      - sprstrt_v:   Vertical start of sprite
 198
 199   (*) Even Commodore did it wrong in the AGA monitor drivers by not adding 1.
 200
 201   Horizontal values are in dotclock cycles (35 ns), vertical values are in
 202   scanlines.
 203
 204   (0, 0) is somewhere in the upper-left corner :-)
 205
 206
 207   Dependencies (AGA, SHRES (35 ns dotclock))
 208   -------------------------------------------
 209
 210   Since there are much more parameters for the Amiga display than for the
 211   frame buffer interface, there must be some dependencies among the Amiga
 212   display parameters. Here's what I found out:
 213
 214      - ddfstrt and ddfstop are best aligned to 64 pixels.
 215      - the chipset needs 64+4 horizontal pixels after the DMA start before the
 216        first pixel is output, so diwstrt_h = ddfstrt+64+4 if you want to
 217        display the first pixel on the line too. Increase diwstrt_h for virtual
 218        screen panning.
 219      - the display DMA always fetches 64 pixels at a time (fmode = 3).
 220      - ddfstop is ddfstrt+#pixels-64.
 221      - diwstop_h = diwstrt_h+xres+1. Because of the additional 1 this can be 1
 222        more than htotal.
 223      - hscroll simply adds a delay to the display output. Smooth horizontal
 224        panning needs an extra 64 pixels on the left to prefetch the pixels that
 225        `fall off' on the left.
 226      - if ddfstrt < 192, the sprite DMA cycles are all stolen by the bitplane
 227        DMA, so it's best to make the DMA start as late as possible.
 228      - you really don't want to make ddfstrt < 128, since this will steal DMA
 229        cycles from the other DMA channels (audio, floppy and Chip RAM refresh).
 230      - I make diwstop_h and diwstop_v as large as possible.
 231
 232   General dependencies
 233   --------------------
 234
 235      - all values are SHRES pixel (35ns)
 236
 237                  table 1:fetchstart  table 2:prefetch    table 3:fetchsize
 238                  ------------------  ----------------    -----------------
 239   Pixclock     # SHRES|HIRES|LORES # SHRES|HIRES|LORES # SHRES|HIRES|LORES
 240   -------------#------+-----+------#------+-----+------#------+-----+------
 241   Bus width 1x #   16 |  32 |  64  #   16 |  32 |  64  #   64 |  64 |  64
 242   Bus width 2x #   32 |  64 | 128  #   32 |  64 |  64  #   64 |  64 | 128
 243   Bus width 4x #   64 | 128 | 256  #   64 |  64 |  64  #   64 | 128 | 256
 244
 245      - chipset needs 4 pixels before the first pixel is output
 246      - ddfstrt must be aligned to fetchstart (table 1)
 247      - chipset needs also prefetch (table 2) to get first pixel data, so
 248        ddfstrt = ((diwstrt_h-4) & -fetchstart) - prefetch
 249      - for horizontal panning decrease diwstrt_h
 250      - the length of a fetchline must be aligned to fetchsize (table 3)
 251      - if fetchstart is smaller than fetchsize, then ddfstrt can a little bit
 252        moved to optimize use of dma (useful for OCS/ECS overscan displays)
 253      - ddfstop is ddfstrt+ddfsize-fetchsize
 254      - If C= didn't change anything for AGA, then at following positions the
 255        dma bus is already used:
 256        ddfstrt <  48 -> memory refresh
 257                <  96 -> disk dma
 258                < 160 -> audio dma
 259                < 192 -> sprite 0 dma
 260                < 416 -> sprite dma (32 per sprite)
 261      - in accordance with the hardware reference manual a hardware stop is at
 262        192, but AGA (ECS?) can go below this.
 263
 264   DMA priorities
 265   --------------
 266
 267   Since there are limits on the earliest start value for display DMA and the
 268   display of sprites, I use the following policy on horizontal panning and
 269   the hardware cursor:
 270
 271      - if you want to start display DMA too early, you lose the ability to
 272        do smooth horizontal panning (xpanstep 1 -> 64).
 273      - if you want to go even further, you lose the hardware cursor too.
 274
 275   IMHO a hardware cursor is more important for X than horizontal scrolling,
 276   so that's my motivation.
 277
 278
 279   Implementation
 280   --------------
 281
 282   ami_decode_var() converts the frame buffer values to the Amiga values. It's
 283   just a `straightforward' implementation of the above rules.
 284
 285
 286   Standard VGA timings
 287   --------------------
 288
 289               xres  yres    left  right  upper  lower    hsync    vsync
 290               ----  ----    ----  -----  -----  -----    -----    -----
 291      80x25     720   400      27     45     35     12      108        2
 292      80x30     720   480      27     45     30      9      108        2
 293
 294   These were taken from a XFree86 configuration file, recalculated for a 28 MHz
 295   dotclock (Amigas don't have a 25 MHz dotclock) and converted to frame buffer
 296   generic timings.
 297
 298   As a comparison, graphics/monitor.h suggests the following:
 299
 300               xres  yres    left  right  upper  lower    hsync    vsync
 301               ----  ----    ----  -----  -----  -----    -----    -----
 302
 303      VGA       640   480      52    112     24     19    112 -      2 +
 304      VGA70     640   400      52    112     27     21    112 -      2 -
 305
 306
 307   Sync polarities
 308   ---------------
 309
 310      VSYNC    HSYNC    Vertical size    Vertical total
 311      -----    -----    -------------    --------------
 312        +        +           Reserved          Reserved
 313        +        -                400               414
 314        -        +                350               362
 315        -        -                480               496
 316
 317   Source: CL-GD542X Technical Reference Manual, Cirrus Logic, Oct 1992
 318
 319
 320   Broadcast video timings
 321   -----------------------
 322
 323   According to the CCIR and RETMA specifications, we have the following values:
 324
 325   CCIR -> PAL
 326   -----------
 327
 328      - a scanline is 64 µs long, of which 52.48 µs are visible. This is about
 329        736 visible 70 ns pixels per line.
 330      - we have 625 scanlines, of which 575 are visible (interlaced); after
 331        rounding this becomes 576.
 332
 333   RETMA -> NTSC
 334   -------------
 335
 336      - a scanline is 63.5 µs long, of which 53.5 µs are visible.  This is about
 337        736 visible 70 ns pixels per line.
 338      - we have 525 scanlines, of which 485 are visible (interlaced); after
 339        rounding this becomes 484.
 340
 341   Thus if you want a PAL compatible display, you have to do the following:
 342
 343      - set the FB_SYNC_BROADCAST flag to indicate that standard broadcast
 344        timings are to be used.
 345      - make sure upper_margin+yres+lower_margin+vsync_len = 625 for an
 346        interlaced, 312 for a non-interlaced and 156 for a doublescanned
 347        display.
 348      - make sure left_margin+xres+right_margin+hsync_len = 1816 for a SHRES,
 349        908 for a HIRES and 454 for a LORES display.
 350      - the left visible part begins at 360 (SHRES; HIRES:180, LORES:90),
 351        left_margin+2*hsync_len must be greater or equal.
 352      - the upper visible part begins at 48 (interlaced; non-interlaced:24,
 353        doublescanned:12), upper_margin+2*vsync_len must be greater or equal.
 354      - ami_encode_var() calculates margins with a hsync of 5320 ns and a vsync
 355        of 4 scanlines
 356
 357   The settings for a NTSC compatible display are straightforward.
 358
 359   Note that in a strict sense the PAL and NTSC standards only define the
 360   encoding of the color part (chrominance) of the video signal and don't say
 361   anything about horizontal/vertical synchronization nor refresh rates.
 362
 363
 364                                                            -- Geert --
 365
 366*******************************************************************************/
 367
 368
 369	/*
 370	 * Custom Chipset Definitions
 371	 */
 372
 373#define CUSTOM_OFS(fld) ((long)&((struct CUSTOM*)0)->fld)
 374
 375	/*
 376	 * BPLCON0 -- Bitplane Control Register 0
 377	 */
 378
 379#define BPC0_HIRES	(0x8000)
 380#define BPC0_BPU2	(0x4000) /* Bit plane used count */
 381#define BPC0_BPU1	(0x2000)
 382#define BPC0_BPU0	(0x1000)
 383#define BPC0_HAM	(0x0800) /* HAM mode */
 384#define BPC0_DPF	(0x0400) /* Double playfield */
 385#define BPC0_COLOR	(0x0200) /* Enable colorburst */
 386#define BPC0_GAUD	(0x0100) /* Genlock audio enable */
 387#define BPC0_UHRES	(0x0080) /* Ultrahi res enable */
 388#define BPC0_SHRES	(0x0040) /* Super hi res mode */
 389#define BPC0_BYPASS	(0x0020) /* Bypass LUT - AGA */
 390#define BPC0_BPU3	(0x0010) /* AGA */
 391#define BPC0_LPEN	(0x0008) /* Light pen enable */
 392#define BPC0_LACE	(0x0004) /* Interlace */
 393#define BPC0_ERSY	(0x0002) /* External resync */
 394#define BPC0_ECSENA	(0x0001) /* ECS enable */
 395
 396	/*
 397	 * BPLCON2 -- Bitplane Control Register 2
 398	 */
 399
 400#define BPC2_ZDBPSEL2	(0x4000) /* Bitplane to be used for ZD - AGA */
 401#define BPC2_ZDBPSEL1	(0x2000)
 402#define BPC2_ZDBPSEL0	(0x1000)
 403#define BPC2_ZDBPEN	(0x0800) /* Enable ZD with ZDBPSELx - AGA */
 404#define BPC2_ZDCTEN	(0x0400) /* Enable ZD with palette bit #31 - AGA */
 405#define BPC2_KILLEHB	(0x0200) /* Kill EHB mode - AGA */
 406#define BPC2_RDRAM	(0x0100) /* Color table accesses read, not write - AGA */
 407#define BPC2_SOGEN	(0x0080) /* SOG output pin high - AGA */
 408#define BPC2_PF2PRI	(0x0040) /* PF2 priority over PF1 */
 409#define BPC2_PF2P2	(0x0020) /* PF2 priority wrt sprites */
 410#define BPC2_PF2P1	(0x0010)
 411#define BPC2_PF2P0	(0x0008)
 412#define BPC2_PF1P2	(0x0004) /* ditto PF1 */
 413#define BPC2_PF1P1	(0x0002)
 414#define BPC2_PF1P0	(0x0001)
 415
 416	/*
 417	 * BPLCON3 -- Bitplane Control Register 3 (AGA)
 418	 */
 419
 420#define BPC3_BANK2	(0x8000) /* Bits to select color register bank */
 421#define BPC3_BANK1	(0x4000)
 422#define BPC3_BANK0	(0x2000)
 423#define BPC3_PF2OF2	(0x1000) /* Bits for color table offset when PF2 */
 424#define BPC3_PF2OF1	(0x0800)
 425#define BPC3_PF2OF0	(0x0400)
 426#define BPC3_LOCT	(0x0200) /* Color register writes go to low bits */
 427#define BPC3_SPRES1	(0x0080) /* Sprite resolution bits */
 428#define BPC3_SPRES0	(0x0040)
 429#define BPC3_BRDRBLNK	(0x0020) /* Border blanked? */
 430#define BPC3_BRDRTRAN	(0x0010) /* Border transparent? */
 431#define BPC3_ZDCLKEN	(0x0004) /* ZD pin is 14 MHz (HIRES) clock output */
 432#define BPC3_BRDRSPRT	(0x0002) /* Sprites in border? */
 433#define BPC3_EXTBLKEN	(0x0001) /* BLANK programmable */
 434
 435	/*
 436	 * BPLCON4 -- Bitplane Control Register 4 (AGA)
 437	 */
 438
 439#define BPC4_BPLAM7	(0x8000) /* bitplane color XOR field */
 440#define BPC4_BPLAM6	(0x4000)
 441#define BPC4_BPLAM5	(0x2000)
 442#define BPC4_BPLAM4	(0x1000)
 443#define BPC4_BPLAM3	(0x0800)
 444#define BPC4_BPLAM2	(0x0400)
 445#define BPC4_BPLAM1	(0x0200)
 446#define BPC4_BPLAM0	(0x0100)
 447#define BPC4_ESPRM7	(0x0080) /* 4 high bits for even sprite colors */
 448#define BPC4_ESPRM6	(0x0040)
 449#define BPC4_ESPRM5	(0x0020)
 450#define BPC4_ESPRM4	(0x0010)
 451#define BPC4_OSPRM7	(0x0008) /* 4 high bits for odd sprite colors */
 452#define BPC4_OSPRM6	(0x0004)
 453#define BPC4_OSPRM5	(0x0002)
 454#define BPC4_OSPRM4	(0x0001)
 455
 456	/*
 457	 * BEAMCON0 -- Beam Control Register
 458	 */
 459
 460#define BMC0_HARDDIS	(0x4000) /* Disable hardware limits */
 461#define BMC0_LPENDIS	(0x2000) /* Disable light pen latch */
 462#define BMC0_VARVBEN	(0x1000) /* Enable variable vertical blank */
 463#define BMC0_LOLDIS	(0x0800) /* Disable long/short line toggle */
 464#define BMC0_CSCBEN	(0x0400) /* Composite sync/blank */
 465#define BMC0_VARVSYEN	(0x0200) /* Enable variable vertical sync */
 466#define BMC0_VARHSYEN	(0x0100) /* Enable variable horizontal sync */
 467#define BMC0_VARBEAMEN	(0x0080) /* Enable variable beam counters */
 468#define BMC0_DUAL	(0x0040) /* Enable alternate horizontal beam counter */
 469#define BMC0_PAL	(0x0020) /* Set decodes for PAL */
 470#define BMC0_VARCSYEN	(0x0010) /* Enable variable composite sync */
 471#define BMC0_BLANKEN	(0x0008) /* Blank enable (no longer used on AGA) */
 472#define BMC0_CSYTRUE	(0x0004) /* CSY polarity */
 473#define BMC0_VSYTRUE	(0x0002) /* VSY polarity */
 474#define BMC0_HSYTRUE	(0x0001) /* HSY polarity */
 475
 476
 477	/*
 478	 * FMODE -- Fetch Mode Control Register (AGA)
 479	 */
 480
 481#define FMODE_SSCAN2	(0x8000) /* Sprite scan-doubling */
 482#define FMODE_BSCAN2	(0x4000) /* Use PF2 modulus every other line */
 483#define FMODE_SPAGEM	(0x0008) /* Sprite page mode */
 484#define FMODE_SPR32	(0x0004) /* Sprite 32 bit fetch */
 485#define FMODE_BPAGEM	(0x0002) /* Bitplane page mode */
 486#define FMODE_BPL32	(0x0001) /* Bitplane 32 bit fetch */
 487
 488	/*
 489	 * Tags used to indicate a specific Pixel Clock
 490	 *
 491	 * clk_shift is the shift value to get the timings in 35 ns units
 492	 */
 493
 494enum { TAG_SHRES, TAG_HIRES, TAG_LORES };
 495
 496	/*
 497	 * Tags used to indicate the specific chipset
 498	 */
 499
 500enum { TAG_OCS, TAG_ECS, TAG_AGA };
 501
 502	/*
 503	 * Tags used to indicate the memory bandwidth
 504	 */
 505
 506enum { TAG_FMODE_1, TAG_FMODE_2, TAG_FMODE_4 };
 507
 508
 509	/*
 510	 * Clock Definitions, Maximum Display Depth
 511	 *
 512	 * These depend on the E-Clock or the Chipset, so they are filled in
 513	 * dynamically
 514	 */
 515
 516static u_long pixclock[3];	/* SHRES/HIRES/LORES: index = clk_shift */
 517static u_short maxdepth[3];	/* SHRES/HIRES/LORES: index = clk_shift */
 518static u_short maxfmode, chipset;
 519
 520
 521	/*
 522	 * Broadcast Video Timings
 523	 *
 524	 * Horizontal values are in 35 ns (SHRES) units
 525	 * Vertical values are in interlaced scanlines
 526	 */
 527
 528#define PAL_DIWSTRT_H	(360)	/* PAL Window Limits */
 529#define PAL_DIWSTRT_V	(48)
 530#define PAL_HTOTAL	(1816)
 531#define PAL_VTOTAL	(625)
 532
 533#define NTSC_DIWSTRT_H	(360)	/* NTSC Window Limits */
 534#define NTSC_DIWSTRT_V	(40)
 535#define NTSC_HTOTAL	(1816)
 536#define NTSC_VTOTAL	(525)
 537
 538
 539	/*
 540	 * Various macros
 541	 */
 542
 543#define up2(v)		(((v)+1) & -2)
 544#define down2(v)	((v) & -2)
 545#define div2(v)		((v)>>1)
 546#define mod2(v)		((v) & 1)
 547
 548#define up4(v)		(((v)+3) & -4)
 549#define down4(v)	((v) & -4)
 550#define mul4(v)		((v)<<2)
 551#define div4(v)		((v)>>2)
 552#define mod4(v)		((v) & 3)
 553
 554#define up8(v)		(((v)+7) & -8)
 555#define down8(v)	((v) & -8)
 556#define div8(v)		((v)>>3)
 557#define mod8(v)		((v) & 7)
 558
 559#define up16(v)		(((v)+15) & -16)
 560#define down16(v)	((v) & -16)
 561#define div16(v)	((v)>>4)
 562#define mod16(v)	((v) & 15)
 563
 564#define up32(v)		(((v)+31) & -32)
 565#define down32(v)	((v) & -32)
 566#define div32(v)	((v)>>5)
 567#define mod32(v)	((v) & 31)
 568
 569#define up64(v)		(((v)+63) & -64)
 570#define down64(v)	((v) & -64)
 571#define div64(v)	((v)>>6)
 572#define mod64(v)	((v) & 63)
 573
 574#define upx(x,v)	(((v)+(x)-1) & -(x))
 575#define downx(x,v)	((v) & -(x))
 576#define modx(x,v)	((v) & ((x)-1))
 577
 578/* if x1 is not a constant, this macro won't make real sense :-) */
 579#ifdef __mc68000__
 580#define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \
 581	"d" (x2), "d" ((long)((x1)/0x100000000ULL)), "0" ((long)(x1))); res;})
 582#else
 583/* We know a bit about the numbers, so we can do it this way */
 584#define DIVUL(x1, x2) ((((long)((unsigned long long)x1 >> 8) / x2) << 8) + \
 585	((((long)((unsigned long long)x1 >> 8) % x2) << 8) / x2))
 586#endif
 587
 588#define highw(x)	((u_long)(x)>>16 & 0xffff)
 589#define loww(x)		((u_long)(x) & 0xffff)
 590
 591#define custom		amiga_custom
 592
 593#define VBlankOn()	custom.intena = IF_SETCLR|IF_COPER
 594#define VBlankOff()	custom.intena = IF_COPER
 595
 596
 597	/*
 598	 * Chip RAM we reserve for the Frame Buffer
 599	 *
 600	 * This defines the Maximum Virtual Screen Size
 601	 * (Setable per kernel options?)
 602	 */
 603
 604#define VIDEOMEMSIZE_AGA_2M	(1310720) /* AGA (2MB) : max 1280*1024*256  */
 605#define VIDEOMEMSIZE_AGA_1M	(786432)  /* AGA (1MB) : max 1024*768*256   */
 606#define VIDEOMEMSIZE_ECS_2M	(655360)  /* ECS (2MB) : max 1280*1024*16   */
 607#define VIDEOMEMSIZE_ECS_1M	(393216)  /* ECS (1MB) : max 1024*768*16    */
 608#define VIDEOMEMSIZE_OCS	(262144)  /* OCS       : max ca. 800*600*16 */
 609
 610#define SPRITEMEMSIZE		(64*64/4) /* max 64*64*4 */
 611#define DUMMYSPRITEMEMSIZE	(8)
 612static u_long spritememory;
 613
 614#define CHIPRAM_SAFETY_LIMIT	(16384)
 615
 616static u_long videomemory;
 617
 618	/*
 619	 * This is the earliest allowed start of fetching display data.
 620	 * Only if you really want no hardware cursor and audio,
 621	 * set this to 128, but let it better at 192
 622	 */
 623
 624static u_long min_fstrt = 192;
 625
 626#define assignchunk(name, type, ptr, size) \
 627{ \
 628	(name) = (type)(ptr); \
 629	ptr += size; \
 630}
 631
 632
 633	/*
 634	 * Copper Instructions
 635	 */
 636
 637#define CMOVE(val, reg)		(CUSTOM_OFS(reg)<<16 | (val))
 638#define CMOVE2(val, reg)	((CUSTOM_OFS(reg)+2)<<16 | (val))
 639#define CWAIT(x, y)		(((y) & 0x1fe)<<23 | ((x) & 0x7f0)<<13 | 0x0001fffe)
 640#define CEND			(0xfffffffe)
 641
 642
 643typedef union {
 644	u_long l;
 645	u_short w[2];
 646} copins;
 647
 648static struct copdisplay {
 649	copins *init;
 650	copins *wait;
 651	copins *list[2][2];
 652	copins *rebuild[2];
 653} copdisplay;
 654
 655static u_short currentcop = 0;
 656
 657	/*
 658	 * Hardware Cursor API Definitions
 659	 * These used to be in linux/fb.h, but were preliminary and used by
 660	 * amifb only anyway
 661	 */
 662
 663#define FBIOGET_FCURSORINFO     0x4607
 664#define FBIOGET_VCURSORINFO     0x4608
 665#define FBIOPUT_VCURSORINFO     0x4609
 666#define FBIOGET_CURSORSTATE     0x460A
 667#define FBIOPUT_CURSORSTATE     0x460B
 668
 669
 670struct fb_fix_cursorinfo {
 671	__u16 crsr_width;		/* width and height of the cursor in */
 672	__u16 crsr_height;		/* pixels (zero if no cursor)	*/
 673	__u16 crsr_xsize;		/* cursor size in display pixels */
 674	__u16 crsr_ysize;
 675	__u16 crsr_color1;		/* colormap entry for cursor color1 */
 676	__u16 crsr_color2;		/* colormap entry for cursor color2 */
 677};
 678
 679struct fb_var_cursorinfo {
 680	__u16 width;
 681	__u16 height;
 682	__u16 xspot;
 683	__u16 yspot;
 684	__u8 data[1];			/* field with [height][width]        */
 685};
 686
 687struct fb_cursorstate {
 688	__s16 xoffset;
 689	__s16 yoffset;
 690	__u16 mode;
 691};
 692
 693#define FB_CURSOR_OFF		0
 694#define FB_CURSOR_ON		1
 695#define FB_CURSOR_FLASH		2
 696
 697
 698	/*
 699	 * Hardware Cursor
 700	 */
 701
 702static int cursorrate = 20;	/* Number of frames/flash toggle */
 703static u_short cursorstate = -1;
 704static u_short cursormode = FB_CURSOR_OFF;
 705
 706static u_short *lofsprite, *shfsprite, *dummysprite;
 707
 708	/*
 709	 * Current Video Mode
 710	 */
 711
 712static struct amifb_par {
 713
 714	/* General Values */
 715
 716	int xres;		/* vmode */
 717	int yres;		/* vmode */
 718	int vxres;		/* vmode */
 719	int vyres;		/* vmode */
 720	int xoffset;		/* vmode */
 721	int yoffset;		/* vmode */
 722	u_short bpp;		/* vmode */
 723	u_short clk_shift;	/* vmode */
 724	u_short line_shift;	/* vmode */
 725	int vmode;		/* vmode */
 726	u_short diwstrt_h;	/* vmode */
 727	u_short diwstop_h;	/* vmode */
 728	u_short diwstrt_v;	/* vmode */
 729	u_short diwstop_v;	/* vmode */
 730	u_long next_line;	/* modulo for next line */
 731	u_long next_plane;	/* modulo for next plane */
 732
 733	/* Cursor Values */
 734
 735	struct {
 736		short crsr_x;	/* movecursor */
 737		short crsr_y;	/* movecursor */
 738		short spot_x;
 739		short spot_y;
 740		u_short height;
 741		u_short width;
 742		u_short fmode;
 743	} crsr;
 744
 745	/* OCS Hardware Registers */
 746
 747	u_long bplpt0;		/* vmode, pan (Note: physical address) */
 748	u_long bplpt0wrap;	/* vmode, pan (Note: physical address) */
 749	u_short ddfstrt;
 750	u_short ddfstop;
 751	u_short bpl1mod;
 752	u_short bpl2mod;
 753	u_short bplcon0;	/* vmode */
 754	u_short bplcon1;	/* vmode */
 755	u_short htotal;		/* vmode */
 756	u_short vtotal;		/* vmode */
 757
 758	/* Additional ECS Hardware Registers */
 759
 760	u_short bplcon3;	/* vmode */
 761	u_short beamcon0;	/* vmode */
 762	u_short hsstrt;		/* vmode */
 763	u_short hsstop;		/* vmode */
 764	u_short hbstrt;		/* vmode */
 765	u_short hbstop;		/* vmode */
 766	u_short vsstrt;		/* vmode */
 767	u_short vsstop;		/* vmode */
 768	u_short vbstrt;		/* vmode */
 769	u_short vbstop;		/* vmode */
 770	u_short hcenter;	/* vmode */
 771
 772	/* Additional AGA Hardware Registers */
 773
 774	u_short fmode;		/* vmode */
 775} currentpar;
 776
 777
 778static struct fb_info fb_info = {
 779    .fix = {
 780	.id		= "Amiga ",
 781	.visual		= FB_VISUAL_PSEUDOCOLOR,
 782	.accel		= FB_ACCEL_AMIGABLITT
 783    }
 784};
 785
 786
 787	/*
 788	 *  Saved color entry 0 so we can restore it when unblanking
 789	 */
 790
 791static u_char red0, green0, blue0;
 792
 793
 794#if defined(CONFIG_FB_AMIGA_ECS)
 795static u_short ecs_palette[32];
 796#endif
 797
 798
 799	/*
 800	 * Latches for Display Changes during VBlank
 801	 */
 802
 803static u_short do_vmode_full = 0;	/* Change the Video Mode */
 804static u_short do_vmode_pan = 0;	/* Update the Video Mode */
 805static short do_blank = 0;		/* (Un)Blank the Screen (±1) */
 806static u_short do_cursor = 0;		/* Move the Cursor */
 807
 808
 809	/*
 810	 * Various Flags
 811	 */
 812
 813static u_short is_blanked = 0;		/* Screen is Blanked */
 814static u_short is_lace = 0;		/* Screen is laced */
 815
 816	/*
 817	 * Predefined Video Modes
 818	 *
 819	 */
 820
 821static struct fb_videomode ami_modedb[] __initdata = {
 822
 823    /*
 824     *  AmigaOS Video Modes
 825     *
 826     *  If you change these, make sure to update DEFMODE_* as well!
 827     */
 828
 829    {
 830	/* 640x200, 15 kHz, 60 Hz (NTSC) */
 831	"ntsc", 60, 640, 200, TAG_HIRES, 106, 86, 44, 16, 76, 2,
 832	FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 833    }, {
 834	/* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
 835	"ntsc-lace", 60, 640, 400, TAG_HIRES, 106, 86, 88, 33, 76, 4,
 836	FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
 837    }, {
 838	/* 640x256, 15 kHz, 50 Hz (PAL) */
 839	"pal", 50, 640, 256, TAG_HIRES, 106, 86, 40, 14, 76, 2,
 840	FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 841    }, {
 842	/* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
 843	"pal-lace", 50, 640, 512, TAG_HIRES, 106, 86, 80, 29, 76, 4,
 844	FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
 845    }, {
 846	/* 640x480, 29 kHz, 57 Hz */
 847	"multiscan", 57, 640, 480, TAG_SHRES, 96, 112, 29, 8, 72, 8,
 848	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 849    }, {
 850	/* 640x960, 29 kHz, 57 Hz interlaced */
 851	"multiscan-lace", 57, 640, 960, TAG_SHRES, 96, 112, 58, 16, 72, 16,
 852	0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
 853    }, {
 854	/* 640x200, 15 kHz, 72 Hz */
 855	"euro36", 72, 640, 200, TAG_HIRES, 92, 124, 6, 6, 52, 5,
 856	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 857    }, {
 858	/* 640x400, 15 kHz, 72 Hz interlaced */
 859	"euro36-lace", 72, 640, 400, TAG_HIRES, 92, 124, 12, 12, 52, 10,
 860	0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
 861    }, {
 862	/* 640x400, 29 kHz, 68 Hz */
 863	"euro72", 68, 640, 400, TAG_SHRES, 164, 92, 9, 9, 80, 8,
 864	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 865    }, {
 866	/* 640x800, 29 kHz, 68 Hz interlaced */
 867	"euro72-lace", 68, 640, 800, TAG_SHRES, 164, 92, 18, 18, 80, 16,
 868	0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
 869    }, {
 870	/* 800x300, 23 kHz, 70 Hz */
 871	"super72", 70, 800, 300, TAG_SHRES, 212, 140, 10, 11, 80, 7,
 872	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 873    }, {
 874	/* 800x600, 23 kHz, 70 Hz interlaced */
 875	"super72-lace", 70, 800, 600, TAG_SHRES, 212, 140, 20, 22, 80, 14,
 876	0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
 877    }, {
 878	/* 640x200, 27 kHz, 57 Hz doublescan */
 879	"dblntsc", 57, 640, 200, TAG_SHRES, 196, 124, 18, 17, 80, 4,
 880	0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
 881    }, {
 882	/* 640x400, 27 kHz, 57 Hz */
 883	"dblntsc-ff", 57, 640, 400, TAG_SHRES, 196, 124, 36, 35, 80, 7,
 884	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 885    }, {
 886	/* 640x800, 27 kHz, 57 Hz interlaced */
 887	"dblntsc-lace", 57, 640, 800, TAG_SHRES, 196, 124, 72, 70, 80, 14,
 888	0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
 889    }, {
 890	/* 640x256, 27 kHz, 47 Hz doublescan */
 891	"dblpal", 47, 640, 256, TAG_SHRES, 196, 124, 14, 13, 80, 4,
 892	0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
 893    }, {
 894	/* 640x512, 27 kHz, 47 Hz */
 895	"dblpal-ff", 47, 640, 512, TAG_SHRES, 196, 124, 28, 27, 80, 7,
 896	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 897    }, {
 898	/* 640x1024, 27 kHz, 47 Hz interlaced */
 899	"dblpal-lace", 47, 640, 1024, TAG_SHRES, 196, 124, 56, 54, 80, 14,
 900	0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
 901    },
 902
 903    /*
 904     *  VGA Video Modes
 905     */
 906
 907    {
 908	/* 640x480, 31 kHz, 60 Hz (VGA) */
 909	"vga", 60, 640, 480, TAG_SHRES, 64, 96, 30, 9, 112, 2,
 910	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 911    }, {
 912	/* 640x400, 31 kHz, 70 Hz (VGA) */
 913	"vga70", 70, 640, 400, TAG_SHRES, 64, 96, 35, 12, 112, 2,
 914	FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 915    },
 916
 917#if 0
 918
 919    /*
 920     *  A2024 video modes
 921     *  These modes don't work yet because there's no A2024 driver.
 922     */
 923
 924    {
 925	/* 1024x800, 10 Hz */
 926	"a2024-10", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
 927	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 928    }, {
 929	/* 1024x800, 15 Hz */
 930	"a2024-15", 15, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
 931	0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
 932    }
 933#endif
 934};
 935
 936#define NUM_TOTAL_MODES  ARRAY_SIZE(ami_modedb)
 937
 938static char *mode_option __initdata = NULL;
 939static int round_down_bpp = 1;	/* for mode probing */
 940
 941	/*
 942	 * Some default modes
 943	 */
 944
 945
 946#define DEFMODE_PAL	    2	/* "pal" for PAL OCS/ECS */
 947#define DEFMODE_NTSC	    0	/* "ntsc" for NTSC OCS/ECS */
 948#define DEFMODE_AMBER_PAL   3	/* "pal-lace" for flicker fixed PAL (A3000) */
 949#define DEFMODE_AMBER_NTSC  1	/* "ntsc-lace" for flicker fixed NTSC (A3000) */
 950#define DEFMODE_AGA	    19	/* "vga70" for AGA */
 951
 952
 953static int amifb_ilbm = 0;	/* interleaved or normal bitplanes */
 954static int amifb_inverse = 0;
 955
 956
 957	/*
 958	 * Macros for the conversion from real world values to hardware register
 959	 * values
 960	 *
 961	 * This helps us to keep our attention on the real stuff...
 962	 *
 963	 * Hardware limits for AGA:
 964	 *
 965	 *	parameter  min    max  step
 966	 *	---------  ---   ----  ----
 967	 *	diwstrt_h    0   2047     1
 968	 *	diwstrt_v    0   2047     1
 969	 *	diwstop_h    0   4095     1
 970	 *	diwstop_v    0   4095     1
 971	 *
 972	 *	ddfstrt      0   2032    16
 973	 *	ddfstop      0   2032    16
 974	 *
 975	 *	htotal       8   2048     8
 976	 *	hsstrt       0   2040     8
 977	 *	hsstop       0   2040     8
 978	 *	vtotal       1   4096     1
 979	 *	vsstrt       0   4095     1
 980	 *	vsstop       0   4095     1
 981	 *	hcenter      0   2040     8
 982	 *
 983	 *	hbstrt       0   2047     1
 984	 *	hbstop       0   2047     1
 985	 *	vbstrt       0   4095     1
 986	 *	vbstop       0   4095     1
 987	 *
 988	 * Horizontal values are in 35 ns (SHRES) pixels
 989	 * Vertical values are in half scanlines
 990	 */
 991
 992/* bplcon1 (smooth scrolling) */
 993
 994#define hscroll2hw(hscroll) \
 995	(((hscroll)<<12 & 0x3000) | ((hscroll)<<8 & 0xc300) | \
 996	 ((hscroll)<<4 & 0x0c00) | ((hscroll)<<2 & 0x00f0) | ((hscroll)>>2 & 0x000f))
 997
 998/* diwstrt/diwstop/diwhigh (visible display window) */
 999
1000#define diwstrt2hw(diwstrt_h, diwstrt_v) \
1001	(((diwstrt_v)<<7 & 0xff00) | ((diwstrt_h)>>2 & 0x00ff))
1002#define diwstop2hw(diwstop_h, diwstop_v) \
1003	(((diwstop_v)<<7 & 0xff00) | ((diwstop_h)>>2 & 0x00ff))
1004#define diwhigh2hw(diwstrt_h, diwstrt_v, diwstop_h, diwstop_v) \
1005	(((diwstop_h)<<3 & 0x2000) | ((diwstop_h)<<11 & 0x1800) | \
1006	 ((diwstop_v)>>1 & 0x0700) | ((diwstrt_h)>>5 & 0x0020) | \
1007	 ((diwstrt_h)<<3 & 0x0018) | ((diwstrt_v)>>9 & 0x0007))
1008
1009/* ddfstrt/ddfstop (display DMA) */
1010
1011#define ddfstrt2hw(ddfstrt)	div8(ddfstrt)
1012#define ddfstop2hw(ddfstop)	div8(ddfstop)
1013
1014/* hsstrt/hsstop/htotal/vsstrt/vsstop/vtotal/hcenter (sync timings) */
1015
1016#define hsstrt2hw(hsstrt)	(div8(hsstrt))
1017#define hsstop2hw(hsstop)	(div8(hsstop))
1018#define htotal2hw(htotal)	(div8(htotal)-1)
1019#define vsstrt2hw(vsstrt)	(div2(vsstrt))
1020#define vsstop2hw(vsstop)	(div2(vsstop))
1021#define vtotal2hw(vtotal)	(div2(vtotal)-1)
1022#define hcenter2hw(htotal)	(div8(htotal))
1023
1024/* hbstrt/hbstop/vbstrt/vbstop (blanking timings) */
1025
1026#define hbstrt2hw(hbstrt)	(((hbstrt)<<8 & 0x0700) | ((hbstrt)>>3 & 0x00ff))
1027#define hbstop2hw(hbstop)	(((hbstop)<<8 & 0x0700) | ((hbstop)>>3 & 0x00ff))
1028#define vbstrt2hw(vbstrt)	(div2(vbstrt))
1029#define vbstop2hw(vbstop)	(div2(vbstop))
1030
1031/* colour */
1032
1033#define rgb2hw8_high(red, green, blue) \
1034	(((red & 0xf0)<<4) | (green & 0xf0) | ((blue & 0xf0)>>4))
1035#define rgb2hw8_low(red, green, blue) \
1036	(((red & 0x0f)<<8) | ((green & 0x0f)<<4) | (blue & 0x0f))
1037#define rgb2hw4(red, green, blue) \
1038	(((red & 0xf0)<<4) | (green & 0xf0) | ((blue & 0xf0)>>4))
1039#define rgb2hw2(red, green, blue) \
1040	(((red & 0xc0)<<4) | (green & 0xc0) | ((blue & 0xc0)>>4))
1041
1042/* sprpos/sprctl (sprite positioning) */
1043
1044#define spr2hw_pos(start_v, start_h) \
1045	(((start_v)<<7&0xff00) | ((start_h)>>3&0x00ff))
1046#define spr2hw_ctl(start_v, start_h, stop_v) \
1047	(((stop_v)<<7&0xff00) | ((start_v)>>4&0x0040) | ((stop_v)>>5&0x0020) | \
1048	 ((start_h)<<3&0x0018) | ((start_v)>>7&0x0004) | ((stop_v)>>8&0x0002) | \
1049	 ((start_h)>>2&0x0001))
1050
1051/* get current vertical position of beam */
1052#define get_vbpos()	((u_short)((*(u_long volatile *)&custom.vposr >> 7) & 0xffe))
1053
1054	/*
1055	 * Copper Initialisation List
1056	 */
1057
1058#define COPINITSIZE (sizeof(copins)*40)
1059
1060enum {
1061	cip_bplcon0
1062};
1063
1064	/*
1065	 * Long Frame/Short Frame Copper List
1066	 * Don't change the order, build_copper()/rebuild_copper() rely on this
1067	 */
1068
1069#define COPLISTSIZE (sizeof(copins)*64)
1070
1071enum {
1072	cop_wait, cop_bplcon0,
1073	cop_spr0ptrh, cop_spr0ptrl,
1074	cop_diwstrt, cop_diwstop,
1075	cop_diwhigh,
1076};
1077
1078	/*
1079	 * Pixel modes for Bitplanes and Sprites
1080	 */
1081
1082static u_short bplpixmode[3] = {
1083	BPC0_SHRES,			/*  35 ns */
1084	BPC0_HIRES,			/*  70 ns */
1085	0				/* 140 ns */
1086};
1087
1088static u_short sprpixmode[3] = {
1089	BPC3_SPRES1 | BPC3_SPRES0,	/*  35 ns */
1090	BPC3_SPRES1,			/*  70 ns */
1091	BPC3_SPRES0			/* 140 ns */
1092};
1093
1094	/*
1095	 * Fetch modes for Bitplanes and Sprites
1096	 */
1097
1098static u_short bplfetchmode[3] = {
1099	0,				/* 1x */
1100	FMODE_BPL32,			/* 2x */
1101	FMODE_BPAGEM | FMODE_BPL32	/* 4x */
1102};
1103
1104static u_short sprfetchmode[3] = {
1105	0,				/* 1x */
1106	FMODE_SPR32,			/* 2x */
1107	FMODE_SPAGEM | FMODE_SPR32	/* 4x */
1108};
1109
1110
1111	/*
1112	 * Interface used by the world
1113	 */
1114
1115int amifb_setup(char*);
1116
1117static int amifb_check_var(struct fb_var_screeninfo *var,
1118			   struct fb_info *info);
1119static int amifb_set_par(struct fb_info *info);
1120static int amifb_setcolreg(unsigned regno, unsigned red, unsigned green,
1121			   unsigned blue, unsigned transp,
1122			   struct fb_info *info);
1123static int amifb_blank(int blank, struct fb_info *info);
1124static int amifb_pan_display(struct fb_var_screeninfo *var,
1125			     struct fb_info *info);
1126static void amifb_fillrect(struct fb_info *info,
1127			   const struct fb_fillrect *rect);
1128static void amifb_copyarea(struct fb_info *info,
1129			   const struct fb_copyarea *region);
1130static void amifb_imageblit(struct fb_info *info,
1131			    const struct fb_image *image);
1132static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
1133
1134
1135	/*
1136	 * Interface to the low level console driver
1137	 */
1138
1139static void amifb_deinit(struct platform_device *pdev);
1140
1141	/*
1142	 * Internal routines
1143	 */
1144
1145static int flash_cursor(void);
1146static irqreturn_t amifb_interrupt(int irq, void *dev_id);
1147static u_long chipalloc(u_long size);
1148static void chipfree(void);
1149
1150	/*
1151	 * Hardware routines
1152	 */
1153
1154static int ami_decode_var(struct fb_var_screeninfo *var,
1155                          struct amifb_par *par);
1156static int ami_encode_var(struct fb_var_screeninfo *var,
1157                          struct amifb_par *par);
1158static void ami_pan_var(struct fb_var_screeninfo *var);
1159static int ami_update_par(void);
1160static void ami_update_display(void);
1161static void ami_init_display(void);
1162static void ami_do_blank(void);
1163static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix);
1164static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
1165static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
1166static int ami_get_cursorstate(struct fb_cursorstate *state);
1167static int ami_set_cursorstate(struct fb_cursorstate *state);
1168static void ami_set_sprite(void);
1169static void ami_init_copper(void);
1170static void ami_reinit_copper(void);
1171static void ami_build_copper(void);
1172static void ami_rebuild_copper(void);
1173
1174
1175static struct fb_ops amifb_ops = {
1176	.owner		= THIS_MODULE,
1177	.fb_check_var	= amifb_check_var,
1178	.fb_set_par	= amifb_set_par,
1179	.fb_setcolreg	= amifb_setcolreg,
1180	.fb_blank	= amifb_blank,
1181	.fb_pan_display	= amifb_pan_display,
1182	.fb_fillrect	= amifb_fillrect,
1183	.fb_copyarea	= amifb_copyarea,
1184	.fb_imageblit	= amifb_imageblit,
1185	.fb_ioctl	= amifb_ioctl,
1186};
1187
1188static void __init amifb_setup_mcap(char *spec)
1189{
1190	char *p;
1191	int vmin, vmax, hmin, hmax;
1192
1193	/* Format for monitor capabilities is: <Vmin>;<Vmax>;<Hmin>;<Hmax>
1194	 * <V*> vertical freq. in Hz
1195	 * <H*> horizontal freq. in kHz
1196	 */
1197
1198	if (!(p = strsep(&spec, ";")) || !*p)
1199		return;
1200	vmin = simple_strtoul(p, NULL, 10);
1201	if (vmin <= 0)
1202		return;
1203	if (!(p = strsep(&spec, ";")) || !*p)
1204		return;
1205	vmax = simple_strtoul(p, NULL, 10);
1206	if (vmax <= 0 || vmax <= vmin)
1207		return;
1208	if (!(p = strsep(&spec, ";")) || !*p)
1209		return;
1210	hmin = 1000 * simple_strtoul(p, NULL, 10);
1211	if (hmin <= 0)
1212		return;
1213	if (!(p = strsep(&spec, "")) || !*p)
1214		return;
1215	hmax = 1000 * simple_strtoul(p, NULL, 10);
1216	if (hmax <= 0 || hmax <= hmin)
1217		return;
1218
1219	fb_info.monspecs.vfmin = vmin;
1220	fb_info.monspecs.vfmax = vmax;
1221	fb_info.monspecs.hfmin = hmin;
1222	fb_info.monspecs.hfmax = hmax;
1223}
1224
1225int __init amifb_setup(char *options)
1226{
1227	char *this_opt;
1228
1229	if (!options || !*options)
1230		return 0;
1231
1232	while ((this_opt = strsep(&options, ",")) != NULL) {
1233		if (!*this_opt)
1234			continue;
1235		if (!strcmp(this_opt, "inverse")) {
1236			amifb_inverse = 1;
1237			fb_invert_cmaps();
1238		} else if (!strcmp(this_opt, "ilbm"))
1239			amifb_ilbm = 1;
1240		else if (!strncmp(this_opt, "monitorcap:", 11))
1241			amifb_setup_mcap(this_opt+11);
1242		else if (!strncmp(this_opt, "fstart:", 7))
1243			min_fstrt = simple_strtoul(this_opt+7, NULL, 0);
1244		else
1245			mode_option = this_opt;
1246	}
1247
1248	if (min_fstrt < 48)
1249		min_fstrt = 48;
1250
1251	return 0;
1252}
1253
1254
1255static int amifb_check_var(struct fb_var_screeninfo *var,
1256			   struct fb_info *info)
1257{
1258	int err;
1259	struct amifb_par par;
1260
1261	/* Validate wanted screen parameters */
1262	if ((err = ami_decode_var(var, &par)))
1263		return err;
1264
1265	/* Encode (possibly rounded) screen parameters */
1266	ami_encode_var(var, &par);
1267	return 0;
1268}
1269
1270
1271static int amifb_set_par(struct fb_info *info)
1272{
1273	struct amifb_par *par = (struct amifb_par *)info->par;
1274
1275	do_vmode_pan = 0;
1276	do_vmode_full = 0;
1277
1278	/* Decode wanted screen parameters */
1279	ami_decode_var(&info->var, par);
1280
1281	/* Set new videomode */
1282	ami_build_copper();
1283
1284	/* Set VBlank trigger */
1285	do_vmode_full = 1;
1286
1287	/* Update fix for new screen parameters */
1288	if (par->bpp == 1) {
1289		info->fix.type = FB_TYPE_PACKED_PIXELS;
1290		info->fix.type_aux = 0;
1291	} else if (amifb_ilbm) {
1292		info->fix.type = FB_TYPE_INTERLEAVED_PLANES;
1293		info->fix.type_aux = par->next_line;
1294	} else {
1295		info->fix.type = FB_TYPE_PLANES;
1296		info->fix.type_aux = 0;
1297	}
1298	info->fix.line_length = div8(upx(16<<maxfmode, par->vxres));
1299
1300	if (par->vmode & FB_VMODE_YWRAP) {
1301		info->fix.ywrapstep = 1;
1302		info->fix.xpanstep = 0;
1303		info->fix.ypanstep = 0;
1304		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YWRAP |
1305		    FBINFO_READS_FAST; /* override SCROLL_REDRAW */
1306	} else {
1307		info->fix.ywrapstep = 0;
1308		if (par->vmode & FB_VMODE_SMOOTH_XPAN)
1309			info->fix.xpanstep = 1;
1310		else
1311			info->fix.xpanstep = 16<<maxfmode;
1312		info->fix.ypanstep = 1;
1313		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1314	}
1315	return 0;
1316}
1317
1318
1319	/*
1320	 * Pan or Wrap the Display
1321	 *
1322	 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1323	 */
1324
1325static int amifb_pan_display(struct fb_var_screeninfo *var,
1326			     struct fb_info *info)
1327{
1328	if (var->vmode & FB_VMODE_YWRAP) {
1329		if (var->yoffset < 0 ||
1330		    var->yoffset >= info->var.yres_virtual || var->xoffset)
1331			return -EINVAL;
1332	} else {
1333		/*
1334		 * TODO: There will be problems when xpan!=1, so some columns
1335		 * on the right side will never be seen
1336		 */
1337		if (var->xoffset+info->var.xres > upx(16<<maxfmode, info->var.xres_virtual) ||
1338		    var->yoffset+info->var.yres > info->var.yres_virtual)
1339			return -EINVAL;
1340	}
1341	ami_pan_var(var);
1342	info->var.xoffset = var->xoffset;
1343	info->var.yoffset = var->yoffset;
1344	if (var->vmode & FB_VMODE_YWRAP)
1345		info->var.vmode |= FB_VMODE_YWRAP;
1346	else
1347		info->var.vmode &= ~FB_VMODE_YWRAP;
1348	return 0;
1349}
1350
1351
1352#if BITS_PER_LONG == 32
1353#define BYTES_PER_LONG	4
1354#define SHIFT_PER_LONG	5
1355#elif BITS_PER_LONG == 64
1356#define BYTES_PER_LONG	8
1357#define SHIFT_PER_LONG	6
1358#else
1359#define Please update me
1360#endif
1361
1362
1363    /*
1364     *  Compose two values, using a bitmask as decision value
1365     *  This is equivalent to (a & mask) | (b & ~mask)
1366     */
1367
1368static inline unsigned long comp(unsigned long a, unsigned long b,
1369				 unsigned long mask)
1370{
1371	return ((a ^ b) & mask) ^ b;
1372}
1373
1374
1375static inline unsigned long xor(unsigned long a, unsigned long b,
1376				unsigned long mask)
1377{
1378	return (a & mask) ^ b;
1379}
1380
1381
1382    /*
1383     *  Unaligned forward bit copy using 32-bit or 64-bit memory accesses
1384     */
1385
1386static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
1387		   int src_idx, u32 n)
1388{
1389	unsigned long first, last;
1390	int shift = dst_idx-src_idx, left, right;
1391	unsigned long d0, d1;
1392	int m;
1393
1394	if (!n)
1395		return;
1396
1397	shift = dst_idx-src_idx;
1398	first = ~0UL >> dst_idx;
1399	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
1400
1401	if (!shift) {
1402		// Same alignment for source and dest
1403
1404		if (dst_idx+n <= BITS_PER_LONG) {
1405			// Single word
1406			if (last)
1407				first &= last;
1408			*dst = comp(*src, *dst, first);
1409		} else {
1410			// Multiple destination words
1411			// Leading bits
1412			if (first) {
1413				*dst = comp(*src, *dst, first);
1414				dst++;
1415				src++;
1416				n -= BITS_PER_LONG-dst_idx;
1417			}
1418
1419			// Main chunk
1420			n /= BITS_PER_LONG;
1421			while (n >= 8) {
1422				*dst++ = *src++;
1423				*dst++ = *src++;
1424				*dst++ = *src++;
1425				*dst++ = *src++;
1426				*dst++ = *src++;
1427				*dst++ = *src++;
1428				*dst++ = *src++;
1429				*dst++ = *src++;
1430				n -= 8;
1431			}
1432			while (n--)
1433				*dst++ = *src++;
1434
1435			// Trailing bits
1436			if (last)
1437				*dst = comp(*src, *dst, last);
1438		}
1439	} else {
1440		// Different alignment for source and dest
1441
1442		right = shift & (BITS_PER_LONG-1);
1443		left = -shift & (BITS_PER_LONG-1);
1444
1445		if (dst_idx+n <= BITS_PER_LONG) {
1446			// Single destination word
1447			if (last)
1448				first &= last;
1449			if (shift > 0) {
1450				// Single source word
1451				*dst = comp(*src >> right, *dst, first);
1452			} else if (src_idx+n <= BITS_PER_LONG) {
1453				// Single source word
1454				*dst = comp(*src << left, *dst, first);
1455			} else {
1456				// 2 source words
1457				d0 = *src++;
1458				d1 = *src;
1459				*dst = comp(d0 << left | d1 >> right, *dst,
1460					    first);
1461			}
1462		} else {
1463			// Multiple destination words
1464			d0 = *src++;
1465			// Leading bits
1466			if (shift > 0) {
1467				// Single source word
1468				*dst = comp(d0 >> right, *dst, first);
1469				dst++;
1470				n -= BITS_PER_LONG-dst_idx;
1471			} else {
1472				// 2 source words
1473				d1 = *src++;
1474				*dst = comp(d0 << left | d1 >> right, *dst,
1475					    first);
1476				d0 = d1;
1477				dst++;
1478				n -= BITS_PER_LONG-dst_idx;
1479			}
1480
1481			// Main chunk
1482			m = n % BITS_PER_LONG;
1483			n /= BITS_PER_LONG;
1484			while (n >= 4) {
1485				d1 = *src++;
1486				*dst++ = d0 << left | d1 >> right;
1487				d0 = d1;
1488				d1 = *src++;
1489				*dst++ = d0 << left | d1 >> right;
1490				d0 = d1;
1491				d1 = *src++;
1492				*dst++ = d0 << left | d1 >> right;
1493				d0 = d1;
1494				d1 = *src++;
1495				*dst++ = d0 << left | d1 >> right;
1496				d0 = d1;
1497				n -= 4;
1498			}
1499			while (n--) {
1500				d1 = *src++;
1501				*dst++ = d0 << left | d1 >> right;
1502				d0 = d1;
1503			}
1504
1505			// Trailing bits
1506			if (last) {
1507				if (m <= right) {
1508					// Single source word
1509					*dst = comp(d0 << left, *dst, last);
1510				} else {
1511					// 2 source words
1512					d1 = *src;
1513					*dst = comp(d0 << left | d1 >> right,
1514						    *dst, last);
1515				}
1516			}
1517		}
1518	}
1519}
1520
1521
1522    /*
1523     *  Unaligned reverse bit copy using 32-bit or 64-bit memory accesses
1524     */
1525
1526static void bitcpy_rev(unsigned long *dst, int dst_idx,
1527		       const unsigned long *src, int src_idx, u32 n)
1528{
1529	unsigned long first, last;
1530	int shift = dst_idx-src_idx, left, right;
1531	unsigned long d0, d1;
1532	int m;
1533
1534	if (!n)
1535		return;
1536
1537	dst += (n-1)/BITS_PER_LONG;
1538	src += (n-1)/BITS_PER_LONG;
1539	if ((n-1) % BITS_PER_LONG) {
1540		dst_idx += (n-1) % BITS_PER_LONG;
1541		dst += dst_idx >> SHIFT_PER_LONG;
1542		dst_idx &= BITS_PER_LONG-1;
1543		src_idx += (n-1) % BITS_PER_LONG;
1544		src += src_idx >> SHIFT_PER_LONG;
1545		src_idx &= BITS_PER_LONG-1;
1546	}
1547
1548	shift = dst_idx-src_idx;
1549	first = ~0UL << (BITS_PER_LONG-1-dst_idx);
1550	last = ~(~0UL << (BITS_PER_LONG-1-((dst_idx-n) % BITS_PER_LONG)));
1551
1552	if (!shift) {
1553		// Same alignment for source and dest
1554
1555		if ((unsigned long)dst_idx+1 >= n) {
1556			// Single word
1557			if (last)
1558				first &= last;
1559			*dst = comp(*src, *dst, first);
1560		} else {
1561			// Multiple destination words
1562			// Leading bits
1563			if (first) {
1564				*dst = comp(*src, *dst, first);
1565				dst--;
1566				src--;
1567				n -= dst_idx+1;
1568			}
1569
1570			// Main chunk
1571			n /= BITS_PER_LONG;
1572			while (n >= 8) {
1573				*dst-- = *src--;
1574				*dst-- = *src--;
1575				*dst-- = *src--;
1576				*dst-- = *src--;
1577				*dst-- = *src--;
1578				*dst-- = *src--;
1579				*dst-- = *src--;
1580				*dst-- = *src--;
1581				n -= 8;
1582			}
1583			while (n--)
1584				*dst-- = *src--;
1585
1586			// Trailing bits
1587			if (last)
1588				*dst = comp(*src, *dst, last);
1589		}
1590	} else {
1591		// Different alignment for source and dest
1592
1593		right = shift & (BITS_PER_LONG-1);
1594		left = -shift & (BITS_PER_LONG-1);
1595
1596		if ((unsigned long)dst_idx+1 >= n) {
1597			// Single destination word
1598			if (last)
1599				first &= last;
1600			if (shift < 0) {
1601				// Single source word
1602				*dst = comp(*src << left, *dst, first);
1603			} else if (1+(unsigned long)src_idx >= n) {
1604				// Single source word
1605				*dst = comp(*src >> right, *dst, first);
1606			} else {
1607				// 2 source words
1608				d0 = *src--;
1609				d1 = *src;
1610				*dst = comp(d0 >> right | d1 << left, *dst,
1611					    first);
1612			}
1613		} else {
1614			// Multiple destination words
1615			d0 = *src--;
1616			// Leading bits
1617			if (shift < 0) {
1618				// Single source word
1619				*dst = comp(d0 << left, *dst, first);
1620				dst--;
1621				n -= dst_idx+1;
1622			} else {
1623				// 2 source words
1624				d1 = *src--;
1625				*dst = comp(d0 >> right | d1 << left, *dst,
1626					    first);
1627				d0 = d1;
1628				dst--;
1629				n -= dst_idx+1;
1630			}
1631
1632			// Main chunk
1633			m = n % BITS_PER_LONG;
1634			n /= BITS_PER_LONG;
1635			while (n >= 4) {
1636				d1 = *src--;
1637				*dst-- = d0 >> right | d1 << left;
1638				d0 = d1;
1639				d1 = *src--;
1640				*dst-- = d0 >> right | d1 << left;
1641				d0 = d1;
1642				d1 = *src--;
1643				*dst-- = d0 >> right | d1 << left;
1644				d0 = d1;
1645				d1 = *src--;
1646				*dst-- = d0 >> right | d1 << left;
1647				d0 = d1;
1648				n -= 4;
1649			}
1650			while (n--) {
1651				d1 = *src--;
1652				*dst-- = d0 >> right | d1 << left;
1653				d0 = d1;
1654			}
1655
1656			// Trailing bits
1657			if (last) {
1658				if (m <= left) {
1659					// Single source word
1660					*dst = comp(d0 >> right, *dst, last);
1661				} else {
1662					// 2 source words
1663					d1 = *src;
1664					*dst = comp(d0 >> right | d1 << left,
1665						    *dst, last);
1666				}
1667			}
1668		}
1669	}
1670}
1671
1672
1673    /*
1674     *  Unaligned forward inverting bit copy using 32-bit or 64-bit memory
1675     *  accesses
1676     */
1677
1678static void bitcpy_not(unsigned long *dst, int dst_idx,
1679		       const unsigned long *src, int src_idx, u32 n)
1680{
1681	unsigned long first, last;
1682	int shift = dst_idx-src_idx, left, right;
1683	unsigned long d0, d1;
1684	int m;
1685
1686	if (!n)
1687		return;
1688
1689	shift = dst_idx-src_idx;
1690	first = ~0UL >> dst_idx;
1691	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
1692
1693	if (!shift) {
1694		// Same alignment for source and dest
1695
1696		if (dst_idx+n <= BITS_PER_LONG) {
1697			// Single word
1698			if (last)
1699				first &= last;
1700			*dst = comp(~*src, *dst, first);
1701		} else {
1702			// Multiple destination words
1703			// Leading bits
1704			if (first) {
1705				*dst = comp(~*src, *dst, first);
1706				dst++;
1707				src++;
1708				n -= BITS_PER_LONG-dst_idx;
1709			}
1710
1711			// Main chunk
1712			n /= BITS_PER_LONG;
1713			while (n >= 8) {
1714				*dst++ = ~*src++;
1715				*dst++ = ~*src++;
1716				*dst++ = ~*src++;
1717				*dst++ = ~*src++;
1718				*dst++ = ~*src++;
1719				*dst++ = ~*src++;
1720				*dst++ = ~*src++;
1721				*dst++ = ~*src++;
1722				n -= 8;
1723			}
1724			while (n--)
1725				*dst++ = ~*src++;
1726
1727			// Trailing bits
1728			if (last)
1729				*dst = comp(~*src, *dst, last);
1730		}
1731	} else {
1732		// Different alignment for source and dest
1733
1734		right = shift & (BITS_PER_LONG-1);
1735		left = -shift & (BITS_PER_LONG-1);
1736
1737		if (dst_idx+n <= BITS_PER_LONG) {
1738			// Single destination word
1739			if (last)
1740				first &= last;
1741			if (shift > 0) {
1742				// Single source word
1743				*dst = comp(~*src >> right, *dst, first);
1744			} else i

Large files files are truncated, but you can click here to view the full file