18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * linux/drivers/video/stifb.c - 38c2ecf20Sopenharmony_ci * Low level Frame buffer driver for HP workstations with 48c2ecf20Sopenharmony_ci * STI (standard text interface) video firmware. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2001-2006 Helge Deller <deller@gmx.de> 78c2ecf20Sopenharmony_ci * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de> 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Based on: 108c2ecf20Sopenharmony_ci * - linux/drivers/video/artistfb.c -- Artist frame buffer driver 118c2ecf20Sopenharmony_ci * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> 128c2ecf20Sopenharmony_ci * - based on skeletonfb, which was 138c2ecf20Sopenharmony_ci * Created 28 Dec 1997 by Geert Uytterhoeven 148c2ecf20Sopenharmony_ci * - HP Xhp cfb-based X11 window driver for XFree86 158c2ecf20Sopenharmony_ci * (c)Copyright 1992 Hewlett-Packard Co. 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * The following graphics display devices (NGLE family) are supported by this driver: 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * HPA4070A known as "HCRX", a 1280x1024 color device with 8 planes 218c2ecf20Sopenharmony_ci * HPA4071A known as "HCRX24", a 1280x1024 color device with 24 planes, 228c2ecf20Sopenharmony_ci * optionally available with a hardware accelerator as HPA4071A_Z 238c2ecf20Sopenharmony_ci * HPA1659A known as "CRX", a 1280x1024 color device with 8 planes 248c2ecf20Sopenharmony_ci * HPA1439A known as "CRX24", a 1280x1024 color device with 24 planes, 258c2ecf20Sopenharmony_ci * optionally available with a hardware accelerator. 268c2ecf20Sopenharmony_ci * HPA1924A known as "GRX", a 1280x1024 grayscale device with 8 planes 278c2ecf20Sopenharmony_ci * HPA2269A known as "Dual CRX", a 1280x1024 color device with 8 planes, 288c2ecf20Sopenharmony_ci * implements support for two displays on a single graphics card. 298c2ecf20Sopenharmony_ci * HP710C internal graphics support optionally available on the HP9000s710 SPU, 308c2ecf20Sopenharmony_ci * supports 1280x1024 color displays with 8 planes. 318c2ecf20Sopenharmony_ci * HP710G same as HP710C, 1280x1024 grayscale only 328c2ecf20Sopenharmony_ci * HP710L same as HP710C, 1024x768 color only 338c2ecf20Sopenharmony_ci * HP712 internal graphics support on HP9000s712 SPU, supports 640x480, 348c2ecf20Sopenharmony_ci * 1024x768 or 1280x1024 color displays on 8 planes (Artist) 358c2ecf20Sopenharmony_ci * 368c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 378c2ecf20Sopenharmony_ci * License. See the file COPYING in the main directory of this archive 388c2ecf20Sopenharmony_ci * for more details. 398c2ecf20Sopenharmony_ci */ 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/* TODO: 428c2ecf20Sopenharmony_ci * - 1bpp mode is completely untested 438c2ecf20Sopenharmony_ci * - add support for h/w acceleration 448c2ecf20Sopenharmony_ci * - add hardware cursor 458c2ecf20Sopenharmony_ci * - automatically disable double buffering (e.g. on RDI precisionbook laptop) 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci/* on supported graphic devices you may: 508c2ecf20Sopenharmony_ci * #define FALLBACK_TO_1BPP to fall back to 1 bpp, or 518c2ecf20Sopenharmony_ci * #undef FALLBACK_TO_1BPP to reject support for unsupported cards */ 528c2ecf20Sopenharmony_ci#undef FALLBACK_TO_1BPP 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#undef DEBUG_STIFB_REGS /* debug sti register accesses */ 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#include <linux/module.h> 588c2ecf20Sopenharmony_ci#include <linux/kernel.h> 598c2ecf20Sopenharmony_ci#include <linux/errno.h> 608c2ecf20Sopenharmony_ci#include <linux/string.h> 618c2ecf20Sopenharmony_ci#include <linux/mm.h> 628c2ecf20Sopenharmony_ci#include <linux/slab.h> 638c2ecf20Sopenharmony_ci#include <linux/delay.h> 648c2ecf20Sopenharmony_ci#include <linux/fb.h> 658c2ecf20Sopenharmony_ci#include <linux/init.h> 668c2ecf20Sopenharmony_ci#include <linux/ioport.h> 678c2ecf20Sopenharmony_ci#include <linux/io.h> 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci#include <asm/grfioctl.h> /* for HP-UX compatibility */ 708c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#include "sticore.h" 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/* REGION_BASE(fb_info, index) returns the virtual address for region <index> */ 758c2ecf20Sopenharmony_ci#define REGION_BASE(fb_info, index) \ 768c2ecf20Sopenharmony_ci F_EXTEND(fb_info->sti->glob_cfg->region_ptrs[index]) 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci#define NGLEDEVDEPROM_CRT_REGION 1 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#define NR_PALETTE 256 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_citypedef struct { 838c2ecf20Sopenharmony_ci __s32 video_config_reg; 848c2ecf20Sopenharmony_ci __s32 misc_video_start; 858c2ecf20Sopenharmony_ci __s32 horiz_timing_fmt; 868c2ecf20Sopenharmony_ci __s32 serr_timing_fmt; 878c2ecf20Sopenharmony_ci __s32 vert_timing_fmt; 888c2ecf20Sopenharmony_ci __s32 horiz_state; 898c2ecf20Sopenharmony_ci __s32 vert_state; 908c2ecf20Sopenharmony_ci __s32 vtg_state_elements; 918c2ecf20Sopenharmony_ci __s32 pipeline_delay; 928c2ecf20Sopenharmony_ci __s32 misc_video_end; 938c2ecf20Sopenharmony_ci} video_setup_t; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_citypedef struct { 968c2ecf20Sopenharmony_ci __s16 sizeof_ngle_data; 978c2ecf20Sopenharmony_ci __s16 x_size_visible; /* visible screen dim in pixels */ 988c2ecf20Sopenharmony_ci __s16 y_size_visible; 998c2ecf20Sopenharmony_ci __s16 pad2[15]; 1008c2ecf20Sopenharmony_ci __s16 cursor_pipeline_delay; 1018c2ecf20Sopenharmony_ci __s16 video_interleaves; 1028c2ecf20Sopenharmony_ci __s32 pad3[11]; 1038c2ecf20Sopenharmony_ci} ngle_rom_t; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistruct stifb_info { 1068c2ecf20Sopenharmony_ci struct fb_info info; 1078c2ecf20Sopenharmony_ci unsigned int id; 1088c2ecf20Sopenharmony_ci ngle_rom_t ngle_rom; 1098c2ecf20Sopenharmony_ci struct sti_struct *sti; 1108c2ecf20Sopenharmony_ci int deviceSpecificConfig; 1118c2ecf20Sopenharmony_ci u32 pseudo_palette[16]; 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic int __initdata stifb_bpp_pref[MAX_STI_ROMS]; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci/* ------------------- chipset specific functions -------------------------- */ 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/* offsets to graphic-chip internal registers */ 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define REG_1 0x000118 1218c2ecf20Sopenharmony_ci#define REG_2 0x000480 1228c2ecf20Sopenharmony_ci#define REG_3 0x0004a0 1238c2ecf20Sopenharmony_ci#define REG_4 0x000600 1248c2ecf20Sopenharmony_ci#define REG_6 0x000800 1258c2ecf20Sopenharmony_ci#define REG_7 0x000804 1268c2ecf20Sopenharmony_ci#define REG_8 0x000820 1278c2ecf20Sopenharmony_ci#define REG_9 0x000a04 1288c2ecf20Sopenharmony_ci#define REG_10 0x018000 1298c2ecf20Sopenharmony_ci#define REG_11 0x018004 1308c2ecf20Sopenharmony_ci#define REG_12 0x01800c 1318c2ecf20Sopenharmony_ci#define REG_13 0x018018 1328c2ecf20Sopenharmony_ci#define REG_14 0x01801c 1338c2ecf20Sopenharmony_ci#define REG_15 0x200000 1348c2ecf20Sopenharmony_ci#define REG_15b0 0x200000 1358c2ecf20Sopenharmony_ci#define REG_16b1 0x200005 1368c2ecf20Sopenharmony_ci#define REG_16b3 0x200007 1378c2ecf20Sopenharmony_ci#define REG_21 0x200218 1388c2ecf20Sopenharmony_ci#define REG_22 0x0005a0 1398c2ecf20Sopenharmony_ci#define REG_23 0x0005c0 1408c2ecf20Sopenharmony_ci#define REG_24 0x000808 1418c2ecf20Sopenharmony_ci#define REG_25 0x000b00 1428c2ecf20Sopenharmony_ci#define REG_26 0x200118 1438c2ecf20Sopenharmony_ci#define REG_27 0x200308 1448c2ecf20Sopenharmony_ci#define REG_32 0x21003c 1458c2ecf20Sopenharmony_ci#define REG_33 0x210040 1468c2ecf20Sopenharmony_ci#define REG_34 0x200008 1478c2ecf20Sopenharmony_ci#define REG_35 0x018010 1488c2ecf20Sopenharmony_ci#define REG_38 0x210020 1498c2ecf20Sopenharmony_ci#define REG_39 0x210120 1508c2ecf20Sopenharmony_ci#define REG_40 0x210130 1518c2ecf20Sopenharmony_ci#define REG_42 0x210028 1528c2ecf20Sopenharmony_ci#define REG_43 0x21002c 1538c2ecf20Sopenharmony_ci#define REG_44 0x210030 1548c2ecf20Sopenharmony_ci#define REG_45 0x210034 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci#define READ_BYTE(fb,reg) gsc_readb((fb)->info.fix.mmio_start + (reg)) 1578c2ecf20Sopenharmony_ci#define READ_WORD(fb,reg) gsc_readl((fb)->info.fix.mmio_start + (reg)) 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci#ifndef DEBUG_STIFB_REGS 1618c2ecf20Sopenharmony_ci# define DEBUG_OFF() 1628c2ecf20Sopenharmony_ci# define DEBUG_ON() 1638c2ecf20Sopenharmony_ci# define WRITE_BYTE(value,fb,reg) gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)) 1648c2ecf20Sopenharmony_ci# define WRITE_WORD(value,fb,reg) gsc_writel((value),(fb)->info.fix.mmio_start + (reg)) 1658c2ecf20Sopenharmony_ci#else 1668c2ecf20Sopenharmony_ci static int debug_on = 1; 1678c2ecf20Sopenharmony_ci# define DEBUG_OFF() debug_on=0 1688c2ecf20Sopenharmony_ci# define DEBUG_ON() debug_on=1 1698c2ecf20Sopenharmony_ci# define WRITE_BYTE(value,fb,reg) do { if (debug_on) \ 1708c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \ 1718c2ecf20Sopenharmony_ci __func__, reg, value, READ_BYTE(fb,reg)); \ 1728c2ecf20Sopenharmony_ci gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0) 1738c2ecf20Sopenharmony_ci# define WRITE_WORD(value,fb,reg) do { if (debug_on) \ 1748c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \ 1758c2ecf20Sopenharmony_ci __func__, reg, value, READ_WORD(fb,reg)); \ 1768c2ecf20Sopenharmony_ci gsc_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0) 1778c2ecf20Sopenharmony_ci#endif /* DEBUG_STIFB_REGS */ 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci#define ENABLE 1 /* for enabling/disabling screen */ 1818c2ecf20Sopenharmony_ci#define DISABLE 0 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci#define NGLE_LOCK(fb_info) do { } while (0) 1848c2ecf20Sopenharmony_ci#define NGLE_UNLOCK(fb_info) do { } while (0) 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_cistatic void 1878c2ecf20Sopenharmony_ciSETUP_HW(struct stifb_info *fb) 1888c2ecf20Sopenharmony_ci{ 1898c2ecf20Sopenharmony_ci char stat; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci do { 1928c2ecf20Sopenharmony_ci stat = READ_BYTE(fb, REG_15b0); 1938c2ecf20Sopenharmony_ci if (!stat) 1948c2ecf20Sopenharmony_ci stat = READ_BYTE(fb, REG_15b0); 1958c2ecf20Sopenharmony_ci } while (stat); 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistatic void 2008c2ecf20Sopenharmony_ciSETUP_FB(struct stifb_info *fb) 2018c2ecf20Sopenharmony_ci{ 2028c2ecf20Sopenharmony_ci unsigned int reg10_value = 0; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci SETUP_HW(fb); 2058c2ecf20Sopenharmony_ci switch (fb->id) 2068c2ecf20Sopenharmony_ci { 2078c2ecf20Sopenharmony_ci case CRT_ID_VISUALIZE_EG: 2088c2ecf20Sopenharmony_ci case S9000_ID_ARTIST: 2098c2ecf20Sopenharmony_ci case S9000_ID_A1659A: 2108c2ecf20Sopenharmony_ci reg10_value = 0x13601000; 2118c2ecf20Sopenharmony_ci break; 2128c2ecf20Sopenharmony_ci case S9000_ID_A1439A: 2138c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 32) 2148c2ecf20Sopenharmony_ci reg10_value = 0xBBA0A000; 2158c2ecf20Sopenharmony_ci else 2168c2ecf20Sopenharmony_ci reg10_value = 0x13601000; 2178c2ecf20Sopenharmony_ci break; 2188c2ecf20Sopenharmony_ci case S9000_ID_HCRX: 2198c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 32) 2208c2ecf20Sopenharmony_ci reg10_value = 0xBBA0A000; 2218c2ecf20Sopenharmony_ci else 2228c2ecf20Sopenharmony_ci reg10_value = 0x13602000; 2238c2ecf20Sopenharmony_ci break; 2248c2ecf20Sopenharmony_ci case S9000_ID_TIMBER: 2258c2ecf20Sopenharmony_ci case CRX24_OVERLAY_PLANES: 2268c2ecf20Sopenharmony_ci reg10_value = 0x13602000; 2278c2ecf20Sopenharmony_ci break; 2288c2ecf20Sopenharmony_ci } 2298c2ecf20Sopenharmony_ci if (reg10_value) 2308c2ecf20Sopenharmony_ci WRITE_WORD(reg10_value, fb, REG_10); 2318c2ecf20Sopenharmony_ci WRITE_WORD(0x83000300, fb, REG_14); 2328c2ecf20Sopenharmony_ci SETUP_HW(fb); 2338c2ecf20Sopenharmony_ci WRITE_BYTE(1, fb, REG_16b1); 2348c2ecf20Sopenharmony_ci} 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic void 2378c2ecf20Sopenharmony_ciSTART_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci SETUP_HW(fb); 2408c2ecf20Sopenharmony_ci WRITE_WORD(0xBBE0F000, fb, REG_10); 2418c2ecf20Sopenharmony_ci WRITE_WORD(0x03000300, fb, REG_14); 2428c2ecf20Sopenharmony_ci WRITE_WORD(~0, fb, REG_13); 2438c2ecf20Sopenharmony_ci} 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_cistatic void 2468c2ecf20Sopenharmony_ciWRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color) 2478c2ecf20Sopenharmony_ci{ 2488c2ecf20Sopenharmony_ci SETUP_HW(fb); 2498c2ecf20Sopenharmony_ci WRITE_WORD(((0x100+index)<<2), fb, REG_3); 2508c2ecf20Sopenharmony_ci WRITE_WORD(color, fb, REG_4); 2518c2ecf20Sopenharmony_ci} 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_cistatic void 2548c2ecf20Sopenharmony_ciFINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb) 2558c2ecf20Sopenharmony_ci{ 2568c2ecf20Sopenharmony_ci WRITE_WORD(0x400, fb, REG_2); 2578c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 32) { 2588c2ecf20Sopenharmony_ci WRITE_WORD(0x83000100, fb, REG_1); 2598c2ecf20Sopenharmony_ci } else { 2608c2ecf20Sopenharmony_ci if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG) 2618c2ecf20Sopenharmony_ci WRITE_WORD(0x80000100, fb, REG_26); 2628c2ecf20Sopenharmony_ci else 2638c2ecf20Sopenharmony_ci WRITE_WORD(0x80000100, fb, REG_1); 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci SETUP_FB(fb); 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic void 2698c2ecf20Sopenharmony_ciSETUP_RAMDAC(struct stifb_info *fb) 2708c2ecf20Sopenharmony_ci{ 2718c2ecf20Sopenharmony_ci SETUP_HW(fb); 2728c2ecf20Sopenharmony_ci WRITE_WORD(0x04000000, fb, 0x1020); 2738c2ecf20Sopenharmony_ci WRITE_WORD(0xff000000, fb, 0x1028); 2748c2ecf20Sopenharmony_ci} 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_cistatic void 2778c2ecf20Sopenharmony_ciCRX24_SETUP_RAMDAC(struct stifb_info *fb) 2788c2ecf20Sopenharmony_ci{ 2798c2ecf20Sopenharmony_ci SETUP_HW(fb); 2808c2ecf20Sopenharmony_ci WRITE_WORD(0x04000000, fb, 0x1000); 2818c2ecf20Sopenharmony_ci WRITE_WORD(0x02000000, fb, 0x1004); 2828c2ecf20Sopenharmony_ci WRITE_WORD(0xff000000, fb, 0x1008); 2838c2ecf20Sopenharmony_ci WRITE_WORD(0x05000000, fb, 0x1000); 2848c2ecf20Sopenharmony_ci WRITE_WORD(0x02000000, fb, 0x1004); 2858c2ecf20Sopenharmony_ci WRITE_WORD(0x03000000, fb, 0x1008); 2868c2ecf20Sopenharmony_ci} 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci#if 0 2898c2ecf20Sopenharmony_cistatic void 2908c2ecf20Sopenharmony_ciHCRX_SETUP_RAMDAC(struct stifb_info *fb) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci WRITE_WORD(0xffffffff, fb, REG_32); 2938c2ecf20Sopenharmony_ci} 2948c2ecf20Sopenharmony_ci#endif 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_cistatic void 2978c2ecf20Sopenharmony_ciCRX24_SET_OVLY_MASK(struct stifb_info *fb) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci SETUP_HW(fb); 3008c2ecf20Sopenharmony_ci WRITE_WORD(0x13a02000, fb, REG_11); 3018c2ecf20Sopenharmony_ci WRITE_WORD(0x03000300, fb, REG_14); 3028c2ecf20Sopenharmony_ci WRITE_WORD(0x000017f0, fb, REG_3); 3038c2ecf20Sopenharmony_ci WRITE_WORD(0xffffffff, fb, REG_13); 3048c2ecf20Sopenharmony_ci WRITE_WORD(0xffffffff, fb, REG_22); 3058c2ecf20Sopenharmony_ci WRITE_WORD(0x00000000, fb, REG_23); 3068c2ecf20Sopenharmony_ci} 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_cistatic void 3098c2ecf20Sopenharmony_ciENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) 3108c2ecf20Sopenharmony_ci{ 3118c2ecf20Sopenharmony_ci unsigned int value = enable ? 0x43000000 : 0x03000000; 3128c2ecf20Sopenharmony_ci SETUP_HW(fb); 3138c2ecf20Sopenharmony_ci WRITE_WORD(0x06000000, fb, 0x1030); 3148c2ecf20Sopenharmony_ci WRITE_WORD(value, fb, 0x1038); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic void 3188c2ecf20Sopenharmony_ciCRX24_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci unsigned int value = enable ? 0x10000000 : 0x30000000; 3218c2ecf20Sopenharmony_ci SETUP_HW(fb); 3228c2ecf20Sopenharmony_ci WRITE_WORD(0x01000000, fb, 0x1000); 3238c2ecf20Sopenharmony_ci WRITE_WORD(0x02000000, fb, 0x1004); 3248c2ecf20Sopenharmony_ci WRITE_WORD(value, fb, 0x1008); 3258c2ecf20Sopenharmony_ci} 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_cistatic void 3288c2ecf20Sopenharmony_ciARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) 3298c2ecf20Sopenharmony_ci{ 3308c2ecf20Sopenharmony_ci u32 DregsMiscVideo = REG_21; 3318c2ecf20Sopenharmony_ci u32 DregsMiscCtl = REG_27; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci SETUP_HW(fb); 3348c2ecf20Sopenharmony_ci if (enable) { 3358c2ecf20Sopenharmony_ci WRITE_WORD(READ_WORD(fb, DregsMiscVideo) | 0x0A000000, fb, DregsMiscVideo); 3368c2ecf20Sopenharmony_ci WRITE_WORD(READ_WORD(fb, DregsMiscCtl) | 0x00800000, fb, DregsMiscCtl); 3378c2ecf20Sopenharmony_ci } else { 3388c2ecf20Sopenharmony_ci WRITE_WORD(READ_WORD(fb, DregsMiscVideo) & ~0x0A000000, fb, DregsMiscVideo); 3398c2ecf20Sopenharmony_ci WRITE_WORD(READ_WORD(fb, DregsMiscCtl) & ~0x00800000, fb, DregsMiscCtl); 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci} 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci#define GET_ROMTABLE_INDEX(fb) \ 3448c2ecf20Sopenharmony_ci (READ_BYTE(fb, REG_16b3) - 1) 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci#define HYPER_CONFIG_PLANES_24 0x00000100 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci#define IS_24_DEVICE(fb) \ 3498c2ecf20Sopenharmony_ci (fb->deviceSpecificConfig & HYPER_CONFIG_PLANES_24) 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci#define IS_888_DEVICE(fb) \ 3528c2ecf20Sopenharmony_ci (!(IS_24_DEVICE(fb))) 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci#define GET_FIFO_SLOTS(fb, cnt, numslots) \ 3558c2ecf20Sopenharmony_ci{ while (cnt < numslots) \ 3568c2ecf20Sopenharmony_ci cnt = READ_WORD(fb, REG_34); \ 3578c2ecf20Sopenharmony_ci cnt -= numslots; \ 3588c2ecf20Sopenharmony_ci} 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci#define IndexedDcd 0 /* Pixel data is indexed (pseudo) color */ 3618c2ecf20Sopenharmony_ci#define Otc04 2 /* Pixels in each longword transfer (4) */ 3628c2ecf20Sopenharmony_ci#define Otc32 5 /* Pixels in each longword transfer (32) */ 3638c2ecf20Sopenharmony_ci#define Ots08 3 /* Each pixel is size (8)d transfer (1) */ 3648c2ecf20Sopenharmony_ci#define OtsIndirect 6 /* Each bit goes through FG/BG color(8) */ 3658c2ecf20Sopenharmony_ci#define AddrLong 5 /* FB address is Long aligned (pixel) */ 3668c2ecf20Sopenharmony_ci#define BINovly 0x2 /* 8 bit overlay */ 3678c2ecf20Sopenharmony_ci#define BINapp0I 0x0 /* Application Buffer 0, Indexed */ 3688c2ecf20Sopenharmony_ci#define BINapp1I 0x1 /* Application Buffer 1, Indexed */ 3698c2ecf20Sopenharmony_ci#define BINapp0F8 0xa /* Application Buffer 0, Fractional 8-8-8 */ 3708c2ecf20Sopenharmony_ci#define BINattr 0xd /* Attribute Bitmap */ 3718c2ecf20Sopenharmony_ci#define RopSrc 0x3 3728c2ecf20Sopenharmony_ci#define BitmapExtent08 3 /* Each write hits ( 8) bits in depth */ 3738c2ecf20Sopenharmony_ci#define BitmapExtent32 5 /* Each write hits (32) bits in depth */ 3748c2ecf20Sopenharmony_ci#define DataDynamic 0 /* Data register reloaded by direct access */ 3758c2ecf20Sopenharmony_ci#define MaskDynamic 1 /* Mask register reloaded by direct access */ 3768c2ecf20Sopenharmony_ci#define MaskOtc 0 /* Mask contains Object Count valid bits */ 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci#define MaskAddrOffset(offset) (offset) 3798c2ecf20Sopenharmony_ci#define StaticReg(en) (en) 3808c2ecf20Sopenharmony_ci#define BGx(en) (en) 3818c2ecf20Sopenharmony_ci#define FGx(en) (en) 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci#define BAJustPoint(offset) (offset) 3848c2ecf20Sopenharmony_ci#define BAIndexBase(base) (base) 3858c2ecf20Sopenharmony_ci#define BA(F,C,S,A,J,B,I) \ 3868c2ecf20Sopenharmony_ci (((F)<<31)|((C)<<27)|((S)<<24)|((A)<<21)|((J)<<16)|((B)<<12)|(I)) 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci#define IBOvals(R,M,X,S,D,L,B,F) \ 3898c2ecf20Sopenharmony_ci (((R)<<8)|((M)<<16)|((X)<<24)|((S)<<29)|((D)<<28)|((L)<<31)|((B)<<1)|(F)) 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci#define NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, val) \ 3928c2ecf20Sopenharmony_ci WRITE_WORD(val, fb, REG_14) 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci#define NGLE_QUICK_SET_DST_BM_ACCESS(fb, val) \ 3958c2ecf20Sopenharmony_ci WRITE_WORD(val, fb, REG_11) 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci#define NGLE_QUICK_SET_CTL_PLN_REG(fb, val) \ 3988c2ecf20Sopenharmony_ci WRITE_WORD(val, fb, REG_12) 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci#define NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, plnmsk32) \ 4018c2ecf20Sopenharmony_ci WRITE_WORD(plnmsk32, fb, REG_13) 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci#define NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, fg32) \ 4048c2ecf20Sopenharmony_ci WRITE_WORD(fg32, fb, REG_35) 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci#define NGLE_SET_TRANSFERDATA(fb, val) \ 4078c2ecf20Sopenharmony_ci WRITE_WORD(val, fb, REG_8) 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci#define NGLE_SET_DSTXY(fb, val) \ 4108c2ecf20Sopenharmony_ci WRITE_WORD(val, fb, REG_6) 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci#define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) ( \ 4138c2ecf20Sopenharmony_ci (u32) (fbaddrbase) + \ 4148c2ecf20Sopenharmony_ci ( (unsigned int) ( (y) << 13 ) | \ 4158c2ecf20Sopenharmony_ci (unsigned int) ( (x) << 2 ) ) \ 4168c2ecf20Sopenharmony_ci ) 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci#define NGLE_BINC_SET_DSTADDR(fb, addr) \ 4198c2ecf20Sopenharmony_ci WRITE_WORD(addr, fb, REG_3) 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci#define NGLE_BINC_SET_SRCADDR(fb, addr) \ 4228c2ecf20Sopenharmony_ci WRITE_WORD(addr, fb, REG_2) 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci#define NGLE_BINC_SET_DSTMASK(fb, mask) \ 4258c2ecf20Sopenharmony_ci WRITE_WORD(mask, fb, REG_22) 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci#define NGLE_BINC_WRITE32(fb, data32) \ 4288c2ecf20Sopenharmony_ci WRITE_WORD(data32, fb, REG_23) 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci#define START_COLORMAPLOAD(fb, cmapBltCtlData32) \ 4318c2ecf20Sopenharmony_ci WRITE_WORD((cmapBltCtlData32), fb, REG_38) 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci#define SET_LENXY_START_RECFILL(fb, lenxy) \ 4348c2ecf20Sopenharmony_ci WRITE_WORD(lenxy, fb, REG_9) 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci#define SETUP_COPYAREA(fb) \ 4378c2ecf20Sopenharmony_ci WRITE_BYTE(0, fb, REG_16b1) 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_cistatic void 4408c2ecf20Sopenharmony_ciHYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) 4418c2ecf20Sopenharmony_ci{ 4428c2ecf20Sopenharmony_ci u32 DregsHypMiscVideo = REG_33; 4438c2ecf20Sopenharmony_ci unsigned int value; 4448c2ecf20Sopenharmony_ci SETUP_HW(fb); 4458c2ecf20Sopenharmony_ci value = READ_WORD(fb, DregsHypMiscVideo); 4468c2ecf20Sopenharmony_ci if (enable) 4478c2ecf20Sopenharmony_ci value |= 0x0A000000; 4488c2ecf20Sopenharmony_ci else 4498c2ecf20Sopenharmony_ci value &= ~0x0A000000; 4508c2ecf20Sopenharmony_ci WRITE_WORD(value, fb, DregsHypMiscVideo); 4518c2ecf20Sopenharmony_ci} 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci/* BufferNumbers used by SETUP_ATTR_ACCESS() */ 4558c2ecf20Sopenharmony_ci#define BUFF0_CMAP0 0x00001e02 4568c2ecf20Sopenharmony_ci#define BUFF1_CMAP0 0x02001e02 4578c2ecf20Sopenharmony_ci#define BUFF1_CMAP3 0x0c001e02 4588c2ecf20Sopenharmony_ci#define ARTIST_CMAP0 0x00000102 4598c2ecf20Sopenharmony_ci#define HYPER_CMAP8 0x00000100 4608c2ecf20Sopenharmony_ci#define HYPER_CMAP24 0x00000800 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_cistatic void 4638c2ecf20Sopenharmony_ciSETUP_ATTR_ACCESS(struct stifb_info *fb, unsigned BufferNumber) 4648c2ecf20Sopenharmony_ci{ 4658c2ecf20Sopenharmony_ci SETUP_HW(fb); 4668c2ecf20Sopenharmony_ci WRITE_WORD(0x2EA0D000, fb, REG_11); 4678c2ecf20Sopenharmony_ci WRITE_WORD(0x23000302, fb, REG_14); 4688c2ecf20Sopenharmony_ci WRITE_WORD(BufferNumber, fb, REG_12); 4698c2ecf20Sopenharmony_ci WRITE_WORD(0xffffffff, fb, REG_8); 4708c2ecf20Sopenharmony_ci} 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_cistatic void 4738c2ecf20Sopenharmony_ciSET_ATTR_SIZE(struct stifb_info *fb, int width, int height) 4748c2ecf20Sopenharmony_ci{ 4758c2ecf20Sopenharmony_ci /* REG_6 seems to have special values when run on a 4768c2ecf20Sopenharmony_ci RDI precisionbook parisc laptop (INTERNAL_EG_DX1024 or 4778c2ecf20Sopenharmony_ci INTERNAL_EG_X1024). The values are: 4788c2ecf20Sopenharmony_ci 0x2f0: internal (LCD) & external display enabled 4798c2ecf20Sopenharmony_ci 0x2a0: external display only 4808c2ecf20Sopenharmony_ci 0x000: zero on standard artist graphic cards 4818c2ecf20Sopenharmony_ci */ 4828c2ecf20Sopenharmony_ci WRITE_WORD(0x00000000, fb, REG_6); 4838c2ecf20Sopenharmony_ci WRITE_WORD((width<<16) | height, fb, REG_9); 4848c2ecf20Sopenharmony_ci WRITE_WORD(0x05000000, fb, REG_6); 4858c2ecf20Sopenharmony_ci WRITE_WORD(0x00040001, fb, REG_9); 4868c2ecf20Sopenharmony_ci} 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_cistatic void 4898c2ecf20Sopenharmony_ciFINISH_ATTR_ACCESS(struct stifb_info *fb) 4908c2ecf20Sopenharmony_ci{ 4918c2ecf20Sopenharmony_ci SETUP_HW(fb); 4928c2ecf20Sopenharmony_ci WRITE_WORD(0x00000000, fb, REG_12); 4938c2ecf20Sopenharmony_ci} 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_cistatic void 4968c2ecf20Sopenharmony_cielkSetupPlanes(struct stifb_info *fb) 4978c2ecf20Sopenharmony_ci{ 4988c2ecf20Sopenharmony_ci SETUP_RAMDAC(fb); 4998c2ecf20Sopenharmony_ci SETUP_FB(fb); 5008c2ecf20Sopenharmony_ci} 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_cistatic void 5038c2ecf20Sopenharmony_cingleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber) 5048c2ecf20Sopenharmony_ci{ 5058c2ecf20Sopenharmony_ci SETUP_ATTR_ACCESS(fb, BufferNumber); 5068c2ecf20Sopenharmony_ci SET_ATTR_SIZE(fb, fb->info.var.xres, fb->info.var.yres); 5078c2ecf20Sopenharmony_ci FINISH_ATTR_ACCESS(fb); 5088c2ecf20Sopenharmony_ci SETUP_FB(fb); 5098c2ecf20Sopenharmony_ci} 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_cistatic void 5138c2ecf20Sopenharmony_cirattlerSetupPlanes(struct stifb_info *fb) 5148c2ecf20Sopenharmony_ci{ 5158c2ecf20Sopenharmony_ci int saved_id, y; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci /* Write RAMDAC pixel read mask register so all overlay 5188c2ecf20Sopenharmony_ci * planes are display-enabled. (CRX24 uses Bt462 pixel 5198c2ecf20Sopenharmony_ci * read mask register for overlay planes, not image planes). 5208c2ecf20Sopenharmony_ci */ 5218c2ecf20Sopenharmony_ci CRX24_SETUP_RAMDAC(fb); 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci /* change fb->id temporarily to fool SETUP_FB() */ 5248c2ecf20Sopenharmony_ci saved_id = fb->id; 5258c2ecf20Sopenharmony_ci fb->id = CRX24_OVERLAY_PLANES; 5268c2ecf20Sopenharmony_ci SETUP_FB(fb); 5278c2ecf20Sopenharmony_ci fb->id = saved_id; 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci for (y = 0; y < fb->info.var.yres; ++y) 5308c2ecf20Sopenharmony_ci fb_memset(fb->info.screen_base + y * fb->info.fix.line_length, 5318c2ecf20Sopenharmony_ci 0xff, fb->info.var.xres * fb->info.var.bits_per_pixel/8); 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci CRX24_SET_OVLY_MASK(fb); 5348c2ecf20Sopenharmony_ci SETUP_FB(fb); 5358c2ecf20Sopenharmony_ci} 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci#define HYPER_CMAP_TYPE 0 5398c2ecf20Sopenharmony_ci#define NGLE_CMAP_INDEXED0_TYPE 0 5408c2ecf20Sopenharmony_ci#define NGLE_CMAP_OVERLAY_TYPE 3 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci/* typedef of LUT (Colormap) BLT Control Register */ 5438c2ecf20Sopenharmony_citypedef union /* Note assumption that fields are packed left-to-right */ 5448c2ecf20Sopenharmony_ci{ u32 all; 5458c2ecf20Sopenharmony_ci struct 5468c2ecf20Sopenharmony_ci { 5478c2ecf20Sopenharmony_ci unsigned enable : 1; 5488c2ecf20Sopenharmony_ci unsigned waitBlank : 1; 5498c2ecf20Sopenharmony_ci unsigned reserved1 : 4; 5508c2ecf20Sopenharmony_ci unsigned lutOffset : 10; /* Within destination LUT */ 5518c2ecf20Sopenharmony_ci unsigned lutType : 2; /* Cursor, image, overlay */ 5528c2ecf20Sopenharmony_ci unsigned reserved2 : 4; 5538c2ecf20Sopenharmony_ci unsigned length : 10; 5548c2ecf20Sopenharmony_ci } fields; 5558c2ecf20Sopenharmony_ci} NgleLutBltCtl; 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci#if 0 5598c2ecf20Sopenharmony_cistatic NgleLutBltCtl 5608c2ecf20Sopenharmony_cisetNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length) 5618c2ecf20Sopenharmony_ci{ 5628c2ecf20Sopenharmony_ci NgleLutBltCtl lutBltCtl; 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci /* set enable, zero reserved fields */ 5658c2ecf20Sopenharmony_ci lutBltCtl.all = 0x80000000; 5668c2ecf20Sopenharmony_ci lutBltCtl.fields.length = length; 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci switch (fb->id) 5698c2ecf20Sopenharmony_ci { 5708c2ecf20Sopenharmony_ci case S9000_ID_A1439A: /* CRX24 */ 5718c2ecf20Sopenharmony_ci if (fb->var.bits_per_pixel == 8) { 5728c2ecf20Sopenharmony_ci lutBltCtl.fields.lutType = NGLE_CMAP_OVERLAY_TYPE; 5738c2ecf20Sopenharmony_ci lutBltCtl.fields.lutOffset = 0; 5748c2ecf20Sopenharmony_ci } else { 5758c2ecf20Sopenharmony_ci lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE; 5768c2ecf20Sopenharmony_ci lutBltCtl.fields.lutOffset = 0 * 256; 5778c2ecf20Sopenharmony_ci } 5788c2ecf20Sopenharmony_ci break; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci case S9000_ID_ARTIST: 5818c2ecf20Sopenharmony_ci lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE; 5828c2ecf20Sopenharmony_ci lutBltCtl.fields.lutOffset = 0 * 256; 5838c2ecf20Sopenharmony_ci break; 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci default: 5868c2ecf20Sopenharmony_ci lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE; 5878c2ecf20Sopenharmony_ci lutBltCtl.fields.lutOffset = 0; 5888c2ecf20Sopenharmony_ci break; 5898c2ecf20Sopenharmony_ci } 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci /* Offset points to start of LUT. Adjust for within LUT */ 5928c2ecf20Sopenharmony_ci lutBltCtl.fields.lutOffset += offsetWithinLut; 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_ci return lutBltCtl; 5958c2ecf20Sopenharmony_ci} 5968c2ecf20Sopenharmony_ci#endif 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_cistatic NgleLutBltCtl 5998c2ecf20Sopenharmony_cisetHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length) 6008c2ecf20Sopenharmony_ci{ 6018c2ecf20Sopenharmony_ci NgleLutBltCtl lutBltCtl; 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci /* set enable, zero reserved fields */ 6048c2ecf20Sopenharmony_ci lutBltCtl.all = 0x80000000; 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci lutBltCtl.fields.length = length; 6078c2ecf20Sopenharmony_ci lutBltCtl.fields.lutType = HYPER_CMAP_TYPE; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci /* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */ 6108c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 8) 6118c2ecf20Sopenharmony_ci lutBltCtl.fields.lutOffset = 2 * 256; 6128c2ecf20Sopenharmony_ci else 6138c2ecf20Sopenharmony_ci lutBltCtl.fields.lutOffset = 0 * 256; 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ci /* Offset points to start of LUT. Adjust for within LUT */ 6168c2ecf20Sopenharmony_ci lutBltCtl.fields.lutOffset += offsetWithinLut; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci return lutBltCtl; 6198c2ecf20Sopenharmony_ci} 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_cistatic void hyperUndoITE(struct stifb_info *fb) 6238c2ecf20Sopenharmony_ci{ 6248c2ecf20Sopenharmony_ci int nFreeFifoSlots = 0; 6258c2ecf20Sopenharmony_ci u32 fbAddr; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci NGLE_LOCK(fb); 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1); 6308c2ecf20Sopenharmony_ci WRITE_WORD(0xffffffff, fb, REG_32); 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci /* Write overlay transparency mask so only entry 255 is transparent */ 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci /* Hardware setup for full-depth write to "magic" location */ 6358c2ecf20Sopenharmony_ci GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7); 6368c2ecf20Sopenharmony_ci NGLE_QUICK_SET_DST_BM_ACCESS(fb, 6378c2ecf20Sopenharmony_ci BA(IndexedDcd, Otc04, Ots08, AddrLong, 6388c2ecf20Sopenharmony_ci BAJustPoint(0), BINovly, BAIndexBase(0))); 6398c2ecf20Sopenharmony_ci NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, 6408c2ecf20Sopenharmony_ci IBOvals(RopSrc, MaskAddrOffset(0), 6418c2ecf20Sopenharmony_ci BitmapExtent08, StaticReg(0), 6428c2ecf20Sopenharmony_ci DataDynamic, MaskOtc, BGx(0), FGx(0))); 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci /* Now prepare to write to the "magic" location */ 6458c2ecf20Sopenharmony_ci fbAddr = NGLE_LONG_FB_ADDRESS(0, 1532, 0); 6468c2ecf20Sopenharmony_ci NGLE_BINC_SET_DSTADDR(fb, fbAddr); 6478c2ecf20Sopenharmony_ci NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffff); 6488c2ecf20Sopenharmony_ci NGLE_BINC_SET_DSTMASK(fb, 0xffffffff); 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci /* Finally, write a zero to clear the mask */ 6518c2ecf20Sopenharmony_ci NGLE_BINC_WRITE32(fb, 0); 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci NGLE_UNLOCK(fb); 6548c2ecf20Sopenharmony_ci} 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_cistatic void 6578c2ecf20Sopenharmony_cingleDepth8_ClearImagePlanes(struct stifb_info *fb) 6588c2ecf20Sopenharmony_ci{ 6598c2ecf20Sopenharmony_ci /* FIXME! */ 6608c2ecf20Sopenharmony_ci} 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_cistatic void 6638c2ecf20Sopenharmony_cingleDepth24_ClearImagePlanes(struct stifb_info *fb) 6648c2ecf20Sopenharmony_ci{ 6658c2ecf20Sopenharmony_ci /* FIXME! */ 6668c2ecf20Sopenharmony_ci} 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_cistatic void 6698c2ecf20Sopenharmony_cingleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg) 6708c2ecf20Sopenharmony_ci{ 6718c2ecf20Sopenharmony_ci int nFreeFifoSlots = 0; 6728c2ecf20Sopenharmony_ci u32 packed_dst; 6738c2ecf20Sopenharmony_ci u32 packed_len; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci NGLE_LOCK(fb); 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci GET_FIFO_SLOTS(fb, nFreeFifoSlots, 4); 6788c2ecf20Sopenharmony_ci NGLE_QUICK_SET_DST_BM_ACCESS(fb, 6798c2ecf20Sopenharmony_ci BA(IndexedDcd, Otc32, OtsIndirect, 6808c2ecf20Sopenharmony_ci AddrLong, BAJustPoint(0), 6818c2ecf20Sopenharmony_ci BINattr, BAIndexBase(0))); 6828c2ecf20Sopenharmony_ci NGLE_QUICK_SET_CTL_PLN_REG(fb, ctlPlaneReg); 6838c2ecf20Sopenharmony_ci NGLE_SET_TRANSFERDATA(fb, 0xffffffff); 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, 6868c2ecf20Sopenharmony_ci IBOvals(RopSrc, MaskAddrOffset(0), 6878c2ecf20Sopenharmony_ci BitmapExtent08, StaticReg(1), 6888c2ecf20Sopenharmony_ci DataDynamic, MaskOtc, 6898c2ecf20Sopenharmony_ci BGx(0), FGx(0))); 6908c2ecf20Sopenharmony_ci packed_dst = 0; 6918c2ecf20Sopenharmony_ci packed_len = (fb->info.var.xres << 16) | fb->info.var.yres; 6928c2ecf20Sopenharmony_ci GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2); 6938c2ecf20Sopenharmony_ci NGLE_SET_DSTXY(fb, packed_dst); 6948c2ecf20Sopenharmony_ci SET_LENXY_START_RECFILL(fb, packed_len); 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci /* 6978c2ecf20Sopenharmony_ci * In order to work around an ELK hardware problem (Buffy doesn't 6988c2ecf20Sopenharmony_ci * always flush it's buffers when writing to the attribute 6998c2ecf20Sopenharmony_ci * planes), at least 4 pixels must be written to the attribute 7008c2ecf20Sopenharmony_ci * planes starting at (X == 1280) and (Y != to the last Y written 7018c2ecf20Sopenharmony_ci * by BIF): 7028c2ecf20Sopenharmony_ci */ 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci if (fb->id == S9000_ID_A1659A) { /* ELK_DEVICE_ID */ 7058c2ecf20Sopenharmony_ci /* It's safe to use scanline zero: */ 7068c2ecf20Sopenharmony_ci packed_dst = (1280 << 16); 7078c2ecf20Sopenharmony_ci GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2); 7088c2ecf20Sopenharmony_ci NGLE_SET_DSTXY(fb, packed_dst); 7098c2ecf20Sopenharmony_ci packed_len = (4 << 16) | 1; 7108c2ecf20Sopenharmony_ci SET_LENXY_START_RECFILL(fb, packed_len); 7118c2ecf20Sopenharmony_ci } /* ELK Hardware Kludge */ 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci /**** Finally, set the Control Plane Register back to zero: ****/ 7148c2ecf20Sopenharmony_ci GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1); 7158c2ecf20Sopenharmony_ci NGLE_QUICK_SET_CTL_PLN_REG(fb, 0); 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci NGLE_UNLOCK(fb); 7188c2ecf20Sopenharmony_ci} 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_cistatic void 7218c2ecf20Sopenharmony_cingleClearOverlayPlanes(struct stifb_info *fb, int mask, int data) 7228c2ecf20Sopenharmony_ci{ 7238c2ecf20Sopenharmony_ci int nFreeFifoSlots = 0; 7248c2ecf20Sopenharmony_ci u32 packed_dst; 7258c2ecf20Sopenharmony_ci u32 packed_len; 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_ci NGLE_LOCK(fb); 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci /* Hardware setup */ 7308c2ecf20Sopenharmony_ci GET_FIFO_SLOTS(fb, nFreeFifoSlots, 8); 7318c2ecf20Sopenharmony_ci NGLE_QUICK_SET_DST_BM_ACCESS(fb, 7328c2ecf20Sopenharmony_ci BA(IndexedDcd, Otc04, Ots08, AddrLong, 7338c2ecf20Sopenharmony_ci BAJustPoint(0), BINovly, BAIndexBase(0))); 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci NGLE_SET_TRANSFERDATA(fb, 0xffffffff); /* Write foreground color */ 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_ci NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, data); 7388c2ecf20Sopenharmony_ci NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask); 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci packed_dst = 0; 7418c2ecf20Sopenharmony_ci packed_len = (fb->info.var.xres << 16) | fb->info.var.yres; 7428c2ecf20Sopenharmony_ci NGLE_SET_DSTXY(fb, packed_dst); 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_ci /* Write zeroes to overlay planes */ 7458c2ecf20Sopenharmony_ci NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, 7468c2ecf20Sopenharmony_ci IBOvals(RopSrc, MaskAddrOffset(0), 7478c2ecf20Sopenharmony_ci BitmapExtent08, StaticReg(0), 7488c2ecf20Sopenharmony_ci DataDynamic, MaskOtc, BGx(0), FGx(0))); 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci SET_LENXY_START_RECFILL(fb, packed_len); 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci NGLE_UNLOCK(fb); 7538c2ecf20Sopenharmony_ci} 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_cistatic void 7568c2ecf20Sopenharmony_cihyperResetPlanes(struct stifb_info *fb, int enable) 7578c2ecf20Sopenharmony_ci{ 7588c2ecf20Sopenharmony_ci unsigned int controlPlaneReg; 7598c2ecf20Sopenharmony_ci 7608c2ecf20Sopenharmony_ci NGLE_LOCK(fb); 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_ci if (IS_24_DEVICE(fb)) 7638c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 32) 7648c2ecf20Sopenharmony_ci controlPlaneReg = 0x04000F00; 7658c2ecf20Sopenharmony_ci else 7668c2ecf20Sopenharmony_ci controlPlaneReg = 0x00000F00; /* 0x00000800 should be enough, but lets clear all 4 bits */ 7678c2ecf20Sopenharmony_ci else 7688c2ecf20Sopenharmony_ci controlPlaneReg = 0x00000F00; /* 0x00000100 should be enough, but lets clear all 4 bits */ 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_ci switch (enable) { 7718c2ecf20Sopenharmony_ci case ENABLE: 7728c2ecf20Sopenharmony_ci /* clear screen */ 7738c2ecf20Sopenharmony_ci if (IS_24_DEVICE(fb)) 7748c2ecf20Sopenharmony_ci ngleDepth24_ClearImagePlanes(fb); 7758c2ecf20Sopenharmony_ci else 7768c2ecf20Sopenharmony_ci ngleDepth8_ClearImagePlanes(fb); 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci /* Paint attribute planes for default case. 7798c2ecf20Sopenharmony_ci * On Hyperdrive, this means all windows using overlay cmap 0. */ 7808c2ecf20Sopenharmony_ci ngleResetAttrPlanes(fb, controlPlaneReg); 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci /* clear overlay planes */ 7838c2ecf20Sopenharmony_ci ngleClearOverlayPlanes(fb, 0xff, 255); 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci /************************************************** 7868c2ecf20Sopenharmony_ci ** Also need to counteract ITE settings 7878c2ecf20Sopenharmony_ci **************************************************/ 7888c2ecf20Sopenharmony_ci hyperUndoITE(fb); 7898c2ecf20Sopenharmony_ci break; 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci case DISABLE: 7928c2ecf20Sopenharmony_ci /* clear screen */ 7938c2ecf20Sopenharmony_ci if (IS_24_DEVICE(fb)) 7948c2ecf20Sopenharmony_ci ngleDepth24_ClearImagePlanes(fb); 7958c2ecf20Sopenharmony_ci else 7968c2ecf20Sopenharmony_ci ngleDepth8_ClearImagePlanes(fb); 7978c2ecf20Sopenharmony_ci ngleResetAttrPlanes(fb, controlPlaneReg); 7988c2ecf20Sopenharmony_ci ngleClearOverlayPlanes(fb, 0xff, 0); 7998c2ecf20Sopenharmony_ci break; 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci case -1: /* RESET */ 8028c2ecf20Sopenharmony_ci hyperUndoITE(fb); 8038c2ecf20Sopenharmony_ci ngleResetAttrPlanes(fb, controlPlaneReg); 8048c2ecf20Sopenharmony_ci break; 8058c2ecf20Sopenharmony_ci } 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ci NGLE_UNLOCK(fb); 8088c2ecf20Sopenharmony_ci} 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */ 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_cistatic void 8138c2ecf20Sopenharmony_cingleGetDeviceRomData(struct stifb_info *fb) 8148c2ecf20Sopenharmony_ci{ 8158c2ecf20Sopenharmony_ci#if 0 8168c2ecf20Sopenharmony_ciXXX: FIXME: !!! 8178c2ecf20Sopenharmony_ci int *pBytePerLongDevDepData;/* data byte == LSB */ 8188c2ecf20Sopenharmony_ci int *pRomTable; 8198c2ecf20Sopenharmony_ci NgleDevRomData *pPackedDevRomData; 8208c2ecf20Sopenharmony_ci int sizePackedDevRomData = sizeof(*pPackedDevRomData); 8218c2ecf20Sopenharmony_ci char *pCard8; 8228c2ecf20Sopenharmony_ci int i; 8238c2ecf20Sopenharmony_ci char *mapOrigin = NULL; 8248c2ecf20Sopenharmony_ci 8258c2ecf20Sopenharmony_ci int romTableIdx; 8268c2ecf20Sopenharmony_ci 8278c2ecf20Sopenharmony_ci pPackedDevRomData = fb->ngle_rom; 8288c2ecf20Sopenharmony_ci 8298c2ecf20Sopenharmony_ci SETUP_HW(fb); 8308c2ecf20Sopenharmony_ci if (fb->id == S9000_ID_ARTIST) { 8318c2ecf20Sopenharmony_ci pPackedDevRomData->cursor_pipeline_delay = 4; 8328c2ecf20Sopenharmony_ci pPackedDevRomData->video_interleaves = 4; 8338c2ecf20Sopenharmony_ci } else { 8348c2ecf20Sopenharmony_ci /* Get pointer to unpacked byte/long data in ROM */ 8358c2ecf20Sopenharmony_ci pBytePerLongDevDepData = fb->sti->regions[NGLEDEVDEPROM_CRT_REGION]; 8368c2ecf20Sopenharmony_ci 8378c2ecf20Sopenharmony_ci /* Tomcat supports several resolutions: 1280x1024, 1024x768, 640x480 */ 8388c2ecf20Sopenharmony_ci if (fb->id == S9000_ID_TOMCAT) 8398c2ecf20Sopenharmony_ci { 8408c2ecf20Sopenharmony_ci /* jump to the correct ROM table */ 8418c2ecf20Sopenharmony_ci GET_ROMTABLE_INDEX(romTableIdx); 8428c2ecf20Sopenharmony_ci while (romTableIdx > 0) 8438c2ecf20Sopenharmony_ci { 8448c2ecf20Sopenharmony_ci pCard8 = (Card8 *) pPackedDevRomData; 8458c2ecf20Sopenharmony_ci pRomTable = pBytePerLongDevDepData; 8468c2ecf20Sopenharmony_ci /* Pack every fourth byte from ROM into structure */ 8478c2ecf20Sopenharmony_ci for (i = 0; i < sizePackedDevRomData; i++) 8488c2ecf20Sopenharmony_ci { 8498c2ecf20Sopenharmony_ci *pCard8++ = (Card8) (*pRomTable++); 8508c2ecf20Sopenharmony_ci } 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci pBytePerLongDevDepData = (Card32 *) 8538c2ecf20Sopenharmony_ci ((Card8 *) pBytePerLongDevDepData + 8548c2ecf20Sopenharmony_ci pPackedDevRomData->sizeof_ngle_data); 8558c2ecf20Sopenharmony_ci 8568c2ecf20Sopenharmony_ci romTableIdx--; 8578c2ecf20Sopenharmony_ci } 8588c2ecf20Sopenharmony_ci } 8598c2ecf20Sopenharmony_ci 8608c2ecf20Sopenharmony_ci pCard8 = (Card8 *) pPackedDevRomData; 8618c2ecf20Sopenharmony_ci 8628c2ecf20Sopenharmony_ci /* Pack every fourth byte from ROM into structure */ 8638c2ecf20Sopenharmony_ci for (i = 0; i < sizePackedDevRomData; i++) 8648c2ecf20Sopenharmony_ci { 8658c2ecf20Sopenharmony_ci *pCard8++ = (Card8) (*pBytePerLongDevDepData++); 8668c2ecf20Sopenharmony_ci } 8678c2ecf20Sopenharmony_ci } 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci SETUP_FB(fb); 8708c2ecf20Sopenharmony_ci#endif 8718c2ecf20Sopenharmony_ci} 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_ci 8748c2ecf20Sopenharmony_ci#define HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES 4 8758c2ecf20Sopenharmony_ci#define HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE 8 8768c2ecf20Sopenharmony_ci#define HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE 10 8778c2ecf20Sopenharmony_ci#define HYPERBOWL_MODE2_8_24 15 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci/* HCRX specific boot-time initialization */ 8808c2ecf20Sopenharmony_cistatic void __init 8818c2ecf20Sopenharmony_ciSETUP_HCRX(struct stifb_info *fb) 8828c2ecf20Sopenharmony_ci{ 8838c2ecf20Sopenharmony_ci int hyperbowl; 8848c2ecf20Sopenharmony_ci int nFreeFifoSlots = 0; 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci if (fb->id != S9000_ID_HCRX) 8878c2ecf20Sopenharmony_ci return; 8888c2ecf20Sopenharmony_ci 8898c2ecf20Sopenharmony_ci /* Initialize Hyperbowl registers */ 8908c2ecf20Sopenharmony_ci GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7); 8918c2ecf20Sopenharmony_ci 8928c2ecf20Sopenharmony_ci if (IS_24_DEVICE(fb)) { 8938c2ecf20Sopenharmony_ci hyperbowl = (fb->info.var.bits_per_pixel == 32) ? 8948c2ecf20Sopenharmony_ci HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE : 8958c2ecf20Sopenharmony_ci HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE; 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci /* First write to Hyperbowl must happen twice (bug) */ 8988c2ecf20Sopenharmony_ci WRITE_WORD(hyperbowl, fb, REG_40); 8998c2ecf20Sopenharmony_ci WRITE_WORD(hyperbowl, fb, REG_40); 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_ci WRITE_WORD(HYPERBOWL_MODE2_8_24, fb, REG_39); 9028c2ecf20Sopenharmony_ci 9038c2ecf20Sopenharmony_ci WRITE_WORD(0x014c0148, fb, REG_42); /* Set lut 0 to be the direct color */ 9048c2ecf20Sopenharmony_ci WRITE_WORD(0x404c4048, fb, REG_43); 9058c2ecf20Sopenharmony_ci WRITE_WORD(0x034c0348, fb, REG_44); 9068c2ecf20Sopenharmony_ci WRITE_WORD(0x444c4448, fb, REG_45); 9078c2ecf20Sopenharmony_ci } else { 9088c2ecf20Sopenharmony_ci hyperbowl = HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES; 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_ci /* First write to Hyperbowl must happen twice (bug) */ 9118c2ecf20Sopenharmony_ci WRITE_WORD(hyperbowl, fb, REG_40); 9128c2ecf20Sopenharmony_ci WRITE_WORD(hyperbowl, fb, REG_40); 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_ci WRITE_WORD(0x00000000, fb, REG_42); 9158c2ecf20Sopenharmony_ci WRITE_WORD(0x00000000, fb, REG_43); 9168c2ecf20Sopenharmony_ci WRITE_WORD(0x00000000, fb, REG_44); 9178c2ecf20Sopenharmony_ci WRITE_WORD(0x444c4048, fb, REG_45); 9188c2ecf20Sopenharmony_ci } 9198c2ecf20Sopenharmony_ci} 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_ci/* ------------------- driver specific functions --------------------------- */ 9238c2ecf20Sopenharmony_ci 9248c2ecf20Sopenharmony_cistatic int 9258c2ecf20Sopenharmony_cistifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 9268c2ecf20Sopenharmony_ci{ 9278c2ecf20Sopenharmony_ci struct stifb_info *fb = container_of(info, struct stifb_info, info); 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_ci if (var->xres != fb->info.var.xres || 9308c2ecf20Sopenharmony_ci var->yres != fb->info.var.yres || 9318c2ecf20Sopenharmony_ci var->bits_per_pixel != fb->info.var.bits_per_pixel) 9328c2ecf20Sopenharmony_ci return -EINVAL; 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ci var->xres_virtual = var->xres; 9358c2ecf20Sopenharmony_ci var->yres_virtual = var->yres; 9368c2ecf20Sopenharmony_ci var->xoffset = 0; 9378c2ecf20Sopenharmony_ci var->yoffset = 0; 9388c2ecf20Sopenharmony_ci var->grayscale = fb->info.var.grayscale; 9398c2ecf20Sopenharmony_ci var->red.length = fb->info.var.red.length; 9408c2ecf20Sopenharmony_ci var->green.length = fb->info.var.green.length; 9418c2ecf20Sopenharmony_ci var->blue.length = fb->info.var.blue.length; 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci return 0; 9448c2ecf20Sopenharmony_ci} 9458c2ecf20Sopenharmony_ci 9468c2ecf20Sopenharmony_cistatic int 9478c2ecf20Sopenharmony_cistifb_setcolreg(u_int regno, u_int red, u_int green, 9488c2ecf20Sopenharmony_ci u_int blue, u_int transp, struct fb_info *info) 9498c2ecf20Sopenharmony_ci{ 9508c2ecf20Sopenharmony_ci struct stifb_info *fb = container_of(info, struct stifb_info, info); 9518c2ecf20Sopenharmony_ci u32 color; 9528c2ecf20Sopenharmony_ci 9538c2ecf20Sopenharmony_ci if (regno >= NR_PALETTE) 9548c2ecf20Sopenharmony_ci return 1; 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_ci red >>= 8; 9578c2ecf20Sopenharmony_ci green >>= 8; 9588c2ecf20Sopenharmony_ci blue >>= 8; 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_ci DEBUG_OFF(); 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_ci START_IMAGE_COLORMAP_ACCESS(fb); 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_ci if (unlikely(fb->info.var.grayscale)) { 9658c2ecf20Sopenharmony_ci /* gray = 0.30*R + 0.59*G + 0.11*B */ 9668c2ecf20Sopenharmony_ci color = ((red * 77) + 9678c2ecf20Sopenharmony_ci (green * 151) + 9688c2ecf20Sopenharmony_ci (blue * 28)) >> 8; 9698c2ecf20Sopenharmony_ci } else { 9708c2ecf20Sopenharmony_ci color = ((red << 16) | 9718c2ecf20Sopenharmony_ci (green << 8) | 9728c2ecf20Sopenharmony_ci (blue)); 9738c2ecf20Sopenharmony_ci } 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_ci if (fb->info.fix.visual == FB_VISUAL_DIRECTCOLOR) { 9768c2ecf20Sopenharmony_ci struct fb_var_screeninfo *var = &fb->info.var; 9778c2ecf20Sopenharmony_ci if (regno < 16) 9788c2ecf20Sopenharmony_ci ((u32 *)fb->info.pseudo_palette)[regno] = 9798c2ecf20Sopenharmony_ci regno << var->red.offset | 9808c2ecf20Sopenharmony_ci regno << var->green.offset | 9818c2ecf20Sopenharmony_ci regno << var->blue.offset; 9828c2ecf20Sopenharmony_ci } 9838c2ecf20Sopenharmony_ci 9848c2ecf20Sopenharmony_ci WRITE_IMAGE_COLOR(fb, regno, color); 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci if (fb->id == S9000_ID_HCRX) { 9878c2ecf20Sopenharmony_ci NgleLutBltCtl lutBltCtl; 9888c2ecf20Sopenharmony_ci 9898c2ecf20Sopenharmony_ci lutBltCtl = setHyperLutBltCtl(fb, 9908c2ecf20Sopenharmony_ci 0, /* Offset w/i LUT */ 9918c2ecf20Sopenharmony_ci 256); /* Load entire LUT */ 9928c2ecf20Sopenharmony_ci NGLE_BINC_SET_SRCADDR(fb, 9938c2ecf20Sopenharmony_ci NGLE_LONG_FB_ADDRESS(0, 0x100, 0)); 9948c2ecf20Sopenharmony_ci /* 0x100 is same as used in WRITE_IMAGE_COLOR() */ 9958c2ecf20Sopenharmony_ci START_COLORMAPLOAD(fb, lutBltCtl.all); 9968c2ecf20Sopenharmony_ci SETUP_FB(fb); 9978c2ecf20Sopenharmony_ci } else { 9988c2ecf20Sopenharmony_ci /* cleanup colormap hardware */ 9998c2ecf20Sopenharmony_ci FINISH_IMAGE_COLORMAP_ACCESS(fb); 10008c2ecf20Sopenharmony_ci } 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci DEBUG_ON(); 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci return 0; 10058c2ecf20Sopenharmony_ci} 10068c2ecf20Sopenharmony_ci 10078c2ecf20Sopenharmony_cistatic int 10088c2ecf20Sopenharmony_cistifb_blank(int blank_mode, struct fb_info *info) 10098c2ecf20Sopenharmony_ci{ 10108c2ecf20Sopenharmony_ci struct stifb_info *fb = container_of(info, struct stifb_info, info); 10118c2ecf20Sopenharmony_ci int enable = (blank_mode == 0) ? ENABLE : DISABLE; 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci switch (fb->id) { 10148c2ecf20Sopenharmony_ci case S9000_ID_A1439A: 10158c2ecf20Sopenharmony_ci CRX24_ENABLE_DISABLE_DISPLAY(fb, enable); 10168c2ecf20Sopenharmony_ci break; 10178c2ecf20Sopenharmony_ci case CRT_ID_VISUALIZE_EG: 10188c2ecf20Sopenharmony_ci case S9000_ID_ARTIST: 10198c2ecf20Sopenharmony_ci ARTIST_ENABLE_DISABLE_DISPLAY(fb, enable); 10208c2ecf20Sopenharmony_ci break; 10218c2ecf20Sopenharmony_ci case S9000_ID_HCRX: 10228c2ecf20Sopenharmony_ci HYPER_ENABLE_DISABLE_DISPLAY(fb, enable); 10238c2ecf20Sopenharmony_ci break; 10248c2ecf20Sopenharmony_ci case S9000_ID_A1659A: 10258c2ecf20Sopenharmony_ci case S9000_ID_TIMBER: 10268c2ecf20Sopenharmony_ci case CRX24_OVERLAY_PLANES: 10278c2ecf20Sopenharmony_ci default: 10288c2ecf20Sopenharmony_ci ENABLE_DISABLE_DISPLAY(fb, enable); 10298c2ecf20Sopenharmony_ci break; 10308c2ecf20Sopenharmony_ci } 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_ci SETUP_FB(fb); 10338c2ecf20Sopenharmony_ci return 0; 10348c2ecf20Sopenharmony_ci} 10358c2ecf20Sopenharmony_ci 10368c2ecf20Sopenharmony_cistatic void 10378c2ecf20Sopenharmony_cistifb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 10388c2ecf20Sopenharmony_ci{ 10398c2ecf20Sopenharmony_ci struct stifb_info *fb = container_of(info, struct stifb_info, info); 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_ci SETUP_COPYAREA(fb); 10428c2ecf20Sopenharmony_ci 10438c2ecf20Sopenharmony_ci SETUP_HW(fb); 10448c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 32) { 10458c2ecf20Sopenharmony_ci WRITE_WORD(0xBBA0A000, fb, REG_10); 10468c2ecf20Sopenharmony_ci 10478c2ecf20Sopenharmony_ci NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff); 10488c2ecf20Sopenharmony_ci } else { 10498c2ecf20Sopenharmony_ci WRITE_WORD(fb->id == S9000_ID_HCRX ? 0x13a02000 : 0x13a01000, fb, REG_10); 10508c2ecf20Sopenharmony_ci 10518c2ecf20Sopenharmony_ci NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xff); 10528c2ecf20Sopenharmony_ci } 10538c2ecf20Sopenharmony_ci 10548c2ecf20Sopenharmony_ci NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, 10558c2ecf20Sopenharmony_ci IBOvals(RopSrc, MaskAddrOffset(0), 10568c2ecf20Sopenharmony_ci BitmapExtent08, StaticReg(1), 10578c2ecf20Sopenharmony_ci DataDynamic, MaskOtc, BGx(0), FGx(0))); 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_ci WRITE_WORD(((area->sx << 16) | area->sy), fb, REG_24); 10608c2ecf20Sopenharmony_ci WRITE_WORD(((area->width << 16) | area->height), fb, REG_7); 10618c2ecf20Sopenharmony_ci WRITE_WORD(((area->dx << 16) | area->dy), fb, REG_25); 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_ci SETUP_FB(fb); 10648c2ecf20Sopenharmony_ci} 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_ci#define ARTIST_VRAM_SIZE 0x000804 10678c2ecf20Sopenharmony_ci#define ARTIST_VRAM_SRC 0x000808 10688c2ecf20Sopenharmony_ci#define ARTIST_VRAM_SIZE_TRIGGER_WINFILL 0x000a04 10698c2ecf20Sopenharmony_ci#define ARTIST_VRAM_DEST_TRIGGER_BLOCKMOVE 0x000b00 10708c2ecf20Sopenharmony_ci#define ARTIST_SRC_BM_ACCESS 0x018008 10718c2ecf20Sopenharmony_ci#define ARTIST_FGCOLOR 0x018010 10728c2ecf20Sopenharmony_ci#define ARTIST_BGCOLOR 0x018014 10738c2ecf20Sopenharmony_ci#define ARTIST_BITMAP_OP 0x01801c 10748c2ecf20Sopenharmony_ci 10758c2ecf20Sopenharmony_cistatic void 10768c2ecf20Sopenharmony_cistifb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 10778c2ecf20Sopenharmony_ci{ 10788c2ecf20Sopenharmony_ci struct stifb_info *fb = container_of(info, struct stifb_info, info); 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_ci if (rect->rop != ROP_COPY || 10818c2ecf20Sopenharmony_ci (fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32)) 10828c2ecf20Sopenharmony_ci return cfb_fillrect(info, rect); 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_ci SETUP_HW(fb); 10858c2ecf20Sopenharmony_ci 10868c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 32) { 10878c2ecf20Sopenharmony_ci WRITE_WORD(0xBBA0A000, fb, REG_10); 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff); 10908c2ecf20Sopenharmony_ci } else { 10918c2ecf20Sopenharmony_ci WRITE_WORD(fb->id == S9000_ID_HCRX ? 0x13a02000 : 0x13a01000, fb, REG_10); 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xff); 10948c2ecf20Sopenharmony_ci } 10958c2ecf20Sopenharmony_ci 10968c2ecf20Sopenharmony_ci WRITE_WORD(0x03000300, fb, ARTIST_BITMAP_OP); 10978c2ecf20Sopenharmony_ci WRITE_WORD(0x2ea01000, fb, ARTIST_SRC_BM_ACCESS); 10988c2ecf20Sopenharmony_ci NGLE_QUICK_SET_DST_BM_ACCESS(fb, 0x2ea01000); 10998c2ecf20Sopenharmony_ci NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, rect->color); 11008c2ecf20Sopenharmony_ci WRITE_WORD(0, fb, ARTIST_BGCOLOR); 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_ci NGLE_SET_DSTXY(fb, (rect->dx << 16) | (rect->dy)); 11038c2ecf20Sopenharmony_ci SET_LENXY_START_RECFILL(fb, (rect->width << 16) | (rect->height)); 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_ci SETUP_FB(fb); 11068c2ecf20Sopenharmony_ci} 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_cistatic void __init 11098c2ecf20Sopenharmony_cistifb_init_display(struct stifb_info *fb) 11108c2ecf20Sopenharmony_ci{ 11118c2ecf20Sopenharmony_ci int id = fb->id; 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_ci SETUP_FB(fb); 11148c2ecf20Sopenharmony_ci 11158c2ecf20Sopenharmony_ci /* HCRX specific initialization */ 11168c2ecf20Sopenharmony_ci SETUP_HCRX(fb); 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_ci /* 11198c2ecf20Sopenharmony_ci if (id == S9000_ID_HCRX) 11208c2ecf20Sopenharmony_ci hyperInitSprite(fb); 11218c2ecf20Sopenharmony_ci else 11228c2ecf20Sopenharmony_ci ngleInitSprite(fb); 11238c2ecf20Sopenharmony_ci */ 11248c2ecf20Sopenharmony_ci 11258c2ecf20Sopenharmony_ci /* Initialize the image planes. */ 11268c2ecf20Sopenharmony_ci switch (id) { 11278c2ecf20Sopenharmony_ci case S9000_ID_HCRX: 11288c2ecf20Sopenharmony_ci hyperResetPlanes(fb, ENABLE); 11298c2ecf20Sopenharmony_ci break; 11308c2ecf20Sopenharmony_ci case S9000_ID_A1439A: 11318c2ecf20Sopenharmony_ci rattlerSetupPlanes(fb); 11328c2ecf20Sopenharmony_ci break; 11338c2ecf20Sopenharmony_ci case S9000_ID_A1659A: 11348c2ecf20Sopenharmony_ci case S9000_ID_ARTIST: 11358c2ecf20Sopenharmony_ci case CRT_ID_VISUALIZE_EG: 11368c2ecf20Sopenharmony_ci elkSetupPlanes(fb); 11378c2ecf20Sopenharmony_ci break; 11388c2ecf20Sopenharmony_ci } 11398c2ecf20Sopenharmony_ci 11408c2ecf20Sopenharmony_ci /* Clear attribute planes on non HCRX devices. */ 11418c2ecf20Sopenharmony_ci switch (id) { 11428c2ecf20Sopenharmony_ci case S9000_ID_A1659A: 11438c2ecf20Sopenharmony_ci case S9000_ID_A1439A: 11448c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 32) 11458c2ecf20Sopenharmony_ci ngleSetupAttrPlanes(fb, BUFF1_CMAP3); 11468c2ecf20Sopenharmony_ci else { 11478c2ecf20Sopenharmony_ci ngleSetupAttrPlanes(fb, BUFF1_CMAP0); 11488c2ecf20Sopenharmony_ci } 11498c2ecf20Sopenharmony_ci if (id == S9000_ID_A1439A) 11508c2ecf20Sopenharmony_ci ngleClearOverlayPlanes(fb, 0xff, 0); 11518c2ecf20Sopenharmony_ci break; 11528c2ecf20Sopenharmony_ci case S9000_ID_ARTIST: 11538c2ecf20Sopenharmony_ci case CRT_ID_VISUALIZE_EG: 11548c2ecf20Sopenharmony_ci if (fb->info.var.bits_per_pixel == 32) 11558c2ecf20Sopenharmony_ci ngleSetupAttrPlanes(fb, BUFF1_CMAP3); 11568c2ecf20Sopenharmony_ci else { 11578c2ecf20Sopenharmony_ci ngleSetupAttrPlanes(fb, ARTIST_CMAP0); 11588c2ecf20Sopenharmony_ci } 11598c2ecf20Sopenharmony_ci break; 11608c2ecf20Sopenharmony_ci } 11618c2ecf20Sopenharmony_ci stifb_blank(0, (struct fb_info *)fb); /* 0=enable screen */ 11628c2ecf20Sopenharmony_ci 11638c2ecf20Sopenharmony_ci SETUP_FB(fb); 11648c2ecf20Sopenharmony_ci} 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_ci/* ------------ Interfaces to hardware functions ------------ */ 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_cistatic const struct fb_ops stifb_ops = { 11698c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11708c2ecf20Sopenharmony_ci .fb_check_var = stifb_check_var, 11718c2ecf20Sopenharmony_ci .fb_setcolreg = stifb_setcolreg, 11728c2ecf20Sopenharmony_ci .fb_blank = stifb_blank, 11738c2ecf20Sopenharmony_ci .fb_fillrect = stifb_fillrect, 11748c2ecf20Sopenharmony_ci .fb_copyarea = stifb_copyarea, 11758c2ecf20Sopenharmony_ci .fb_imageblit = cfb_imageblit, 11768c2ecf20Sopenharmony_ci}; 11778c2ecf20Sopenharmony_ci 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_ci/* 11808c2ecf20Sopenharmony_ci * Initialization 11818c2ecf20Sopenharmony_ci */ 11828c2ecf20Sopenharmony_ci 11838c2ecf20Sopenharmony_cistatic int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) 11848c2ecf20Sopenharmony_ci{ 11858c2ecf20Sopenharmony_ci struct fb_fix_screeninfo *fix; 11868c2ecf20Sopenharmony_ci struct fb_var_screeninfo *var; 11878c2ecf20Sopenharmony_ci struct stifb_info *fb; 11888c2ecf20Sopenharmony_ci struct fb_info *info; 11898c2ecf20Sopenharmony_ci unsigned long sti_rom_address; 11908c2ecf20Sopenharmony_ci char modestr[32]; 11918c2ecf20Sopenharmony_ci char *dev_name; 11928c2ecf20Sopenharmony_ci int bpp, xres, yres; 11938c2ecf20Sopenharmony_ci 11948c2ecf20Sopenharmony_ci fb = kzalloc(sizeof(*fb), GFP_ATOMIC); 11958c2ecf20Sopenharmony_ci if (!fb) 11968c2ecf20Sopenharmony_ci return -ENOMEM; 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci info = &fb->info; 11998c2ecf20Sopenharmony_ci 12008c2ecf20Sopenharmony_ci /* set struct to a known state */ 12018c2ecf20Sopenharmony_ci fix = &info->fix; 12028c2ecf20Sopenharmony_ci var = &info->var; 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci fb->sti = sti; 12058c2ecf20Sopenharmony_ci dev_name = sti->sti_data->inq_outptr.dev_name; 12068c2ecf20Sopenharmony_ci /* store upper 32bits of the graphics id */ 12078c2ecf20Sopenharmony_ci fb->id = fb->sti->graphics_id[0]; 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci /* only supported cards are allowed */ 12108c2ecf20Sopenharmony_ci switch (fb->id) { 12118c2ecf20Sopenharmony_ci case CRT_ID_VISUALIZE_EG: 12128c2ecf20Sopenharmony_ci /* Visualize cards can run either in "double buffer" or 12138c2ecf20Sopenharmony_ci "standard" mode. Depending on the mode, the card reports 12148c2ecf20Sopenharmony_ci a different device name, e.g. "INTERNAL_EG_DX1024" in double 12158c2ecf20Sopenharmony_ci buffer mode and "INTERNAL_EG_X1024" in standard mode. 12168c2ecf20Sopenharmony_ci Since this driver only supports standard mode, we check 12178c2ecf20Sopenharmony_ci if the device name contains the string "DX" and tell the 12188c2ecf20Sopenharmony_ci user how to reconfigure the card. */ 12198c2ecf20Sopenharmony_ci if (strstr(dev_name, "DX")) { 12208c2ecf20Sopenharmony_ci printk(KERN_WARNING 12218c2ecf20Sopenharmony_ci"WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n" 12228c2ecf20Sopenharmony_ci"WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n", 12238c2ecf20Sopenharmony_ci dev_name); 12248c2ecf20Sopenharmony_ci goto out_err0; 12258c2ecf20Sopenharmony_ci } 12268c2ecf20Sopenharmony_ci fallthrough; 12278c2ecf20Sopenharmony_ci case S9000_ID_ARTIST: 12288c2ecf20Sopenharmony_ci case S9000_ID_HCRX: 12298c2ecf20Sopenharmony_ci case S9000_ID_TIMBER: 12308c2ecf20Sopenharmony_ci case S9000_ID_A1659A: 12318c2ecf20Sopenharmony_ci case S9000_ID_A1439A: 12328c2ecf20Sopenharmony_ci break; 12338c2ecf20Sopenharmony_ci default: 12348c2ecf20Sopenharmony_ci printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n", 12358c2ecf20Sopenharmony_ci dev_name, fb->id); 12368c2ecf20Sopenharmony_ci goto out_err0; 12378c2ecf20Sopenharmony_ci } 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_ci /* default to 8 bpp on most graphic chips */ 12408c2ecf20Sopenharmony_ci bpp = 8; 12418c2ecf20Sopenharmony_ci xres = sti_onscreen_x(fb->sti); 12428c2ecf20Sopenharmony_ci yres = sti_onscreen_y(fb->sti); 12438c2ecf20Sopenharmony_ci 12448c2ecf20Sopenharmony_ci ngleGetDeviceRomData(fb); 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_ci /* get (virtual) io region base addr */ 12478c2ecf20Sopenharmony_ci fix->mmio_start = REGION_BASE(fb,2); 12488c2ecf20Sopenharmony_ci fix->mmio_len = 0x400000; 12498c2ecf20Sopenharmony_ci 12508c2ecf20Sopenharmony_ci /* Reject any device not in the NGLE family */ 12518c2ecf20Sopenharmony_ci switch (fb->id) { 12528c2ecf20Sopenharmony_ci case S9000_ID_A1659A: /* CRX/A1659A */ 12538c2ecf20Sopenharmony_ci break; 12548c2ecf20Sopenharmony_ci case S9000_ID_ELM: /* GRX, grayscale but else same as A1659A */ 12558c2ecf20Sopenharmony_ci var->grayscale = 1; 12568c2ecf20Sopenharmony_ci fb->id = S9000_ID_A1659A; 12578c2ecf20Sopenharmony_ci break; 12588c2ecf20Sopenharmony_ci case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */ 12598c2ecf20Sopenharmony_ci if (strstr(dev_name, "GRAYSCALE") || 12608c2ecf20Sopenharmony_ci strstr(dev_name, "Grayscale") || 12618c2ecf20Sopenharmony_ci strstr(dev_name, "grayscale")) 12628c2ecf20Sopenharmony_ci var->grayscale = 1; 12638c2ecf20Sopenharmony_ci break; 12648c2ecf20Sopenharmony_ci case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */ 12658c2ecf20Sopenharmony_ci /* FIXME: TomCat supports two heads: 12668c2ecf20Sopenharmony_ci * fb.iobase = REGION_BASE(fb_info,3); 12678c2ecf20Sopenharmony_ci * fb.screen_base = ioremap(REGION_BASE(fb_info,2),xxx); 12688c2ecf20Sopenharmony_ci * for now we only support the left one ! */ 12698c2ecf20Sopenharmony_ci xres = fb->ngle_rom.x_size_visible; 12708c2ecf20Sopenharmony_ci yres = fb->ngle_rom.y_size_visible; 12718c2ecf20Sopenharmony_ci fb->id = S9000_ID_A1659A; 12728c2ecf20Sopenharmony_ci break; 12738c2ecf20Sopenharmony_ci case S9000_ID_A1439A: /* CRX24/A1439A */ 12748c2ecf20Sopenharmony_ci bpp = 32; 12758c2ecf20Sopenharmony_ci break; 12768c2ecf20Sopenharmony_ci case S9000_ID_HCRX: /* Hyperdrive/HCRX */ 12778c2ecf20Sopenharmony_ci memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom)); 12788c2ecf20Sopenharmony_ci if ((fb->sti->regions_phys[0] & 0xfc000000) == 12798c2ecf20Sopenharmony_ci (fb->sti->regions_phys[2] & 0xfc000000)) 12808c2ecf20Sopenharmony_ci sti_rom_address = F_EXTEND(fb->sti->regions_phys[0]); 12818c2ecf20Sopenharmony_ci else 12828c2ecf20Sopenharmony_ci sti_rom_address = F_EXTEND(fb->sti->regions_phys[1]); 12838c2ecf20Sopenharmony_ci 12848c2ecf20Sopenharmony_ci fb->deviceSpecificConfig = gsc_readl(sti_rom_address); 12858c2ecf20Sopenharmony_ci if (IS_24_DEVICE(fb)) { 12868c2ecf20Sopenharmony_ci if (bpp_pref == 8 || bpp_pref == 32) 12878c2ecf20Sopenharmony_ci bpp = bpp_pref; 12888c2ecf20Sopenharmony_ci else 12898c2ecf20Sopenharmony_ci bpp = 32; 12908c2ecf20Sopenharmony_ci } else 12918c2ecf20Sopenharmony_ci bpp = 8; 12928c2ecf20Sopenharmony_ci READ_WORD(fb, REG_15); 12938c2ecf20Sopenharmony_ci SETUP_HW(fb); 12948c2ecf20Sopenharmony_ci break; 12958c2ecf20Sopenharmony_ci case CRT_ID_VISUALIZE_EG: 12968c2ecf20Sopenharmony_ci case S9000_ID_ARTIST: /* Artist */ 12978c2ecf20Sopenharmony_ci break; 12988c2ecf20Sopenharmony_ci default: 12998c2ecf20Sopenharmony_ci#ifdef FALLBACK_TO_1BPP 13008c2ecf20Sopenharmony_ci printk(KERN_WARNING 13018c2ecf20Sopenharmony_ci "stifb: Unsupported graphics card (id=0x%08x) " 13028c2ecf20Sopenharmony_ci "- now trying 1bpp mode instead\n", 13038c2ecf20Sopenharmony_ci fb->id); 13048c2ecf20Sopenharmony_ci bpp = 1; /* default to 1 bpp */ 13058c2ecf20Sopenharmony_ci break; 13068c2ecf20Sopenharmony_ci#else 13078c2ecf20Sopenharmony_ci printk(KERN_WARNING 13088c2ecf20Sopenharmony_ci "stifb: Unsupported graphics card (id=0x%08x) " 13098c2ecf20Sopenharmony_ci "- skipping.\n", 13108c2ecf20Sopenharmony_ci fb->id); 13118c2ecf20Sopenharmony_ci goto out_err0; 13128c2ecf20Sopenharmony_ci#endif 13138c2ecf20Sopenharmony_ci } 13148c2ecf20Sopenharmony_ci 13158c2ecf20Sopenharmony_ci 13168c2ecf20Sopenharmony_ci /* get framebuffer physical and virtual base addr & len (64bit ready) */ 13178c2ecf20Sopenharmony_ci fix->smem_start = F_EXTEND(fb->sti->regions_phys[1]); 13188c2ecf20Sopenharmony_ci fix->smem_len = fb->sti->regions[1].region_desc.length * 4096; 13198c2ecf20Sopenharmony_ci 13208c2ecf20Sopenharmony_ci fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8; 13218c2ecf20Sopenharmony_ci if (!fix->line_length) 13228c2ecf20Sopenharmony_ci fix->line_length = 2048; /* default */ 13238c2ecf20Sopenharmony_ci 13248c2ecf20Sopenharmony_ci /* limit fbsize to max visible screen size */ 13258c2ecf20Sopenharmony_ci if (fix->smem_len > yres*fix->line_length) 13268c2ecf20Sopenharmony_ci fix->smem_len = ALIGN(yres*fix->line_length, 4*1024*1024); 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_ci fix->accel = FB_ACCEL_NONE; 13298c2ecf20Sopenharmony_ci 13308c2ecf20Sopenharmony_ci switch (bpp) { 13318c2ecf20Sopenharmony_ci case 1: 13328c2ecf20Sopenharmony_ci fix->type = FB_TYPE_PLANES; /* well, sort of */ 13338c2ecf20Sopenharmony_ci fix->visual = FB_VISUAL_MONO10; 13348c2ecf20Sopenharmony_ci var->red.length = var->green.length = var->blue.length = 1; 13358c2ecf20Sopenharmony_ci break; 13368c2ecf20Sopenharmony_ci case 8: 13378c2ecf20Sopenharmony_ci fix->type = FB_TYPE_PACKED_PIXELS; 13388c2ecf20Sopenharmony_ci fix->visual = FB_VISUAL_PSEUDOCOLOR; 13398c2ecf20Sopenharmony_ci var->red.length = var->green.length = var->blue.length = 8; 13408c2ecf20Sopenharmony_ci break; 13418c2ecf20Sopenharmony_ci case 32: 13428c2ecf20Sopenharmony_ci fix->type = FB_TYPE_PACKED_PIXELS; 13438c2ecf20Sopenharmony_ci fix->visual = FB_VISUAL_DIRECTCOLOR; 13448c2ecf20Sopenharmony_ci var->red.length = var->green.length = var->blue.length = var->transp.length = 8; 13458c2ecf20Sopenharmony_ci var->blue.offset = 0; 13468c2ecf20Sopenharmony_ci var->green.offset = 8; 13478c2ecf20Sopenharmony_ci var->red.offset = 16; 13488c2ecf20Sopenharmony_ci var->transp.offset = 24; 13498c2ecf20Sopenharmony_ci break; 13508c2ecf20Sopenharmony_ci default: 13518c2ecf20Sopenharmony_ci break; 13528c2ecf20Sopenharmony_ci } 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci var->xres = var->xres_virtual = xres; 13558c2ecf20Sopenharmony_ci var->yres = var->yres_virtual = yres; 13568c2ecf20Sopenharmony_ci var->bits_per_pixel = bpp; 13578c2ecf20Sopenharmony_ci 13588c2ecf20Sopenharmony_ci strcpy(fix->id, "stifb"); 13598c2ecf20Sopenharmony_ci info->fbops = &stifb_ops; 13608c2ecf20Sopenharmony_ci info->screen_base = ioremap(REGION_BASE(fb,1), fix->smem_len); 13618c2ecf20Sopenharmony_ci if (!info->screen_base) { 13628c2ecf20Sopenharmony_ci printk(KERN_ERR "stifb: failed to map memory\n"); 13638c2ecf20Sopenharmony_ci goto out_err0; 13648c2ecf20Sopenharmony_ci } 13658c2ecf20Sopenharmony_ci info->screen_size = fix->smem_len; 13668c2ecf20Sopenharmony_ci info->flags = FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; 13678c2ecf20Sopenharmony_ci info->pseudo_palette = &fb->pseudo_palette; 13688c2ecf20Sopenharmony_ci 13698c2ecf20Sopenharmony_ci scnprintf(modestr, sizeof(modestr), "%dx%d-%d", xres, yres, bpp); 13708c2ecf20Sopenharmony_ci fb_find_mode(&info->var, info, modestr, NULL, 0, NULL, bpp); 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci /* This has to be done !!! */ 13738c2ecf20Sopenharmony_ci if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0)) 13748c2ecf20Sopenharmony_ci goto out_err1; 13758c2ecf20Sopenharmony_ci stifb_init_display(fb); 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) { 13788c2ecf20Sopenharmony_ci printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n", 13798c2ecf20Sopenharmony_ci fix->smem_start, fix->smem_start+fix->smem_len); 13808c2ecf20Sopenharmony_ci goto out_err2; 13818c2ecf20Sopenharmony_ci } 13828c2ecf20Sopenharmony_ci 13838c2ecf20Sopenharmony_ci if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) { 13848c2ecf20Sopenharmony_ci printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n", 13858c2ecf20Sopenharmony_ci fix->mmio_start, fix->mmio_start+fix->mmio_len); 13868c2ecf20Sopenharmony_ci goto out_err3; 13878c2ecf20Sopenharmony_ci } 13888c2ecf20Sopenharmony_ci 13898c2ecf20Sopenharmony_ci /* save for primary gfx device detection & unregister_framebuffer() */ 13908c2ecf20Sopenharmony_ci sti->info = info; 13918c2ecf20Sopenharmony_ci if (register_framebuffer(&fb->info) < 0) 13928c2ecf20Sopenharmony_ci goto out_err4; 13938c2ecf20Sopenharmony_ci 13948c2ecf20Sopenharmony_ci fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n", 13958c2ecf20Sopenharmony_ci fix->id, 13968c2ecf20Sopenharmony_ci var->xres, 13978c2ecf20Sopenharmony_ci var->yres, 13988c2ecf20Sopenharmony_ci var->bits_per_pixel, 13998c2ecf20Sopenharmony_ci dev_name, 14008c2ecf20Sopenharmony_ci fb->id, 14018c2ecf20Sopenharmony_ci fix->mmio_start); 14028c2ecf20Sopenharmony_ci 14038c2ecf20Sopenharmony_ci return 0; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci 14068c2ecf20Sopenharmony_ciout_err4: 14078c2ecf20Sopenharmony_ci release_mem_region(fix->mmio_start, fix->mmio_len); 14088c2ecf20Sopenharmony_ciout_err3: 14098c2ecf20Sopenharmony_ci release_mem_region(fix->smem_start, fix->smem_len); 14108c2ecf20Sopenharmony_ciout_err2: 14118c2ecf20Sopenharmony_ci fb_dealloc_cmap(&info->cmap); 14128c2ecf20Sopenharmony_ciout_err1: 14138c2ecf20Sopenharmony_ci iounmap(info->screen_base); 14148c2ecf20Sopenharmony_ciout_err0: 14158c2ecf20Sopenharmony_ci kfree(fb); 14168c2ecf20Sopenharmony_ci sti->info = NULL; 14178c2ecf20Sopenharmony_ci return -ENXIO; 14188c2ecf20Sopenharmony_ci} 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_cistatic int stifb_disabled __initdata; 14218c2ecf20Sopenharmony_ci 14228c2ecf20Sopenharmony_ciint __init 14238c2ecf20Sopenharmony_cistifb_setup(char *options); 14248c2ecf20Sopenharmony_ci 14258c2ecf20Sopenharmony_cistatic int __init stifb_init(void) 14268c2ecf20Sopenharmony_ci{ 14278c2ecf20Sopenharmony_ci struct sti_struct *sti; 14288c2ecf20Sopenharmony_ci struct sti_struct *def_sti; 14298c2ecf20Sopenharmony_ci int i; 14308c2ecf20Sopenharmony_ci 14318c2ecf20Sopenharmony_ci#ifndef MODULE 14328c2ecf20Sopenharmony_ci char *option = NULL; 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci if (fb_get_options("stifb", &option)) 14358c2ecf20Sopenharmony_ci return -ENODEV; 14368c2ecf20Sopenharmony_ci stifb_setup(option); 14378c2ecf20Sopenharmony_ci#endif 14388c2ecf20Sopenharmony_ci if (stifb_disabled) { 14398c2ecf20Sopenharmony_ci printk(KERN_INFO "stifb: disabled by \"stifb=off\" kernel parameter\n"); 14408c2ecf20Sopenharmony_ci return -ENXIO; 14418c2ecf20Sopenharmony_ci } 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_ci def_sti = sti_get_rom(0); 14448c2ecf20Sopenharmony_ci if (def_sti) { 14458c2ecf20Sopenharmony_ci for (i = 1; i <= MAX_STI_ROMS; i++) { 14468c2ecf20Sopenharmony_ci sti = sti_get_rom(i); 14478c2ecf20Sopenharmony_ci if (!sti) 14488c2ecf20Sopenharmony_ci break; 14498c2ecf20Sopenharmony_ci if (sti == def_sti) { 14508c2ecf20Sopenharmony_ci stifb_init_fb(sti, stifb_bpp_pref[i - 1]); 14518c2ecf20Sopenharmony_ci break; 14528c2ecf20Sopenharmony_ci } 14538c2ecf20Sopenharmony_ci } 14548c2ecf20Sopenharmony_ci } 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci for (i = 1; i <= MAX_STI_ROMS; i++) { 14578c2ecf20Sopenharmony_ci sti = sti_get_rom(i); 14588c2ecf20Sopenharmony_ci if (!sti) 14598c2ecf20Sopenharmony_ci break; 14608c2ecf20Sopenharmony_ci if (sti == def_sti) 14618c2ecf20Sopenharmony_ci continue; 14628c2ecf20Sopenharmony_ci stifb_init_fb(sti, stifb_bpp_pref[i - 1]); 14638c2ecf20Sopenharmony_ci } 14648c2ecf20Sopenharmony_ci return 0; 14658c2ecf20Sopenharmony_ci} 14668c2ecf20Sopenharmony_ci 14678c2ecf20Sopenharmony_ci/* 14688c2ecf20Sopenharmony_ci * Cleanup 14698c2ecf20Sopenharmony_ci */ 14708c2ecf20Sopenharmony_ci 14718c2ecf20Sopenharmony_cistatic void __exit 14728c2ecf20Sopenharmony_cistifb_cleanup(void) 14738c2ecf20Sopenharmony_ci{ 14748c2ecf20Sopenharmony_ci struct sti_struct *sti; 14758c2ecf20Sopenharmony_ci int i; 14768c2ecf20Sopenharmony_ci 14778c2ecf20Sopenharmony_ci for (i = 1; i <= MAX_STI_ROMS; i++) { 14788c2ecf20Sopenharmony_ci sti = sti_get_rom(i); 14798c2ecf20Sopenharmony_ci if (!sti) 14808c2ecf20Sopenharmony_ci break; 14818c2ecf20Sopenharmony_ci if (sti->info) { 14828c2ecf20Sopenharmony_ci struct fb_info *info = sti->info; 14838c2ecf20Sopenharmony_ci unregister_framebuffer(sti->info); 14848c2ecf20Sopenharmony_ci release_mem_region(info->fix.mmio_start, info->fix.mmio_len); 14858c2ecf20Sopenharmony_ci release_mem_region(info->fix.smem_start, info->fix.smem_len); 14868c2ecf20Sopenharmony_ci if (info->screen_base) 14878c2ecf20Sopenharmony_ci iounmap(info->screen_base); 14888c2ecf20Sopenharmony_ci fb_dealloc_cmap(&info->cmap); 14898c2ecf20Sopenharmony_ci framebuffer_release(info); 14908c2ecf20Sopenharmony_ci } 14918c2ecf20Sopenharmony_ci sti->info = NULL; 14928c2ecf20Sopenharmony_ci } 14938c2ecf20Sopenharmony_ci} 14948c2ecf20Sopenharmony_ci 14958c2ecf20Sopenharmony_ciint __init 14968c2ecf20Sopenharmony_cistifb_setup(char *options) 14978c2ecf20Sopenharmony_ci{ 14988c2ecf20Sopenharmony_ci int i; 14998c2ecf20Sopenharmony_ci 15008c2ecf20Sopenharmony_ci if (!options || !*options) 15018c2ecf20Sopenharmony_ci return 1; 15028c2ecf20Sopenharmony_ci 15038c2ecf20Sopenharmony_ci if (strncmp(options, "off", 3) == 0) { 15048c2ecf20Sopenharmony_ci stifb_disabled = 1; 15058c2ecf20Sopenharmony_ci options += 3; 15068c2ecf20Sopenharmony_ci } 15078c2ecf20Sopenharmony_ci 15088c2ecf20Sopenharmony_ci if (strncmp(options, "bpp", 3) == 0) { 15098c2ecf20Sopenharmony_ci options += 3; 15108c2ecf20Sopenharmony_ci for (i = 0; i < MAX_STI_ROMS; i++) { 15118c2ecf20Sopenharmony_ci if (*options++ != ':') 15128c2ecf20Sopenharmony_ci break; 15138c2ecf20Sopenharmony_ci stifb_bpp_pref[i] = simple_strtoul(options, &options, 10); 15148c2ecf20Sopenharmony_ci } 15158c2ecf20Sopenharmony_ci } 15168c2ecf20Sopenharmony_ci return 1; 15178c2ecf20Sopenharmony_ci} 15188c2ecf20Sopenharmony_ci 15198c2ecf20Sopenharmony_ci__setup("stifb=", stifb_setup); 15208c2ecf20Sopenharmony_ci 15218c2ecf20Sopenharmony_cimodule_init(stifb_init); 15228c2ecf20Sopenharmony_cimodule_exit(stifb_cleanup); 15238c2ecf20Sopenharmony_ci 15248c2ecf20Sopenharmony_ciMODULE_AUTHOR("Helge Deller <deller@gmx.de>, Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); 15258c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines"); 15268c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 1527