^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* ffb.c: Creator/Elite3D frame buffer driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Driver layout based loosely on tgafb.c, see that file for credits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/upa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/fbio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "sbuslib.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Local functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static int ffb_setcolreg(unsigned, unsigned, unsigned, unsigned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned, struct fb_info *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int ffb_blank(int, struct fb_info *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static void ffb_imageblit(struct fb_info *, const struct fb_image *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static void ffb_fillrect(struct fb_info *, const struct fb_fillrect *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static void ffb_copyarea(struct fb_info *, const struct fb_copyarea *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int ffb_sync(struct fb_info *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int ffb_mmap(struct fb_info *, struct vm_area_struct *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int ffb_ioctl(struct fb_info *, unsigned int, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static int ffb_pan_display(struct fb_var_screeninfo *, struct fb_info *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Frame buffer operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static const struct fb_ops ffb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .fb_setcolreg = ffb_setcolreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .fb_blank = ffb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .fb_pan_display = ffb_pan_display,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .fb_fillrect = ffb_fillrect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .fb_copyarea = ffb_copyarea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .fb_imageblit = ffb_imageblit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .fb_sync = ffb_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .fb_mmap = ffb_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .fb_ioctl = ffb_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .fb_compat_ioctl = sbusfb_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Register layout and definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define FFB_SFB8R_VOFF 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define FFB_SFB8G_VOFF 0x00400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define FFB_SFB8B_VOFF 0x00800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define FFB_SFB8X_VOFF 0x00c00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define FFB_SFB32_VOFF 0x01000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define FFB_SFB64_VOFF 0x02000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define FFB_FBC_REGS_VOFF 0x04000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define FFB_BM_FBC_REGS_VOFF 0x04002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define FFB_DFB8R_VOFF 0x04004000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define FFB_DFB8G_VOFF 0x04404000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define FFB_DFB8B_VOFF 0x04804000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define FFB_DFB8X_VOFF 0x04c04000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define FFB_DFB24_VOFF 0x05004000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define FFB_DFB32_VOFF 0x06004000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define FFB_DFB422A_VOFF 0x07004000 /* DFB 422 mode write to A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define FFB_DFB422AD_VOFF 0x07804000 /* DFB 422 mode with line doubling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define FFB_DFB24B_VOFF 0x08004000 /* DFB 24bit mode write to B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define FFB_DFB422B_VOFF 0x09004000 /* DFB 422 mode write to B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define FFB_DFB422BD_VOFF 0x09804000 /* DFB 422 mode with line doubling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define FFB_SFB16Z_VOFF 0x0a004000 /* 16bit mode Z planes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define FFB_SFB8Z_VOFF 0x0a404000 /* 8bit mode Z planes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define FFB_SFB422_VOFF 0x0ac04000 /* SFB 422 mode write to A/B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define FFB_SFB422D_VOFF 0x0b404000 /* SFB 422 mode with line doubling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define FFB_FBC_KREGS_VOFF 0x0bc04000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define FFB_DAC_VOFF 0x0bc06000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define FFB_PROM_VOFF 0x0bc08000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define FFB_EXP_VOFF 0x0bc18000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define FFB_SFB8R_POFF 0x04000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define FFB_SFB8G_POFF 0x04400000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define FFB_SFB8B_POFF 0x04800000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define FFB_SFB8X_POFF 0x04c00000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define FFB_SFB32_POFF 0x05000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define FFB_SFB64_POFF 0x06000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define FFB_FBC_REGS_POFF 0x00600000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define FFB_BM_FBC_REGS_POFF 0x00600000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define FFB_DFB8R_POFF 0x01000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define FFB_DFB8G_POFF 0x01400000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define FFB_DFB8B_POFF 0x01800000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define FFB_DFB8X_POFF 0x01c00000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define FFB_DFB24_POFF 0x02000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define FFB_DFB32_POFF 0x03000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define FFB_FBC_KREGS_POFF 0x00610000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define FFB_DAC_POFF 0x00400000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define FFB_PROM_POFF 0x00000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define FFB_EXP_POFF 0x00200000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define FFB_DFB422A_POFF 0x09000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define FFB_DFB422AD_POFF 0x09800000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define FFB_DFB24B_POFF 0x0a000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define FFB_DFB422B_POFF 0x0b000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define FFB_DFB422BD_POFF 0x0b800000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define FFB_SFB16Z_POFF 0x0c800000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define FFB_SFB8Z_POFF 0x0c000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define FFB_SFB422_POFF 0x0d000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define FFB_SFB422D_POFF 0x0d800000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Draw operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define FFB_DRAWOP_DOT 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define FFB_DRAWOP_AADOT 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define FFB_DRAWOP_BRLINECAP 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define FFB_DRAWOP_BRLINEOPEN 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define FFB_DRAWOP_DDLINE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define FFB_DRAWOP_AALINE 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define FFB_DRAWOP_TRIANGLE 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define FFB_DRAWOP_POLYGON 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define FFB_DRAWOP_RECTANGLE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define FFB_DRAWOP_FASTFILL 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define FFB_DRAWOP_BCOPY 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define FFB_DRAWOP_VSCROLL 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* Pixel processor control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Force WID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define FFB_PPC_FW_DISABLE 0x800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define FFB_PPC_FW_ENABLE 0xc00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* Auxiliary clip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define FFB_PPC_ACE_DISABLE 0x040000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define FFB_PPC_ACE_AUX_SUB 0x080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define FFB_PPC_ACE_AUX_ADD 0x0c0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Depth cue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define FFB_PPC_DCE_DISABLE 0x020000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define FFB_PPC_DCE_ENABLE 0x030000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Alpha blend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define FFB_PPC_ABE_DISABLE 0x008000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define FFB_PPC_ABE_ENABLE 0x00c000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* View clip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define FFB_PPC_VCE_DISABLE 0x001000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define FFB_PPC_VCE_2D 0x002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define FFB_PPC_VCE_3D 0x003000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* Area pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define FFB_PPC_APE_DISABLE 0x000800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define FFB_PPC_APE_ENABLE 0x000c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Transparent background */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define FFB_PPC_TBE_OPAQUE 0x000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define FFB_PPC_TBE_TRANSPARENT 0x000300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Z source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define FFB_PPC_ZS_VAR 0x000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define FFB_PPC_ZS_CONST 0x0000c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* Y source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define FFB_PPC_YS_VAR 0x000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define FFB_PPC_YS_CONST 0x000030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* X source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define FFB_PPC_XS_WID 0x000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define FFB_PPC_XS_VAR 0x000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define FFB_PPC_XS_CONST 0x00000c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Color (BGR) source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define FFB_PPC_CS_VAR 0x000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define FFB_PPC_CS_CONST 0x000003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define FFB_ROP_NEW 0x83
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define FFB_ROP_OLD 0x85
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define FFB_ROP_NEW_XOR_OLD 0x86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define FFB_UCSR_FIFO_MASK 0x00000fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define FFB_UCSR_FB_BUSY 0x01000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define FFB_UCSR_RP_BUSY 0x02000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define FFB_UCSR_READ_ERR 0x40000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define FFB_UCSR_FIFO_OVFL 0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define FFB_UCSR_ALL_ERRORS (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct ffb_fbc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* Next vertex registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u32 xxx1[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) u32 alpha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) u32 red;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u32 green;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u32 blue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u32 depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u32 y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u32 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u32 xxx2[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u32 ryf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u32 rxf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u32 xxx3[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u32 dmyf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u32 dmxf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u32 xxx4[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u32 ebyi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 ebxi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u32 xxx5[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u32 by;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u32 bx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u32 dy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u32 dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) u32 bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) u32 bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u32 xxx6[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u32 xxx7[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Setup unit vertex state register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u32 suvtx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) u32 xxx8[63];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) u32 ppc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u32 wid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) u32 fg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u32 bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) u32 consty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) u32 constz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u32 xclip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u32 dcss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u32 vclipmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) u32 vclipmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u32 vclipzmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u32 vclipzmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) u32 dcsf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u32 dcsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) u32 dczf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u32 dczb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u32 xxx9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u32 blendc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) u32 blendc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u32 blendc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u32 fbramitc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) u32 fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) u32 rop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u32 cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u32 matchab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u32 matchc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) u32 magnab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) u32 magnc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) u32 fbcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) u32 fbcfg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 fbcfg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) u32 fbcfg3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u32 ppcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u32 pick;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u32 fillmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) u32 fbramwac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u32 pmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) u32 xpmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) u32 ypmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u32 zpmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) u32 clip0min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u32 clip0max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) u32 clip1min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) u32 clip1max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) u32 clip2min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u32 clip2max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u32 clip3min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u32 clip3max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* New 3dRAM III support regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u32 rawblend2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) u32 rawpreblend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) u32 rawstencil;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u32 rawstencilctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u32 threedram1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) u32 threedram2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u32 passin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) u32 rawclrdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) u32 rawpmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) u32 rawcsrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u32 rawmatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) u32 rawmagn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) u32 rawropblend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) u32 rawcmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) u32 rawwac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) u32 fbramid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) u32 drawop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) u32 xxx10[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) u32 fontlpat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) u32 xxx11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 fontxy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u32 fontw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u32 fontinc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u32 font;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) u32 xxx12[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 blend2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u32 preblend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) u32 stencil;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) u32 stencilctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) u32 xxx13[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u32 dcss1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u32 dcss2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) u32 dcss3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u32 widpmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) u32 dcs2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) u32 dcs3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) u32 dcs4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u32 xxx14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u32 dcd2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) u32 dcd3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) u32 dcd4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) u32 xxx15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) u32 pattern[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u32 xxx16[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) u32 devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) u32 xxx17[63];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) u32 ucsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) u32 xxx18[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) u32 mer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct ffb_dac {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) u32 type2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u32 value2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #define FFB_DAC_UCTRL 0x1001 /* User Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #define FFB_DAC_UCTRL_MANREV 0x00000f00 /* 4-bit Manufacturing Revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #define FFB_DAC_UCTRL_MANREV_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #define FFB_DAC_TGEN 0x6000 /* Timing Generator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #define FFB_DAC_TGEN_VIDE 0x00000001 /* Video Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) #define FFB_DAC_DID 0x8000 /* Device Identification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #define FFB_DAC_DID_PNUM 0x0ffff000 /* Device Part Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #define FFB_DAC_DID_PNUM_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) #define FFB_DAC_DID_REV 0xf0000000 /* Device Revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #define FFB_DAC_DID_REV_SHIFT 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #define FFB_DAC_CUR_CTRL 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) #define FFB_DAC_CUR_CTRL_P0 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #define FFB_DAC_CUR_CTRL_P1 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct ffb_par {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct ffb_fbc __iomem *fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct ffb_dac __iomem *dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) #define FFB_FLAG_AFB 0x00000001 /* AFB m3 or m6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) #define FFB_FLAG_BLANKED 0x00000002 /* screen is blanked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) #define FFB_FLAG_INVCURSOR 0x00000004 /* DAC has inverted cursor logic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) u32 fg_cache __attribute__((aligned (8)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) u32 bg_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u32 rop_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int fifo_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) unsigned long physbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) unsigned long fbsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) int board_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) u32 pseudo_palette[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static void FFBFifo(struct ffb_par *par, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct ffb_fbc __iomem *fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int cache = par->fifo_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (cache - n < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) fbc = par->fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) cache -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) } while (cache - n < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) par->fifo_cache = cache - n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void FFBWait(struct ffb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct ffb_fbc __iomem *fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int limit = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) fbc = par->fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_BUSY) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) } while (--limit > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static int ffb_sync(struct fb_info *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct ffb_par *par = (struct ffb_par *)p->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) FFBWait(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static __inline__ void ffb_rop(struct ffb_par *par, u32 rop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (par->rop_cache != rop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) FFBFifo(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) upa_writel(rop, &par->fbc->rop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) par->rop_cache = rop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static void ffb_switch_from_graph(struct ffb_par *par)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct ffb_fbc __iomem *fbc = par->fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct ffb_dac __iomem *dac = par->dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) spin_lock_irqsave(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) FFBWait(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) par->fifo_cache = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) FFBFifo(par, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) upa_writel(FFB_PPC_VCE_DISABLE | FFB_PPC_TBE_OPAQUE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) &fbc->ppc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) upa_writel(0x2000707f, &fbc->fbc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) upa_writel(par->rop_cache, &fbc->rop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) upa_writel(0xffffffff, &fbc->pmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) upa_writel((1 << 16) | (0 << 0), &fbc->fontinc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) upa_writel(par->fg_cache, &fbc->fg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) upa_writel(par->bg_cache, &fbc->bg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) FFBWait(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /* Disable cursor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) upa_writel(FFB_DAC_CUR_CTRL, &dac->type2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (par->flags & FFB_FLAG_INVCURSOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) upa_writel(0, &dac->value2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) upa_writel((FFB_DAC_CUR_CTRL_P0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) FFB_DAC_CUR_CTRL_P1), &dac->value2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) spin_unlock_irqrestore(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct ffb_par *par = (struct ffb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* We just use this to catch switches out of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * graphics mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ffb_switch_from_graph(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (var->xoffset || var->yoffset || var->vmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * ffb_fillrect - Draws a rectangle on the screen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * @rect: structure defining the rectagle and operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct ffb_par *par = (struct ffb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct ffb_fbc __iomem *fbc = par->fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u32 fg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) BUG_ON(rect->rop != ROP_COPY && rect->rop != ROP_XOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) fg = ((u32 *)info->pseudo_palette)[rect->color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) spin_lock_irqsave(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (fg != par->fg_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) FFBFifo(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) upa_writel(fg, &fbc->fg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) par->fg_cache = fg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ffb_rop(par, rect->rop == ROP_COPY ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) FFB_ROP_NEW :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) FFB_ROP_NEW_XOR_OLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) FFBFifo(par, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) upa_writel(FFB_DRAWOP_RECTANGLE, &fbc->drawop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) upa_writel(rect->dy, &fbc->by);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) upa_writel(rect->dx, &fbc->bx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) upa_writel(rect->height, &fbc->bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) upa_writel(rect->width, &fbc->bw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) spin_unlock_irqrestore(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * ffb_copyarea - Copies on area of the screen to another area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * @area: structure defining the source and destination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static void ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct ffb_par *par = (struct ffb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct ffb_fbc __iomem *fbc = par->fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (area->dx != area->sx ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) area->dy == area->sy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) cfb_copyarea(info, area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) spin_lock_irqsave(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ffb_rop(par, FFB_ROP_OLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) FFBFifo(par, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) upa_writel(FFB_DRAWOP_VSCROLL, &fbc->drawop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) upa_writel(area->sy, &fbc->by);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) upa_writel(area->sx, &fbc->bx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) upa_writel(area->dy, &fbc->dy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) upa_writel(area->dx, &fbc->dx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) upa_writel(area->height, &fbc->bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) upa_writel(area->width, &fbc->bw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) spin_unlock_irqrestore(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * ffb_imageblit - Copies a image from system memory to the screen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * @image: structure defining the image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct ffb_par *par = (struct ffb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct ffb_fbc __iomem *fbc = par->fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) const u8 *data = image->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u32 fg, bg, xy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) u64 fgbg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) int i, width, stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (image->depth > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) cfb_imageblit(info, image);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) fg = ((u32 *)info->pseudo_palette)[image->fg_color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) bg = ((u32 *)info->pseudo_palette)[image->bg_color];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) fgbg = ((u64) fg << 32) | (u64) bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) xy = (image->dy << 16) | image->dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) width = image->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) stride = ((width + 7) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) spin_lock_irqsave(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (fgbg != *(u64 *)&par->fg_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) FFBFifo(par, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) upa_writeq(fgbg, &fbc->fg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) *(u64 *)&par->fg_cache = fgbg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (width >= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) FFBFifo(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) upa_writel(32, &fbc->fontw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) while (width >= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) const u8 *next_data = data + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) FFBFifo(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) upa_writel(xy, &fbc->fontxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) xy += (32 << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) for (i = 0; i < image->height; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) u32 val = (((u32)data[0] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ((u32)data[1] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ((u32)data[2] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ((u32)data[3] << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) FFBFifo(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) upa_writel(val, &fbc->font);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) data += stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) data = next_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) width -= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) FFBFifo(par, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) upa_writel(width, &fbc->fontw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) upa_writel(xy, &fbc->fontxy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) for (i = 0; i < image->height; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) u32 val = (((u32)data[0] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ((u32)data[1] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ((u32)data[2] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ((u32)data[3] << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) FFBFifo(par, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) upa_writel(val, &fbc->font);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) data += stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) spin_unlock_irqrestore(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static void ffb_fixup_var_rgb(struct fb_var_screeninfo *var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) var->red.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) var->red.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) var->green.offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) var->green.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) var->blue.offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) var->blue.length = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) var->transp.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) var->transp.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * ffb_setcolreg - Sets a color register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * @regno: boolean, 0 copy local, 1 get_user() function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * @red: frame buffer colormap structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * @green: The green value which can be up to 16 bits wide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * @blue: The blue value which can be up to 16 bits wide.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * @transp: If supported the alpha value which can be up to 16 bits wide.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * @info: frame buffer info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static int ffb_setcolreg(unsigned regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) unsigned red, unsigned green, unsigned blue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) unsigned transp, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (regno >= 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) red >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) green >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) blue >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) value = (blue << 16) | (green << 8) | red;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ((u32 *)info->pseudo_palette)[regno] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * ffb_blank - Optional function. Blanks the display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * @blank_mode: the blank mode we want.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static int ffb_blank(int blank, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct ffb_par *par = (struct ffb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct ffb_dac __iomem *dac = par->dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) spin_lock_irqsave(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) FFBWait(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) upa_writel(FFB_DAC_TGEN, &dac->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) val = upa_readl(&dac->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) switch (blank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) case FB_BLANK_UNBLANK: /* Unblanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) val |= FFB_DAC_TGEN_VIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) par->flags &= ~FFB_FLAG_BLANKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) case FB_BLANK_NORMAL: /* Normal blanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) case FB_BLANK_POWERDOWN: /* Poweroff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) val &= ~FFB_DAC_TGEN_VIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) par->flags |= FFB_FLAG_BLANKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) upa_writel(FFB_DAC_TGEN, &dac->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) upa_writel(val, &dac->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) for (i = 0; i < 10; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) upa_writel(FFB_DAC_TGEN, &dac->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) upa_readl(&dac->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) spin_unlock_irqrestore(&par->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static struct sbus_mmap_map ffb_mmap_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) .voff = FFB_SFB8R_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) .poff = FFB_SFB8R_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) .size = 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) .voff = FFB_SFB8G_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .poff = FFB_SFB8G_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .size = 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) .voff = FFB_SFB8B_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) .poff = FFB_SFB8B_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) .size = 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .voff = FFB_SFB8X_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) .poff = FFB_SFB8X_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .size = 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .voff = FFB_SFB32_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) .poff = FFB_SFB32_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) .size = 0x1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) .voff = FFB_SFB64_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .poff = FFB_SFB64_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) .size = 0x2000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .voff = FFB_FBC_REGS_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .poff = FFB_FBC_REGS_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .size = 0x0002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .voff = FFB_BM_FBC_REGS_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) .poff = FFB_BM_FBC_REGS_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) .size = 0x0002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .voff = FFB_DFB8R_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .poff = FFB_DFB8R_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .size = 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) .voff = FFB_DFB8G_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .poff = FFB_DFB8G_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .size = 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) .voff = FFB_DFB8B_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .poff = FFB_DFB8B_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .size = 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .voff = FFB_DFB8X_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .poff = FFB_DFB8X_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) .size = 0x0400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .voff = FFB_DFB24_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) .poff = FFB_DFB24_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .size = 0x1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) .voff = FFB_DFB32_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .poff = FFB_DFB32_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) .size = 0x1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .voff = FFB_FBC_KREGS_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) .poff = FFB_FBC_KREGS_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .size = 0x0002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) .voff = FFB_DAC_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .poff = FFB_DAC_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) .size = 0x0002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) .voff = FFB_PROM_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) .poff = FFB_PROM_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) .size = 0x0010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .voff = FFB_EXP_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .poff = FFB_EXP_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .size = 0x0002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) .voff = FFB_DFB422A_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .poff = FFB_DFB422A_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .size = 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) .voff = FFB_DFB422AD_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) .poff = FFB_DFB422AD_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) .size = 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .voff = FFB_DFB24B_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .poff = FFB_DFB24B_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .size = 0x1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .voff = FFB_DFB422B_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) .poff = FFB_DFB422B_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .size = 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .voff = FFB_DFB422BD_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .poff = FFB_DFB422BD_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .size = 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .voff = FFB_SFB16Z_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .poff = FFB_SFB16Z_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) .size = 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .voff = FFB_SFB8Z_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .poff = FFB_SFB8Z_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .size = 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) .voff = FFB_SFB422_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .poff = FFB_SFB422_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .size = 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .voff = FFB_SFB422D_VOFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .poff = FFB_SFB422D_POFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .size = 0x0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) { .size = 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) static int ffb_mmap(struct fb_info *info, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct ffb_par *par = (struct ffb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return sbusfb_mmap_helper(ffb_mmap_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) par->physbase, par->fbsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 0, vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct ffb_par *par = (struct ffb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return sbusfb_ioctl_helper(cmd, arg, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) FBTYPE_CREATOR, 24, par->fbsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) * Initialisation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static void ffb_init_fix(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct ffb_par *par = (struct ffb_par *)info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) const char *ffb_type_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (!(par->flags & FFB_FLAG_AFB)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if ((par->board_type & 0x7) == 0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ffb_type_name = "Creator 3D";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ffb_type_name = "Creator";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ffb_type_name = "Elite 3D";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) strlcpy(info->fix.id, ffb_type_name, sizeof(info->fix.id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) info->fix.type = FB_TYPE_PACKED_PIXELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) info->fix.visual = FB_VISUAL_TRUECOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /* Framebuffer length is the same regardless of resolution. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) info->fix.line_length = 8192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) info->fix.accel = FB_ACCEL_SUN_CREATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) static int ffb_probe(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct device_node *dp = op->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct ffb_fbc __iomem *fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct ffb_dac __iomem *dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct ffb_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) u32 dac_pnum, dac_rev, dac_mrev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) info = framebuffer_alloc(sizeof(struct ffb_par), &op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) spin_lock_init(&par->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) par->fbc = of_ioremap(&op->resource[2], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) sizeof(struct ffb_fbc), "ffb fbc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!par->fbc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) goto out_release_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) par->dac = of_ioremap(&op->resource[1], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) sizeof(struct ffb_dac), "ffb dac");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (!par->dac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) goto out_unmap_fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) par->rop_cache = FFB_ROP_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) par->physbase = op->resource[0].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* Don't mention copyarea, so SCROLL_REDRAW is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * used. It is the fastest on this chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) info->flags = (FBINFO_DEFAULT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* FBINFO_HWACCEL_COPYAREA | */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) FBINFO_HWACCEL_FILLRECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) FBINFO_HWACCEL_IMAGEBLIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) info->fbops = &ffb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) info->screen_base = (char *) par->physbase + FFB_DFB24_POFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) info->pseudo_palette = par->pseudo_palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) sbusfb_fill_var(&info->var, dp, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ffb_fixup_var_rgb(&info->var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) info->var.accel_flags = FB_ACCELF_TEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (of_node_name_eq(dp, "SUNW,afb"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) par->flags |= FFB_FLAG_AFB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) par->board_type = of_getintprop_default(dp, "board_type", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) fbc = par->fbc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dac = par->dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) upa_writel(FFB_DAC_DID, &dac->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) dac_pnum = upa_readl(&dac->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) dac_pnum = (dac_pnum & FFB_DAC_DID_PNUM) >> FFB_DAC_DID_PNUM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) upa_writel(FFB_DAC_UCTRL, &dac->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) dac_mrev = upa_readl(&dac->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) dac_mrev = (dac_mrev & FFB_DAC_UCTRL_MANREV) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) FFB_DAC_UCTRL_MANREV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /* Elite3D has different DAC revision numbering, and no DAC revisions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * have the reversed meaning of cursor enable. Otherwise, Pacifica 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * ramdacs with manufacturing revision less than 3 have inverted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * cursor logic. We identify Pacifica 1 as not Pacifica 2, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * latter having a part number value of 0x236e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if ((par->flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) par->flags &= ~FFB_FLAG_INVCURSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (dac_mrev < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) par->flags |= FFB_FLAG_INVCURSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ffb_switch_from_graph(par);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /* Unblank it just to be sure. When there are multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * FFB/AFB cards in the system, or it is not the OBP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * chosen console, it will have video outputs off in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * the DAC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ffb_blank(FB_BLANK_UNBLANK, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (fb_alloc_cmap(&info->cmap, 256, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) goto out_unmap_dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ffb_init_fix(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) err = register_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) goto out_dealloc_cmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) dev_set_drvdata(&op->dev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) printk(KERN_INFO "%pOF: %s at %016lx, type %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) "DAC pnum[%x] rev[%d] manuf_rev[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ((par->flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) par->physbase, par->board_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) dac_pnum, dac_rev, dac_mrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) out_dealloc_cmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) fb_dealloc_cmap(&info->cmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) out_unmap_dac:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) out_unmap_fbc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) out_release_fb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static int ffb_remove(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct fb_info *info = dev_get_drvdata(&op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct ffb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) unregister_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) fb_dealloc_cmap(&info->cmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) static const struct of_device_id ffb_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .name = "SUNW,ffb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) .name = "SUNW,afb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) MODULE_DEVICE_TABLE(of, ffb_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static struct platform_driver ffb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .name = "ffb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .of_match_table = ffb_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .probe = ffb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .remove = ffb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int __init ffb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (fb_get_options("ffb", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return platform_driver_register(&ffb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static void __exit ffb_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) platform_driver_unregister(&ffb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) module_init(ffb_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) module_exit(ffb_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) MODULE_VERSION("2.0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) MODULE_LICENSE("GPL");