1d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* 2d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Silicon Motion SM7XX frame buffer device 3d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 4d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Copyright (C) 2006 Silicon Motion Technology Corp. 5d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Authors: Ge Wang, gewang@siliconmotion.com 6ed57d08b9f500f6553d8fa755d90ec710757d74bPatrick Rooney * Boyod boyod.yang@siliconmotion.com.cn 7d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 8d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Copyright (C) 2009 Lemote, Inc. 9f7a904dffe30a02636053d8022498ced7e44d31cWu Zhangjin * Author: Wu Zhangjin, wuzhangjin@gmail.com 10d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 11dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid * Copyright (C) 2011 Igalia, S.L. 12dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid * Author: Javier M. Mellid <jmunhoz@igalia.com> 13dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid * 14d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * This file is subject to the terms and conditions of the GNU General Public 15d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * License. See the file COPYING in the main directory of this archive for 16d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * more details. 17d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 18d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Version 0.10.26192.21.01 19ed57d08b9f500f6553d8fa755d90ec710757d74bPatrick Rooney * - Add PowerPC/Big endian support 203b70a26bcbe05db12965de702368ca0b9ec945f1Javier M. Mellid * - Verified on 2.6.19.2 213b70a26bcbe05db12965de702368ca0b9ec945f1Javier M. Mellid * Boyod.yang <boyod.yang@siliconmotion.com.cn> 22d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 23d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Version 0.09.2621.00.01 243b70a26bcbe05db12965de702368ca0b9ec945f1Javier M. Mellid * - Only support Linux Kernel's version 2.6.21 253b70a26bcbe05db12965de702368ca0b9ec945f1Javier M. Mellid * Boyod.yang <boyod.yang@siliconmotion.com.cn> 26d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 27d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Version 0.09 283b70a26bcbe05db12965de702368ca0b9ec945f1Javier M. Mellid * - Only support Linux Kernel's version 2.6.12 29ed57d08b9f500f6553d8fa755d90ec710757d74bPatrick Rooney * Boyod.yang <boyod.yang@siliconmotion.com.cn> 30d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 31d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 32d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include <linux/io.h> 33d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include <linux/fb.h> 34d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include <linux/pci.h> 35d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include <linux/init.h> 365a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 37d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include <linux/uaccess.h> 3899c978529a40132a6f7a5f136b4362b56fc88d8cPaul Gortmaker#include <linux/module.h> 39d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include <linux/console.h> 40d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include <linux/screen_info.h> 41d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 42d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef CONFIG_PM 43d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include <linux/pm.h> 44d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 45d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 46d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#include "smtcfb.h" 47d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 48d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef DEBUG 49dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) 50d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#else 51d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#define smdbg(format, arg...) 52d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 53d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 54dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellidstruct screen_info smtc_screen_info; 55dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 56d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* 57d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin* Private structure 58d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin*/ 59d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstruct smtcfb_info { 60d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* 61d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * The following is a pointer to be passed into the 62d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * functions below. The modules outside the main 63d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * voyager.c driver have no knowledge as to what 64d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * is within this structure. 65d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 66d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct fb_info fb; 67d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct display_switch *dispsw; 68d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct pci_dev *dev; 69d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin signed int currcon; 70d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 71d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct { 72d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u8 red, green, blue; 73d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } palette[NR_RGB]; 74d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 75d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u_int palette_size; 76d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin}; 77d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 78d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstruct par_info { 79d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* 80d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Hardware 81d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 82d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u16 chipID; 83d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unsigned char __iomem *m_pMMIO; 84d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin char __iomem *m_pLFB; 85d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin char *m_pDPR; 86d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin char *m_pVPR; 87d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin char *m_pCPR; 88d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 89d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u_int width; 90d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u_int height; 91d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u_int hz; 92d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u_long BaseAddressInVRAM; 93d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u8 chipRevID; 94d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin}; 95d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 96d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstruct vesa_mode_table { 97d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin char mode_index[6]; 98d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u16 lfb_width; 99d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u16 lfb_height; 100d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u16 lfb_depth; 101d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin}; 102d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 103d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic struct vesa_mode_table vesa_mode[] = { 104d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x301", 640, 480, 8}, 105d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x303", 800, 600, 8}, 1063b70a26bcbe05db12965de702368ca0b9ec945f1Javier M. Mellid {"0x305", 1024, 768, 8}, 107d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x307", 1280, 1024, 8}, 108d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 109d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x311", 640, 480, 16}, 110d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x314", 800, 600, 16}, 1113b70a26bcbe05db12965de702368ca0b9ec945f1Javier M. Mellid {"0x317", 1024, 768, 16}, 112d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x31A", 1280, 1024, 16}, 113d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 114d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x312", 640, 480, 24}, 115d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x315", 800, 600, 24}, 1163b70a26bcbe05db12965de702368ca0b9ec945f1Javier M. Mellid {"0x318", 1024, 768, 24}, 117d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {"0x31B", 1280, 1024, 24}, 118d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin}; 119d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 120d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinchar __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ 121d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinchar __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ 122d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 123d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic u32 colreg[17]; 124d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic struct par_info hw; /* hardware information */ 125d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 126d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinu16 smtc_ChipIDs[] = { 127d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 0x710, 128d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 0x712, 129d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 0x720 130d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin}; 131d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1321639c8ab4857f18f59222141777c8db931071785anish kumar#define numSMTCchipIDs ARRAY_SIZE(smtc_ChipIDs) 133d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 134dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellidstatic struct fb_var_screeninfo smtcfb_var = { 135dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .xres = 1024, 136dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .yres = 600, 137dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .xres_virtual = 1024, 138dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .yres_virtual = 600, 139dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .bits_per_pixel = 16, 140dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .red = {16, 8, 0}, 141dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .green = {8, 8, 0}, 142dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .blue = {0, 8, 0}, 143dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .activate = FB_ACTIVATE_NOW, 144dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .height = -1, 145dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .width = -1, 146dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .vmode = FB_VMODE_NONINTERLACED, 147dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid}; 148dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 149dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellidstatic struct fb_fix_screeninfo smtcfb_fix = { 150dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .id = "sm712fb", 151dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .type = FB_TYPE_PACKED_PIXELS, 152dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .visual = FB_VISUAL_TRUECOLOR, 153dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .line_length = 800 * 3, 154dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .accel = FB_ACCEL_SMI_LYNX, 155dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid}; 156dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 157d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic void sm712_set_timing(struct smtcfb_info *sfb, 158d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct par_info *ppar_info) 159d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 160d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin int i = 0, j = 0; 161d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u32 m_nScreenStride; 162d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 163d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smdbg("\nppar_info->width = %d ppar_info->height = %d" 164d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n", 165d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin ppar_info->width, ppar_info->height, 166d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.bits_per_pixel, ppar_info->hz); 167d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 168d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (j = 0; j < numVGAModes; j++) { 169d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (VGAMode[j].mmSizeX == ppar_info->width && 170d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].mmSizeY == ppar_info->height && 171d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && 172d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].hz == ppar_info->hz) { 173d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 174d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY =" 175d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin "%d VGAMode[j].bpp = %d" 176d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin "VGAMode[j].hz=%d\n", 177d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, 178d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].bpp, VGAMode[j].hz); 179d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 180d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smdbg("VGAMode index=%d\n", j); 181d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 182d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_mmiowb(0x0, 0x3c6); 183d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 184d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0, 0x1); 185d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 186d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2); 187d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 188d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init SEQ register SR00 - SR04 */ 189d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_SR00_SR04; i++) 190d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]); 191d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 192d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init SEQ register SR10 - SR24 */ 193d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_SR10_SR24; i++) 194d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(i + 0x10, 195d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].Init_SR10_SR24[i]); 196d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 197d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init SEQ register SR30 - SR75 */ 198d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_SR30_SR75; i++) 199d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (((i + 0x30) != 0x62) \ 200d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin && ((i + 0x30) != 0x6a) \ 201d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin && ((i + 0x30) != 0x6b)) 202d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(i + 0x30, 203d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].Init_SR30_SR75[i]); 204d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 205d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init SEQ register SR80 - SR93 */ 206d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_SR80_SR93; i++) 207d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(i + 0x80, 208d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].Init_SR80_SR93[i]); 209d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 210d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init SEQ register SRA0 - SRAF */ 211d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_SRA0_SRAF; i++) 212d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(i + 0xa0, 213d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].Init_SRA0_SRAF[i]); 214d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 215d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init Graphic register GR00 - GR08 */ 216d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_GR00_GR08; i++) 217d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]); 218d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 219d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init Attribute register AR00 - AR14 */ 220d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_AR00_AR14; i++) 221d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]); 222d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 223d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init CRTC register CR00 - CR18 */ 224d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_CR00_CR18; i++) 225d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]); 226d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 227d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init CRTC register CR30 - CR4D */ 228d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_CR30_CR4D; i++) 229d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_crtcw(i + 0x30, 230d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].Init_CR30_CR4D[i]); 231d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 232d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* init CRTC register CR90 - CRA7 */ 233d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = 0; i < SIZE_CR90_CRA7; i++) 234d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_crtcw(i + 0x90, 235d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin VGAMode[j].Init_CR90_CRA7[i]); 236d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 237d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 238d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_mmiowb(0x67, 0x3c2); 239d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 240d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* set VPR registers */ 241d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin writel(0x0, ppar_info->m_pVPR + 0x0C); 242d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin writel(0x0, ppar_info->m_pVPR + 0x40); 243d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 244d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* set data width */ 245d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin m_nScreenStride = 246d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64; 247d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin switch (sfb->fb.var.bits_per_pixel) { 248d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 8: 249d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin writel(0x0, ppar_info->m_pVPR + 0x0); 250d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 251d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 16: 252d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin writel(0x00020000, ppar_info->m_pVPR + 0x0); 253d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 254d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 24: 255d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin writel(0x00040000, ppar_info->m_pVPR + 0x0); 256d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 257d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 32: 258d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin writel(0x00030000, ppar_info->m_pVPR + 0x0); 259d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 260d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 261d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride), 262d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin ppar_info->m_pVPR + 0x10); 263d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 264d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 265d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 266d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic void sm712_setpalette(int regno, unsigned red, unsigned green, 267d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unsigned blue, struct fb_info *info) 268d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 269d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct par_info *cur_par = (struct par_info *)info->par; 270d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 271d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (cur_par->BaseAddressInVRAM) 272d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* 273d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * second display palette for dual head. Enable CRT RAM, 6-bit 274d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * RAM 275d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 276d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20); 277d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin else 278d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* primary display palette. Enable LCD RAM only, 6-bit RAM */ 279d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10); 280d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_mmiowb(regno, dac_reg); 281d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_mmiowb(red >> 10, dac_val); 282d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_mmiowb(green >> 10, dac_val); 283d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_mmiowb(blue >> 10, dac_val); 284d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 285d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 286d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic void smtc_set_timing(struct smtcfb_info *sfb, struct par_info 287d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin *ppar_info) 288d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 289d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin switch (ppar_info->chipID) { 290d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x710: 291d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x712: 292d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x720: 293d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sm712_set_timing(sfb, ppar_info); 294d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 295d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 296d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 297d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 298d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* chan_to_field 299d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 300d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * convert a colour value into a field position 301d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 302d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * from pxafb.c 303d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 304d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 305d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic inline unsigned int chan_to_field(unsigned int chan, 306d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct fb_bitfield *bf) 307d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 308d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin chan &= 0xffff; 309d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin chan >>= 16 - bf->length; 310d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return chan << bf->offset; 311d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 312d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 3133af805735a2538c38ec16014f19d19030544aaefWu Zhangjinstatic int cfb_blank(int blank_mode, struct fb_info *info) 314d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 315d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* clear DPMS setting */ 316d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin switch (blank_mode) { 317d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case FB_BLANK_UNBLANK: 318d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* Screen On: HSync: On, VSync : On */ 319d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); 320d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x16); 321d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 322d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77)); 323d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); 324d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); 325d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); 326d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03)); 327d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 328d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case FB_BLANK_NORMAL: 329d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* Screen Off: HSync: On, VSync : On Soft blank */ 330d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); 331d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x16); 332d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 333d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); 334d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); 335d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); 336d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); 337d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 338d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case FB_BLANK_VSYNC_SUSPEND: 339d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* Screen On: HSync: On, VSync : Off */ 340d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); 341d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); 342d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x0c); 343d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 344d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); 345d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20)); 346d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20)); 347d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); 348d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); 349d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); 350d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 351d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case FB_BLANK_HSYNC_SUSPEND: 352d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* Screen On: HSync: Off, VSync : On */ 353d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); 354d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); 355d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x0c); 356d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 357d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); 358d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10)); 359d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); 360d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); 361d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); 362d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); 363d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 364d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case FB_BLANK_POWERDOWN: 365d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* Screen On: HSync: Off, VSync : Off */ 366d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); 367d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); 368d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x0c); 369d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 370d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); 371d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30)); 372d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); 373d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); 374d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); 375d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); 376d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 377d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin default: 378d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -EINVAL; 379d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 380d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 381d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 0; 382d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 383d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 384d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic int smtc_setcolreg(unsigned regno, unsigned red, unsigned green, 385d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unsigned blue, unsigned trans, struct fb_info *info) 386d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 387d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct smtcfb_info *sfb = (struct smtcfb_info *)info; 388d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u32 val; 389d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 390d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (regno > 255) 391d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 1; 392d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 393d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin switch (sfb->fb.fix.visual) { 394d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case FB_VISUAL_DIRECTCOLOR: 395d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case FB_VISUAL_TRUECOLOR: 396d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* 397d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 16/32 bit true-colour, use pseuo-palette for 16 base color 398d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 399d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (regno < 16) { 400d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb->fb.var.bits_per_pixel == 16) { 401d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u32 *pal = sfb->fb.pseudo_palette; 402d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin val = chan_to_field(red, &sfb->fb.var.red); 403d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin val |= chan_to_field(green, \ 404d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin &sfb->fb.var.green); 405d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin val |= chan_to_field(blue, &sfb->fb.var.blue); 406d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 407d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin pal[regno] = 408d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin ((red & 0xf800) >> 8) | 409d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin ((green & 0xe000) >> 13) | 410d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin ((green & 0x1c00) << 3) | 411d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin ((blue & 0xf800) >> 3); 412d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#else 413d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin pal[regno] = val; 414d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 415d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } else { 416d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u32 *pal = sfb->fb.pseudo_palette; 417d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin val = chan_to_field(red, &sfb->fb.var.red); 418d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin val |= chan_to_field(green, \ 419d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin &sfb->fb.var.green); 420d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin val |= chan_to_field(blue, &sfb->fb.var.blue); 421d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 422d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin val = 423d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin (val & 0xff00ff00 >> 8) | 424d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin (val & 0x00ff00ff << 8); 425d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 426d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin pal[regno] = val; 427d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 428d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 429d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 430d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 431d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case FB_VISUAL_PSEUDOCOLOR: 432d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* color depth 8 bit */ 433d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sm712_setpalette(regno, red, green, blue, info); 434d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 435d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 436d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin default: 437d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 1; /* unknown type */ 438d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 439d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 440d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 0; 441d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 442d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 443d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 444d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 445c8100d2b186b804305608c22cc77b0deeb1d9821Josenivaldo Benito Jrstatic ssize_t smtcfb_read(struct fb_info *info, char __user *buf, size_t 446d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin count, loff_t *ppos) 447d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 448d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unsigned long p = *ppos; 449d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 450d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u32 *buffer, *dst; 451d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u32 __iomem *src; 452d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin int c, i, cnt = 0, err = 0; 453d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unsigned long total_size; 454d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 455d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!info || !info->screen_base) 456d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -ENODEV; 457d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 458d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (info->state != FBINFO_STATE_RUNNING) 459d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -EPERM; 460d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 461d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin total_size = info->screen_size; 462d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 463d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (total_size == 0) 464d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin total_size = info->fix.smem_len; 465d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 466d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (p >= total_size) 467d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 0; 468d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 469d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (count >= total_size) 470d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin count = total_size; 471d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 472d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (count + p > total_size) 473d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin count = total_size - p; 474d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 475d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); 476d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!buffer) 477d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -ENOMEM; 478d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 479d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin src = (u32 __iomem *) (info->screen_base + p); 480d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 481d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (info->fbops->fb_sync) 482d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin info->fbops->fb_sync(info); 483d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 484d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin while (count) { 485d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin c = (count > PAGE_SIZE) ? PAGE_SIZE : count; 486d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin dst = buffer; 487d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = c >> 2; i--;) { 488d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin *dst = fb_readl(src++); 489d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin *dst = 490d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin (*dst & 0xff00ff00 >> 8) | 491d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin (*dst & 0x00ff00ff << 8); 492d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin dst++; 493d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 494d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (c & 3) { 495d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u8 *dst8 = (u8 *) dst; 496d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u8 __iomem *src8 = (u8 __iomem *) src; 497d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 498d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = c & 3; i--;) { 499d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (i & 1) { 500d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin *dst8++ = fb_readb(++src8); 501d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } else { 502d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin *dst8++ = fb_readb(--src8); 503d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin src8 += 2; 504d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 505d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 506d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin src = (u32 __iomem *) src8; 507d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 508d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 509d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (copy_to_user(buf, buffer, c)) { 510d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin err = -EFAULT; 511d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 512d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 513d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin *ppos += c; 514d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin buf += c; 515d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin cnt += c; 516d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin count -= c; 517d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 518d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 519d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin kfree(buffer); 520d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 521d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return (err) ? err : cnt; 522d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 523d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 524d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic ssize_t 525d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinsmtcfb_write(struct fb_info *info, const char __user *buf, size_t count, 526d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin loff_t *ppos) 527d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 528d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unsigned long p = *ppos; 529d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 530d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u32 *buffer, *src; 531d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u32 __iomem *dst; 532d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin int c, i, cnt = 0, err = 0; 533d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unsigned long total_size; 534d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 535d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!info || !info->screen_base) 536d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -ENODEV; 537d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 538d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (info->state != FBINFO_STATE_RUNNING) 539d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -EPERM; 540d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 541d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin total_size = info->screen_size; 542d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 543d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (total_size == 0) 544d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin total_size = info->fix.smem_len; 545d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 546d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (p > total_size) 547d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -EFBIG; 548d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 549d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (count > total_size) { 550d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin err = -EFBIG; 551d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin count = total_size; 552d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 553d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 554d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (count + p > total_size) { 555d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!err) 556d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin err = -ENOSPC; 557d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 558d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin count = total_size - p; 559d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 560d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 561d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); 562d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!buffer) 563d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -ENOMEM; 564d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 565d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin dst = (u32 __iomem *) (info->screen_base + p); 566d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 567d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (info->fbops->fb_sync) 568d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin info->fbops->fb_sync(info); 569d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 570d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin while (count) { 571d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin c = (count > PAGE_SIZE) ? PAGE_SIZE : count; 572d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin src = buffer; 573d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 574d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (copy_from_user(src, buf, c)) { 575d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin err = -EFAULT; 576d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 577d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 578d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 579d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = c >> 2; i--;) { 580d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin fb_writel((*src & 0xff00ff00 >> 8) | 581d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin (*src & 0x00ff00ff << 8), dst++); 582d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin src++; 583d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 584d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (c & 3) { 585d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u8 *src8 = (u8 *) src; 586d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u8 __iomem *dst8 = (u8 __iomem *) dst; 587d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 588d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (i = c & 3; i--;) { 589d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (i & 1) { 590d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin fb_writeb(*src8++, ++dst8); 591d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } else { 592d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin fb_writeb(*src8++, --dst8); 593d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin dst8 += 2; 594d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 595d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 596d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin dst = (u32 __iomem *) dst8; 597d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 598d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 599d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin *ppos += c; 600d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin buf += c; 601d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin cnt += c; 602d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin count -= c; 603d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 604d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 605d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin kfree(buffer); 606d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 607d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return (cnt) ? cnt : err; 608d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 609d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif /* ! __BIG_ENDIAN */ 610d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 611d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinvoid smtcfb_setmode(struct smtcfb_info *sfb) 612d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 613d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin switch (sfb->fb.var.bits_per_pixel) { 614d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 32: 615d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; 616d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.line_length = sfb->fb.var.xres * 4; 617d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.red.length = 8; 618d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.green.length = 8; 619d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.blue.length = 8; 620d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.red.offset = 16; 621d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.green.offset = 8; 622d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.blue.offset = 0; 623d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 624d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 625d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 8: 626d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; 627d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.line_length = sfb->fb.var.xres; 628d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.red.offset = 5; 629d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.red.length = 3; 630d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.green.offset = 2; 631d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.green.length = 3; 632d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.blue.offset = 0; 633d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.blue.length = 2; 634d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 635d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 24: 636d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; 637d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.line_length = sfb->fb.var.xres * 3; 638d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.red.length = 8; 639d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.green.length = 8; 640d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.blue.length = 8; 641d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 642d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.red.offset = 16; 643d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.green.offset = 8; 644d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.blue.offset = 0; 645d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 646d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 647d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 16: 648d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin default: 649d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; 650d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.line_length = sfb->fb.var.xres * 2; 651d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 652d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.red.length = 5; 653d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.green.length = 6; 654d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.blue.length = 5; 655d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 656d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.red.offset = 11; 657d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.green.offset = 5; 658d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.blue.offset = 0; 659d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 660d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 661d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 662d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 663d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.width = sfb->fb.var.xres; 664d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.height = sfb->fb.var.yres; 665d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.hz = 60; 666d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_set_timing(sfb, &hw); 667d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 668d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 669dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellidstatic int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 670dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid{ 671dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid /* sanity checks */ 672dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid if (var->xres_virtual < var->xres) 673dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid var->xres_virtual = var->xres; 674dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 675dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid if (var->yres_virtual < var->yres) 676dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid var->yres_virtual = var->yres; 677dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 678dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid /* set valid default bpp */ 679dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid if ((var->bits_per_pixel != 8) && (var->bits_per_pixel != 16) && 680dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32)) 681dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid var->bits_per_pixel = 16; 682dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 683dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid return 0; 684dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid} 685dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 686dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellidstatic int smtc_set_par(struct fb_info *info) 687dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid{ 688dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid struct smtcfb_info *sfb = (struct smtcfb_info *)info; 689dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 690dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid smtcfb_setmode(sfb); 691dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 692dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid return 0; 693dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid} 694dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 695dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellidstatic struct fb_ops smtcfb_ops = { 696dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .owner = THIS_MODULE, 697dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_check_var = smtc_check_var, 698dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_set_par = smtc_set_par, 699dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_setcolreg = smtc_setcolreg, 700dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_blank = cfb_blank, 701dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_fillrect = cfb_fillrect, 702dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_imageblit = cfb_imageblit, 703dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_copyarea = cfb_copyarea, 704dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid#ifdef __BIG_ENDIAN 705dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_read = smtcfb_read, 706dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid .fb_write = smtcfb_write, 707dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid#endif 708dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid}; 709dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellid 710d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* 711d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Alloc struct smtcfb_info and assign the default value 712d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 713d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, 714d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin char *name) 715d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 716d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct smtcfb_info *sfb; 717d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 718617a0c7177195a5cef6f0c2e559ee05b5d4191ddanish kumar sfb = kzalloc(sizeof(*sfb), GFP_KERNEL); 719d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 720d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!sfb) 721d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return NULL; 722d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 723d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->currcon = -1; 724d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->dev = dev; 725d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 726d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /*** Init sfb->fb with default value ***/ 727d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.flags = FBINFO_FLAG_DEFAULT; 728d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fbops = &smtcfb_ops; 729d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var = smtcfb_var; 730d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix = smtcfb_fix; 731d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 732d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin strcpy(sfb->fb.fix.id, name); 733d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 734d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; 735d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.type_aux = 0; 736d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.xpanstep = 0; 737d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.ypanstep = 0; 738d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.ywrapstep = 0; 739d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX; 740d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 741d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.nonstd = 0; 742d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.activate = FB_ACTIVATE_NOW; 743d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.height = -1; 744d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.width = -1; 745d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* text mode acceleration */ 746d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.accel_flags = FB_ACCELF_TEXT; 747d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; 748d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.par = &hw; 749d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.pseudo_palette = colreg; 750d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 751d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return sfb; 752d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 753d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 754d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* 755d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Unmap in the memory mapped IO registers 756d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 757d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 758d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic void smtc_unmap_mmio(struct smtcfb_info *sfb) 759d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 760d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb && smtc_RegBaseAddress) 761d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_RegBaseAddress = NULL; 762d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 763d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 764d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* 765d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Map in the screen memory 766d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 767d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 768d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic int smtc_map_smem(struct smtcfb_info *sfb, 769d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct pci_dev *dev, u_long smem_len) 770d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 771d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb->fb.var.bits_per_pixel == 32) { 772d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 773d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.smem_start = pci_resource_start(dev, 0) 774d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin + 0x800000; 775d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#else 776d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.smem_start = pci_resource_start(dev, 0); 777d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 778d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } else { 779d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.smem_start = pci_resource_start(dev, 0); 780d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 781d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 782d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.smem_len = smem_len; 783d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 784d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.screen_base = smtc_VRAMBaseAddress; 785d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 786d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!sfb->fb.screen_base) { 78723a4231150ad227c99b7358ae9a741def5898d90anish kumar printk(KERN_ERR "%s: unable to map screen memory\n", 788d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.id); 789d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -ENOMEM; 790d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 791d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 792d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 0; 793d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 794d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 795d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* 796d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Unmap in the screen memory 797d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 798d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 799d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic void smtc_unmap_smem(struct smtcfb_info *sfb) 800d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 801d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb && sfb->fb.screen_base) { 802d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin iounmap(sfb->fb.screen_base); 803d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.screen_base = NULL; 804d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 805d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 806d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 807d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* 808d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * We need to wake up the LynxEM+, and make sure its in linear memory mode. 809d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 810d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic inline void sm7xx_init_hw(void) 811d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 812d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin outb_p(0x18, 0x3c4); 813d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin outb_p(0x11, 0x3c5); 814d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 815d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 816d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic void smtc_free_fb_info(struct smtcfb_info *sfb) 817d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 818d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb) { 819d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin fb_alloc_cmap(&sfb->fb.cmap, 0, 0); 820d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin kfree(sfb); 821d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 822d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 823d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 824d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* 825d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * sm712vga_setup - process command line options, get vga parameter 826d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * @options: string of options 827d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Returns zero. 828d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * 829d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 830dc762c4f8514f23094927e0a62ef305d90651535Javier M. Mellidstatic int __init sm712vga_setup(char *options) 831d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 832d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin int index; 833d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 834d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!options || !*options) { 835d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smdbg("\n No vga parameter\n"); 836d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -EINVAL; 837d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 838d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 839d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_screen_info.lfb_width = 0; 840d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_screen_info.lfb_height = 0; 841d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_screen_info.lfb_depth = 0; 842d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 843d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smdbg("\nsm712vga_setup = %s\n", options); 844d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 845d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin for (index = 0; 8461639c8ab4857f18f59222141777c8db931071785anish kumar index < ARRAY_SIZE(vesa_mode); 847d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin index++) { 848d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (strstr(options, vesa_mode[index].mode_index)) { 849d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_screen_info.lfb_width = vesa_mode[index].lfb_width; 850d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_screen_info.lfb_height = 851d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin vesa_mode[index].lfb_height; 852d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_screen_info.lfb_depth = vesa_mode[index].lfb_depth; 853d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 0; 854d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 855d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 856d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 857d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return -1; 858d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 859d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin__setup("vga=", sm712vga_setup); 860d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 861d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* Jason (08/13/2009) 862d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Original init function changed to probe method to be used by pci_drv 863d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * process used to detect chips replaced with kernel process in pci_drv 864d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 865b99e1943fd416a5889300fe0fe58367aa3e5705fWu Zhangjinstatic int __devinit smtcfb_pci_probe(struct pci_dev *pdev, 866d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin const struct pci_device_id *ent) 867d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 868d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct smtcfb_info *sfb; 869d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin u_long smem_size = 0x00800000; /* default 8MB */ 870d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin char name[16]; 871d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin int err; 872d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unsigned long pFramebufferPhysical; 873d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 874d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin printk(KERN_INFO 875d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n"); 876d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 877d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin err = pci_enable_device(pdev); /* enable SMTC chip */ 878d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (err) 879d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return err; 880d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 881d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.chipID = ent->device; 882d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sprintf(name, "sm%Xfb", hw.chipID); 883d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 884d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb = smtc_alloc_fb_info(pdev, name); 885d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 886d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!sfb) 887918e3592b9ea865ce29bda06a7200eba80d8d5f8Kulikov Vasiliy goto failed_free; 888d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* Jason (08/13/2009) 889d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * Store fb_info to be further used when suspending and resuming 890d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 891d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin pci_set_drvdata(pdev, sfb); 892d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 893d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sm7xx_init_hw(); 894d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 895d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /*get mode parameter from smtc_screen_info */ 896d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (smtc_screen_info.lfb_width != 0) { 897d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.xres = smtc_screen_info.lfb_width; 898d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.yres = smtc_screen_info.lfb_height; 899d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.bits_per_pixel = smtc_screen_info.lfb_depth; 900d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } else { 901d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* default resolution 1024x600 16bit mode */ 902d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.xres = SCREEN_X_RES; 903d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.yres = SCREEN_Y_RES; 904d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.bits_per_pixel = SCREEN_BPP; 905d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 906d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 907d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 908d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb->fb.var.bits_per_pixel == 24) 909d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.bits_per_pixel = (smtc_screen_info.lfb_depth = 32); 910d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 911d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* Map address and memory detection */ 912d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin pFramebufferPhysical = pci_resource_start(pdev, 0); 913d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID); 914d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 915d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin switch (hw.chipID) { 916d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x710: 917d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x712: 918d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; 919d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.mmio_len = 0x00400000; 920d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smem_size = SM712_VIDEOMEMORYSIZE; 921d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 922d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.m_pLFB = (smtc_VRAMBaseAddress = 923d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin ioremap(pFramebufferPhysical, 0x00c00000)); 924d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#else 925d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.m_pLFB = (smtc_VRAMBaseAddress = 926d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin ioremap(pFramebufferPhysical, 0x00800000)); 927d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 928d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.m_pMMIO = (smtc_RegBaseAddress = 929d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_VRAMBaseAddress + 0x00700000); 9303af805735a2538c38ec16014f19d19030544aaefWu Zhangjin hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000; 931d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.m_pVPR = hw.m_pLFB + 0x0040c000; 932d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 933d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb->fb.var.bits_per_pixel == 32) { 934d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_VRAMBaseAddress += 0x800000; 935d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.m_pLFB += 0x800000; 936d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin printk(KERN_INFO 937d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n", 938d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_VRAMBaseAddress, hw.m_pLFB); 939d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 940d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 941d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (!smtc_RegBaseAddress) { 94223a4231150ad227c99b7358ae9a741def5898d90anish kumar printk(KERN_ERR 943d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin "%s: unable to map memory mapped IO\n", 944d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.id); 945918e3592b9ea865ce29bda06a7200eba80d8d5f8Kulikov Vasiliy err = -ENOMEM; 946918e3592b9ea865ce29bda06a7200eba80d8d5f8Kulikov Vasiliy goto failed_fb; 947d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 948d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 949d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* set MCLK = 14.31818 * (0x16 / 0x2) */ 950d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x16); 951d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 952d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x62, 0x3e); 953d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* enable PCI burst */ 954d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x17, 0x20); 955d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* enable word swap */ 956d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 957d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb->fb.var.bits_per_pixel == 32) 958d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x17, 0x30); 959d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 960d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 961d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x720: 962d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.mmio_start = pFramebufferPhysical; 963d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.fix.mmio_len = 0x00200000; 964d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smem_size = SM722_VIDEOMEMORYSIZE; 9653af805735a2538c38ec16014f19d19030544aaefWu Zhangjin hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000); 966d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.m_pLFB = (smtc_VRAMBaseAddress = 9673af805735a2538c38ec16014f19d19030544aaefWu Zhangjin hw.m_pDPR + 0x00200000); 968d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.m_pMMIO = (smtc_RegBaseAddress = 9693af805735a2538c38ec16014f19d19030544aaefWu Zhangjin hw.m_pDPR + 0x000c0000); 9703af805735a2538c38ec16014f19d19030544aaefWu Zhangjin hw.m_pVPR = hw.m_pDPR + 0x800; 971d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 972d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x62, 0xff); 973d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x0d); 974d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 975d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 976d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin default: 97723a4231150ad227c99b7358ae9a741def5898d90anish kumar printk(KERN_ERR 978d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin "No valid Silicon Motion display chip was detected!\n"); 979d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 980918e3592b9ea865ce29bda06a7200eba80d8d5f8Kulikov Vasiliy goto failed_fb; 981d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 982d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 983d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* can support 32 bpp */ 984d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (15 == sfb->fb.var.bits_per_pixel) 985d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.bits_per_pixel = 16; 986d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 987d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.xres_virtual = sfb->fb.var.xres; 988d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.yres_virtual = sfb->fb.var.yres; 989d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin err = smtc_map_smem(sfb, pdev, smem_size); 990d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (err) 991d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin goto failed; 992d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 993d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtcfb_setmode(sfb); 99425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* Primary display starting from 0 position */ 995d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin hw.BaseAddressInVRAM = 0; 996d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.par = &hw; 997d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 998d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin err = register_framebuffer(&sfb->fb); 999d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (err < 0) 1000d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin goto failed; 1001d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1002d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode" 1003d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, 1004d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.xres, sfb->fb.var.yres, 1005d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb->fb.var.bits_per_pixel); 1006d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1007d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 0; 1008d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 10091639c8ab4857f18f59222141777c8db931071785anish kumarfailed: 101023a4231150ad227c99b7358ae9a741def5898d90anish kumar printk(KERN_ERR "Silicon Motion, Inc. primary display init fail\n"); 1011d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1012d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_unmap_smem(sfb); 1013d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_unmap_mmio(sfb); 1014918e3592b9ea865ce29bda06a7200eba80d8d5f8Kulikov Vasiliyfailed_fb: 1015d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_free_fb_info(sfb); 1016d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1017918e3592b9ea865ce29bda06a7200eba80d8d5f8Kulikov Vasiliyfailed_free: 1018918e3592b9ea865ce29bda06a7200eba80d8d5f8Kulikov Vasiliy pci_disable_device(pdev); 1019918e3592b9ea865ce29bda06a7200eba80d8d5f8Kulikov Vasiliy 1020d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return err; 1021d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 1022d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1023d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1024d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* Jason (08/11/2009) PCI_DRV wrapper essential structs */ 10256f475b71605c7ebf6f5b06b8e4dc58f672b4f9b5Namhyung Kimstatic DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { 1026c0fe602f2de66fa775b1d28981212ff853a62d1bPeter Huewe { PCI_DEVICE(0x126f, 0x710), }, 1027c0fe602f2de66fa775b1d28981212ff853a62d1bPeter Huewe { PCI_DEVICE(0x126f, 0x712), }, 1028c0fe602f2de66fa775b1d28981212ff853a62d1bPeter Huewe { PCI_DEVICE(0x126f, 0x720), }, 1029d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin {0,} 1030d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin}; 1031d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1032d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1033d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin/* Jason (08/14/2009) 1034d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * do some clean up when the driver module is removed 1035d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 1036d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic void __devexit smtcfb_pci_remove(struct pci_dev *pdev) 1037d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 1038d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct smtcfb_info *sfb; 1039d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1040d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb = pci_get_drvdata(pdev); 1041d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin pci_set_drvdata(pdev, NULL); 1042d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_unmap_smem(sfb); 1043d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_unmap_mmio(sfb); 1044d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin unregister_framebuffer(&sfb->fb); 1045d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_free_fb_info(sfb); 1046d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 1047d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1048392a002a0066812480e1b55639bbced5936d26aaJavier M. Mellid#ifdef CONFIG_PM 104959815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellidstatic int smtcfb_pci_suspend(struct device *device) 1050d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 105159815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid struct pci_dev *pdev = to_pci_dev(device); 1052d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct smtcfb_info *sfb; 1053d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1054d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb = pci_get_drvdata(pdev); 1055d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1056d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* set the hw in sleep mode use externel clock and self memory refresh 1057d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin * so that we can turn off internal PLLs later on 1058d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin */ 1059d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0)); 1060d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7)); 1061d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 106259815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid console_lock(); 106359815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid fb_set_suspend(&sfb->fb, 1); 106459815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid console_unlock(); 1065d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 106625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* additionally turn off all function blocks including internal PLLs */ 1067d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x21, 0xff); 1068d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1069d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 0; 1070d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 1071d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 107259815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellidstatic int smtcfb_pci_resume(struct device *device) 1073d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 107459815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid struct pci_dev *pdev = to_pci_dev(device); 1075d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin struct smtcfb_info *sfb; 1076d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1077d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sfb = pci_get_drvdata(pdev); 1078d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1079d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* reinit hardware */ 1080d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin sm7xx_init_hw(); 1081d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin switch (hw.chipID) { 1082d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x710: 1083d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x712: 1084d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* set MCLK = 14.31818 * (0x16 / 0x2) */ 1085d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x16); 1086d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 1087d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x62, 0x3e); 1088d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin /* enable PCI burst */ 1089d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x17, 0x20); 1090d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#ifdef __BIG_ENDIAN 1091d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin if (sfb->fb.var.bits_per_pixel == 32) 1092d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x17, 0x30); 1093d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin#endif 1094d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 1095d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin case 0x720: 1096d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x62, 0xff); 1097d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6a, 0x0d); 1098d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x6b, 0x02); 1099d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin break; 1100d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin } 1101d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1102d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0)); 1103d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb)); 1104d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1105d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin smtcfb_setmode(sfb); 1106d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1107ac751efa6a0d70f2c9daef5c7e3a92270f5c2dffTorben Hohn console_lock(); 1108d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin fb_set_suspend(&sfb->fb, 0); 1109ac751efa6a0d70f2c9daef5c7e3a92270f5c2dffTorben Hohn console_unlock(); 1110d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1111d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return 0; 1112d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 1113d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 111459815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellidstatic const struct dev_pm_ops sm7xx_pm_ops = { 111559815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid .suspend = smtcfb_pci_suspend, 111659815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid .resume = smtcfb_pci_resume, 111759815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid .freeze = smtcfb_pci_suspend, 111859815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid .thaw = smtcfb_pci_resume, 111959815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid .poweroff = smtcfb_pci_suspend, 112059815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid .restore = smtcfb_pci_resume, 112159815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid}; 112259815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid 112359815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid#define SM7XX_PM_OPS (&sm7xx_pm_ops) 112459815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid 112559815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid#else /* !CONFIG_PM */ 112659815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid 112759815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid#define SM7XX_PM_OPS NULL 112859815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid 112959815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid#endif /* !CONFIG_PM */ 113059815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid 1131d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic struct pci_driver smtcfb_driver = { 1132d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin .name = "smtcfb", 1133d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin .id_table = smtcfb_pci_table, 1134d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin .probe = smtcfb_pci_probe, 1135d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin .remove = __devexit_p(smtcfb_pci_remove), 113659815677555746f8263672f25cebcf4c27fc5d31Javier M. Mellid .driver.pm = SM7XX_PM_OPS, 1137d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin}; 1138d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1139d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic int __init smtcfb_init(void) 1140d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 1141d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin return pci_register_driver(&smtcfb_driver); 1142d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 1143d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1144d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinstatic void __exit smtcfb_exit(void) 1145d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin{ 1146d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin pci_unregister_driver(&smtcfb_driver); 1147d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin} 1148d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1149d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinmodule_init(smtcfb_init); 1150d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjinmodule_exit(smtcfb_exit); 1151d7edf47947f9d921be6ca5fc8e83049124466f98Wu Zhangjin 1152d7edf47947f9d921be6ca5fc8e83049124466f98Wu ZhangjinMODULE_AUTHOR("Siliconmotion "); 1153d7edf47947f9d921be6ca5fc8e83049124466f98Wu ZhangjinMODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards"); 1154d7edf47947f9d921be6ca5fc8e83049124466f98Wu ZhangjinMODULE_LICENSE("GPL"); 1155