brintos

brintos / linux-shallow public Read only

0
0
Text · 48.0 KiB · 104f122 Raw
1780 lines · c
1/*2 * Silicon Motion SM7XX frame buffer device3 *4 * Copyright (C) 2006 Silicon Motion Technology Corp.5 * Authors:  Ge Wang, gewang@siliconmotion.com6 *	     Boyod boyod.yang@siliconmotion.com.cn7 *8 * Copyright (C) 2009 Lemote, Inc.9 * Author:   Wu Zhangjin, wuzhangjin@gmail.com10 *11 * Copyright (C) 2011 Igalia, S.L.12 * Author:   Javier M. Mellid <jmunhoz@igalia.com>13 *14 * This file is subject to the terms and conditions of the GNU General Public15 * License. See the file COPYING in the main directory of this archive for16 * more details.17 *18 * Framebuffer driver for Silicon Motion SM710, SM712, SM721 and SM722 chips19 */20 21#include <linux/aperture.h>22#include <linux/io.h>23#include <linux/fb.h>24#include <linux/pci.h>25#include <linux/init.h>26#include <linux/slab.h>27#include <linux/uaccess.h>28#include <linux/module.h>29#include <linux/console.h>30 31#include <linux/pm.h>32 33#include "sm712.h"34 35struct smtcfb_screen_info {36	u16 lfb_width;37	u16 lfb_height;38	u16 lfb_depth;39};40 41/*42 * Private structure43 */44struct smtcfb_info {45	struct pci_dev *pdev;46	struct fb_info *fb;47	u16 chip_id;48	u8  chip_rev_id;49 50	void __iomem *lfb;	/* linear frame buffer */51	void __iomem *dp_regs;	/* drawing processor control regs */52	void __iomem *vp_regs;	/* video processor control regs */53	void __iomem *cp_regs;	/* capture processor control regs */54	void __iomem *mmio;	/* memory map IO port */55 56	u_int width;57	u_int height;58	u_int hz;59 60	u32 colreg[17];61};62 63void __iomem *smtc_regbaseaddress;	/* Memory Map IO starting address */64 65static const struct fb_var_screeninfo smtcfb_var = {66	.xres           = 1024,67	.yres           = 600,68	.xres_virtual   = 1024,69	.yres_virtual   = 600,70	.bits_per_pixel = 16,71	.red            = {16, 8, 0},72	.green          = {8, 8, 0},73	.blue           = {0, 8, 0},74	.activate       = FB_ACTIVATE_NOW,75	.height         = -1,76	.width          = -1,77	.vmode          = FB_VMODE_NONINTERLACED,78	.nonstd         = 0,79	.accel_flags    = FB_ACCELF_TEXT,80};81 82static struct fb_fix_screeninfo smtcfb_fix = {83	.id             = "smXXXfb",84	.type           = FB_TYPE_PACKED_PIXELS,85	.visual         = FB_VISUAL_TRUECOLOR,86	.line_length    = 800 * 3,87	.accel          = FB_ACCEL_SMI_LYNX,88	.type_aux       = 0,89	.xpanstep       = 0,90	.ypanstep       = 0,91	.ywrapstep      = 0,92};93 94struct vesa_mode {95	char index[6];96	u16  lfb_width;97	u16  lfb_height;98	u16  lfb_depth;99};100 101static const struct vesa_mode vesa_mode_table[] = {102	{"0x301", 640,  480,  8},103	{"0x303", 800,  600,  8},104	{"0x305", 1024, 768,  8},105	{"0x307", 1280, 1024, 8},106 107	{"0x311", 640,  480,  16},108	{"0x314", 800,  600,  16},109	{"0x317", 1024, 768,  16},110	{"0x31A", 1280, 1024, 16},111 112	{"0x312", 640,  480,  24},113	{"0x315", 800,  600,  24},114	{"0x318", 1024, 768,  24},115	{"0x31B", 1280, 1024, 24},116};117 118/**********************************************************************119			 SM712 Mode table.120 **********************************************************************/121static const struct modeinit vgamode[] = {122	{123		/*  mode#0: 640 x 480  16Bpp  60Hz */124		640, 480, 16, 60,125		/*  Init_MISC */126		0xE3,127		{	/*  Init_SR0_SR4 */128			0x03, 0x01, 0x0F, 0x00, 0x0E,129		},130		{	/*  Init_SR10_SR24 */131			0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,132			0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,133			0xC4, 0x30, 0x02, 0x01, 0x01,134		},135		{	/*  Init_SR30_SR75 */136			0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,137			0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,138			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,139			0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,140			0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,141			0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,142			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,143			0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,144			0x00, 0x45, 0x30, 0x30, 0x40, 0x30,145		},146		{	/*  Init_SR80_SR93 */147			0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,148			0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,149			0x00, 0x00, 0x00, 0x00,150		},151		{	/*  Init_SRA0_SRAF */152			0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,153			0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,154		},155		{	/*  Init_GR00_GR08 */156			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,157			0xFF,158		},159		{	/*  Init_AR00_AR14 */160			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,161			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,162			0x41, 0x00, 0x0F, 0x00, 0x00,163		},164		{	/*  Init_CR00_CR18 */165			0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,166			0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,167			0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,168			0xFF,169		},170		{	/*  Init_CR30_CR4D */171			0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,172			0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,173			0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,174			0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,175		},176		{	/*  Init_CR90_CRA7 */177			0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,178			0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,179			0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,180		},181	},182	{183		/*  mode#1: 640 x 480  24Bpp  60Hz */184		640, 480, 24, 60,185		/*  Init_MISC */186		0xE3,187		{	/*  Init_SR0_SR4 */188			0x03, 0x01, 0x0F, 0x00, 0x0E,189		},190		{	/*  Init_SR10_SR24 */191			0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,192			0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,193			0xC4, 0x30, 0x02, 0x01, 0x01,194		},195		{	/*  Init_SR30_SR75 */196			0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,197			0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,198			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,199			0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,200			0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,201			0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,202			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,203			0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,204			0x00, 0x45, 0x30, 0x30, 0x40, 0x30,205		},206		{	/*  Init_SR80_SR93 */207			0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,208			0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,209			0x00, 0x00, 0x00, 0x00,210		},211		{	/*  Init_SRA0_SRAF */212			0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,213			0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,214		},215		{	/*  Init_GR00_GR08 */216			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,217			0xFF,218		},219		{	/*  Init_AR00_AR14 */220			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,221			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,222			0x41, 0x00, 0x0F, 0x00, 0x00,223		},224		{	/*  Init_CR00_CR18 */225			0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,226			0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,227			0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,228			0xFF,229		},230		{	/*  Init_CR30_CR4D */231			0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,232			0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,233			0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,234			0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,235		},236		{	/*  Init_CR90_CRA7 */237			0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,238			0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,239			0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,240		},241	},242	{243		/*  mode#0: 640 x 480  32Bpp  60Hz */244		640, 480, 32, 60,245		/*  Init_MISC */246		0xE3,247		{	/*  Init_SR0_SR4 */248			0x03, 0x01, 0x0F, 0x00, 0x0E,249		},250		{	/*  Init_SR10_SR24 */251			0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,252			0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,253			0xC4, 0x30, 0x02, 0x01, 0x01,254		},255		{	/*  Init_SR30_SR75 */256			0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,257			0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,258			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,259			0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,260			0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,261			0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,262			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,263			0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,264			0x00, 0x45, 0x30, 0x30, 0x40, 0x30,265		},266		{	/*  Init_SR80_SR93 */267			0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,268			0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,269			0x00, 0x00, 0x00, 0x00,270		},271		{	/*  Init_SRA0_SRAF */272			0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,273			0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,274		},275		{	/*  Init_GR00_GR08 */276			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,277			0xFF,278		},279		{	/*  Init_AR00_AR14 */280			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,281			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,282			0x41, 0x00, 0x0F, 0x00, 0x00,283		},284		{	/*  Init_CR00_CR18 */285			0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,286			0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,287			0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,288			0xFF,289		},290		{	/*  Init_CR30_CR4D */291			0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,292			0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,293			0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,294			0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,295		},296		{	/*  Init_CR90_CRA7 */297			0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,298			0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,299			0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,300		},301	},302 303	{	/*  mode#2: 800 x 600  16Bpp  60Hz */304		800, 600, 16, 60,305		/*  Init_MISC */306		0x2B,307		{	/*  Init_SR0_SR4 */308			0x03, 0x01, 0x0F, 0x03, 0x0E,309		},310		{	/*  Init_SR10_SR24 */311			0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,312			0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,313			0xC4, 0x30, 0x02, 0x01, 0x01,314		},315		{	/*  Init_SR30_SR75 */316			0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,317			0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,318			0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,319			0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,320			0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,321			0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,322			0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,323			0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,324			0x02, 0x45, 0x30, 0x35, 0x40, 0x20,325		},326		{	/*  Init_SR80_SR93 */327			0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,328			0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,329			0x00, 0x00, 0x00, 0x00,330		},331		{	/*  Init_SRA0_SRAF */332			0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,333			0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,334		},335		{	/*  Init_GR00_GR08 */336			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,337			0xFF,338		},339		{	/*  Init_AR00_AR14 */340			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,341			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,342			0x41, 0x00, 0x0F, 0x00, 0x00,343		},344		{	/*  Init_CR00_CR18 */345			0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,346			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,347			0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,348			0xFF,349		},350		{	/*  Init_CR30_CR4D */351			0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,352			0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,353			0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,354			0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,355		},356		{	/*  Init_CR90_CRA7 */357			0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,358			0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,359			0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,360		},361	},362	{	/*  mode#3: 800 x 600  24Bpp  60Hz */363		800, 600, 24, 60,364		0x2B,365		{	/*  Init_SR0_SR4 */366			0x03, 0x01, 0x0F, 0x03, 0x0E,367		},368		{	/*  Init_SR10_SR24 */369			0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,370			0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,371			0xC4, 0x30, 0x02, 0x01, 0x01,372		},373		{	/*  Init_SR30_SR75 */374			0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36,375			0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF,376			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,377			0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36,378			0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,379			0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36,380			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,381			0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,382			0x02, 0x45, 0x30, 0x30, 0x40, 0x20,383		},384		{	/*  Init_SR80_SR93 */385			0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36,386			0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36,387			0x00, 0x00, 0x00, 0x00,388		},389		{	/*  Init_SRA0_SRAF */390			0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,391			0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,392		},393		{	/*  Init_GR00_GR08 */394			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,395			0xFF,396		},397		{	/*  Init_AR00_AR14 */398			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,399			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,400			0x41, 0x00, 0x0F, 0x00, 0x00,401		},402		{	/*  Init_CR00_CR18 */403			0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,404			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,405			0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,406			0xFF,407		},408		{	/*  Init_CR30_CR4D */409			0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,410			0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,411			0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,412			0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,413		},414		{	/*  Init_CR90_CRA7 */415			0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,416			0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,417			0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,418		},419	},420	{	/*  mode#7: 800 x 600  32Bpp  60Hz */421		800, 600, 32, 60,422		/*  Init_MISC */423		0x2B,424		{	/*  Init_SR0_SR4 */425			0x03, 0x01, 0x0F, 0x03, 0x0E,426		},427		{	/*  Init_SR10_SR24 */428			0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,429			0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,430			0xC4, 0x30, 0x02, 0x01, 0x01,431		},432		{	/*  Init_SR30_SR75 */433			0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,434			0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,435			0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,436			0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,437			0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,438			0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,439			0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,440			0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,441			0x02, 0x45, 0x30, 0x35, 0x40, 0x20,442		},443		{	/*  Init_SR80_SR93 */444			0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,445			0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,446			0x00, 0x00, 0x00, 0x00,447		},448		{	/*  Init_SRA0_SRAF */449			0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,450			0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,451		},452		{	/*  Init_GR00_GR08 */453			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,454			0xFF,455		},456		{	/*  Init_AR00_AR14 */457			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,458			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,459			0x41, 0x00, 0x0F, 0x00, 0x00,460		},461		{	/*  Init_CR00_CR18 */462			0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,463			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,464			0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,465			0xFF,466		},467		{	/*  Init_CR30_CR4D */468			0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,469			0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,470			0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,471			0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,472		},473		{	/*  Init_CR90_CRA7 */474			0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,475			0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,476			0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,477		},478	},479	/* We use 1024x768 table to light 1024x600 panel for lemote */480	{	/*  mode#4: 1024 x 600  16Bpp  60Hz  */481		1024, 600, 16, 60,482		/*  Init_MISC */483		0xEB,484		{	/*  Init_SR0_SR4 */485			0x03, 0x01, 0x0F, 0x00, 0x0E,486		},487		{	/*  Init_SR10_SR24 */488			0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20,489			0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,490			0xC4, 0x30, 0x02, 0x00, 0x01,491		},492		{	/*  Init_SR30_SR75 */493			0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22,494			0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF,495			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,496			0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22,497			0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,498			0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22,499			0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,500			0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02,501			0x04, 0x45, 0x3F, 0x30, 0x40, 0x20,502		},503		{	/*  Init_SR80_SR93 */504			0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,505			0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,506			0x00, 0x00, 0x00, 0x00,507		},508		{	/*  Init_SRA0_SRAF */509			0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,510			0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,511		},512		{	/*  Init_GR00_GR08 */513			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,514			0xFF,515		},516		{	/*  Init_AR00_AR14 */517			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,518			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,519			0x41, 0x00, 0x0F, 0x00, 0x00,520		},521		{	/*  Init_CR00_CR18 */522			0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,523			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,524			0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,525			0xFF,526		},527		{	/*  Init_CR30_CR4D */528			0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,529			0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,530			0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00,531			0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57,532		},533		{	/*  Init_CR90_CRA7 */534			0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,535			0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,536			0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,537		},538	},539	{	/*  1024 x 768  16Bpp  60Hz */540		1024, 768, 16, 60,541		/*  Init_MISC */542		0xEB,543		{	/*  Init_SR0_SR4 */544			0x03, 0x01, 0x0F, 0x03, 0x0E,545		},546		{	/*  Init_SR10_SR24 */547			0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,548			0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,549			0xC4, 0x30, 0x02, 0x01, 0x01,550		},551		{	/*  Init_SR30_SR75 */552			0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,553			0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,554			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,555			0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,556			0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,557			0x0F, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,558			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,559			0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,560			0x04, 0x45, 0x30, 0x30, 0x40, 0x20,561		},562		{	/*  Init_SR80_SR93 */563			0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,564			0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,565			0x00, 0x00, 0x00, 0x00,566		},567		{	/*  Init_SRA0_SRAF */568			0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,569			0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,570		},571		{	/*  Init_GR00_GR08 */572			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,573			0xFF,574		},575		{	/*  Init_AR00_AR14 */576			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,577			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,578			0x41, 0x00, 0x0F, 0x00, 0x00,579		},580		{	/*  Init_CR00_CR18 */581			0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,582			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,583			0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,584			0xFF,585		},586		{	/*  Init_CR30_CR4D */587			0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,588			0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,589			0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,590			0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,591		},592		{	/*  Init_CR90_CRA7 */593			0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,594			0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,595			0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,596		},597	},598	{	/*  mode#5: 1024 x 768  24Bpp  60Hz */599		1024, 768, 24, 60,600		/*  Init_MISC */601		0xEB,602		{	/*  Init_SR0_SR4 */603			0x03, 0x01, 0x0F, 0x03, 0x0E,604		},605		{	/*  Init_SR10_SR24 */606			0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,607			0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,608			0xC4, 0x30, 0x02, 0x01, 0x01,609		},610		{	/*  Init_SR30_SR75 */611			0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,612			0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,613			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,614			0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,615			0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,616			0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,617			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,618			0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,619			0x04, 0x45, 0x30, 0x30, 0x40, 0x20,620		},621		{	/*  Init_SR80_SR93 */622			0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,623			0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,624			0x00, 0x00, 0x00, 0x00,625		},626		{	/*  Init_SRA0_SRAF */627			0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,628			0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,629		},630		{	/*  Init_GR00_GR08 */631			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,632			0xFF,633		},634		{	/*  Init_AR00_AR14 */635			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,636			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,637			0x41, 0x00, 0x0F, 0x00, 0x00,638		},639		{	/*  Init_CR00_CR18 */640			0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,641			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,642			0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,643			0xFF,644		},645		{	/*  Init_CR30_CR4D */646			0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,647			0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,648			0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,649			0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,650		},651		{	/*  Init_CR90_CRA7 */652			0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,653			0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,654			0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,655		},656	},657	{	/*  mode#4: 1024 x 768  32Bpp  60Hz */658		1024, 768, 32, 60,659		/*  Init_MISC */660		0xEB,661		{	/*  Init_SR0_SR4 */662			0x03, 0x01, 0x0F, 0x03, 0x0E,663		},664		{	/*  Init_SR10_SR24 */665			0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,666			0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,667			0xC4, 0x32, 0x02, 0x01, 0x01,668		},669		{	/*  Init_SR30_SR75 */670			0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,671			0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,672			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,673			0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,674			0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,675			0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,676			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,677			0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,678			0x04, 0x45, 0x30, 0x30, 0x40, 0x20,679		},680		{	/*  Init_SR80_SR93 */681			0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,682			0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,683			0x00, 0x00, 0x00, 0x00,684		},685		{	/*  Init_SRA0_SRAF */686			0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,687			0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,688		},689		{	/*  Init_GR00_GR08 */690			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,691			0xFF,692		},693		{	/*  Init_AR00_AR14 */694			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,695			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,696			0x41, 0x00, 0x0F, 0x00, 0x00,697		},698		{	/*  Init_CR00_CR18 */699			0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,700			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,701			0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,702			0xFF,703		},704		{	/*  Init_CR30_CR4D */705			0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,706			0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,707			0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,708			0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,709		},710		{	/*  Init_CR90_CRA7 */711			0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,712			0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,713			0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,714		},715	},716	{	/*  mode#6: 320 x 240  16Bpp  60Hz */717		320, 240, 16, 60,718		/*  Init_MISC */719		0xEB,720		{	/*  Init_SR0_SR4 */721			0x03, 0x01, 0x0F, 0x03, 0x0E,722		},723		{	/*  Init_SR10_SR24 */724			0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,725			0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,726			0xC4, 0x32, 0x02, 0x01, 0x01,727		},728		{	/*  Init_SR30_SR75 */729			0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,730			0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,731			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,732			0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,733			0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,734			0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,735			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,736			0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,737			0x04, 0x45, 0x30, 0x30, 0x40, 0x20,738		},739		{	/*  Init_SR80_SR93 */740			0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,741			0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,742			0x00, 0x00, 0x00, 0x00,743		},744		{	/*  Init_SRA0_SRAF */745			0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,746			0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,747		},748		{	/*  Init_GR00_GR08 */749			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,750			0xFF,751		},752		{	/*  Init_AR00_AR14 */753			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,754			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,755			0x41, 0x00, 0x0F, 0x00, 0x00,756		},757		{	/*  Init_CR00_CR18 */758			0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,759			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,760			0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,761			0xFF,762		},763		{	/*  Init_CR30_CR4D */764			0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,765			0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,766			0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,767			0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,768		},769		{	/*  Init_CR90_CRA7 */770			0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,771			0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,772			0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,773		},774	},775 776	{	/*  mode#8: 320 x 240  32Bpp  60Hz */777		320, 240, 32, 60,778		/*  Init_MISC */779		0xEB,780		{	/*  Init_SR0_SR4 */781			0x03, 0x01, 0x0F, 0x03, 0x0E,782		},783		{	/*  Init_SR10_SR24 */784			0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,785			0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,786			0xC4, 0x32, 0x02, 0x01, 0x01,787		},788		{	/*  Init_SR30_SR75 */789			0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,790			0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,791			0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,792			0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,793			0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,794			0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,795			0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,796			0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,797			0x04, 0x45, 0x30, 0x30, 0x40, 0x20,798		},799		{	/*  Init_SR80_SR93 */800			0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,801			0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,802			0x00, 0x00, 0x00, 0x00,803		},804		{	/*  Init_SRA0_SRAF */805			0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,806			0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,807		},808		{	/*  Init_GR00_GR08 */809			0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,810			0xFF,811		},812		{	/*  Init_AR00_AR14 */813			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,814			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,815			0x41, 0x00, 0x0F, 0x00, 0x00,816		},817		{	/*  Init_CR00_CR18 */818			0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,819			0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,820			0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,821			0xFF,822		},823		{	/*  Init_CR30_CR4D */824			0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,825			0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,826			0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,827			0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,828		},829		{	/*  Init_CR90_CRA7 */830			0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,831			0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,832			0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,833		},834	},835};836 837static struct smtcfb_screen_info smtc_scr_info;838 839static char *mode_option;840 841/* process command line options, get vga parameter */842static void __init sm7xx_vga_setup(char *options)843{844	int i;845 846	if (!options || !*options)847		return;848 849	smtc_scr_info.lfb_width = 0;850	smtc_scr_info.lfb_height = 0;851	smtc_scr_info.lfb_depth = 0;852 853	pr_debug("%s = %s\n", __func__, options);854 855	for (i = 0; i < ARRAY_SIZE(vesa_mode_table); i++) {856		if (strstr(options, vesa_mode_table[i].index)) {857			smtc_scr_info.lfb_width  = vesa_mode_table[i].lfb_width;858			smtc_scr_info.lfb_height =859						vesa_mode_table[i].lfb_height;860			smtc_scr_info.lfb_depth  = vesa_mode_table[i].lfb_depth;861			return;862		}863	}864}865 866static void sm712_setpalette(int regno, unsigned int red, unsigned int green,867			     unsigned int blue, struct fb_info *info)868{869	/* set bit 5:4 = 01 (write LCD RAM only) */870	smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10);871 872	smtc_mmiowb(regno, dac_reg);873	smtc_mmiowb(red >> 10, dac_val);874	smtc_mmiowb(green >> 10, dac_val);875	smtc_mmiowb(blue >> 10, dac_val);876}877 878/* chan_to_field879 *880 * convert a colour value into a field position881 *882 * from pxafb.c883 */884 885static inline unsigned int chan_to_field(unsigned int chan,886					 struct fb_bitfield *bf)887{888	chan &= 0xffff;889	chan >>= 16 - bf->length;890	return chan << bf->offset;891}892 893static int smtc_blank(int blank_mode, struct fb_info *info)894{895	struct smtcfb_info *sfb = info->par;896 897	/* clear DPMS setting */898	switch (blank_mode) {899	case FB_BLANK_UNBLANK:900		/* Screen On: HSync: On, VSync : On */901 902		switch (sfb->chip_id) {903		case 0x710:904		case 0x712:905			smtc_seqw(0x6a, 0x16);906			smtc_seqw(0x6b, 0x02);907			break;908		case 0x720:909			smtc_seqw(0x6a, 0x0d);910			smtc_seqw(0x6b, 0x02);911			break;912		}913 914		smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));915		smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));916		smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));917		smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));918		smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));919		smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));920		break;921	case FB_BLANK_NORMAL:922		/* Screen Off: HSync: On, VSync : On   Soft blank */923		smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));924		smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));925		smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));926		smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));927		smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));928		smtc_seqw(0x6a, 0x16);929		smtc_seqw(0x6b, 0x02);930		break;931	case FB_BLANK_VSYNC_SUSPEND:932		/* Screen On: HSync: On, VSync : Off */933		smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));934		smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));935		smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));936		smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));937		smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));938		smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));939		smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));940		smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));941		smtc_seqw(0x6a, 0x0c);942		smtc_seqw(0x6b, 0x02);943		break;944	case FB_BLANK_HSYNC_SUSPEND:945		/* Screen On: HSync: Off, VSync : On */946		smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));947		smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));948		smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));949		smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));950		smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));951		smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));952		smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));953		smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));954		smtc_seqw(0x6a, 0x0c);955		smtc_seqw(0x6b, 0x02);956		break;957	case FB_BLANK_POWERDOWN:958		/* Screen On: HSync: Off, VSync : Off */959		smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));960		smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));961		smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));962		smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));963		smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));964		smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));965		smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));966		smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));967		smtc_seqw(0x6a, 0x0c);968		smtc_seqw(0x6b, 0x02);969		break;970	default:971		return -EINVAL;972	}973 974	return 0;975}976 977static int smtc_setcolreg(unsigned int regno, unsigned int red,978			  unsigned int green, unsigned int blue,979			  unsigned int trans, struct fb_info *info)980{981	struct smtcfb_info *sfb;982	u32 val;983 984	sfb = info->par;985 986	if (regno > 255)987		return 1;988 989	switch (sfb->fb->fix.visual) {990	case FB_VISUAL_DIRECTCOLOR:991	case FB_VISUAL_TRUECOLOR:992		/*993		 * 16/32 bit true-colour, use pseudo-palette for 16 base color994		 */995		if (regno >= 16)996			break;997		if (sfb->fb->var.bits_per_pixel == 16) {998			u32 *pal = sfb->fb->pseudo_palette;999 1000			val = chan_to_field(red, &sfb->fb->var.red);1001			val |= chan_to_field(green, &sfb->fb->var.green);1002			val |= chan_to_field(blue, &sfb->fb->var.blue);1003			pal[regno] = pal_rgb(red, green, blue, val);1004		} else {1005			u32 *pal = sfb->fb->pseudo_palette;1006 1007			val = chan_to_field(red, &sfb->fb->var.red);1008			val |= chan_to_field(green, &sfb->fb->var.green);1009			val |= chan_to_field(blue, &sfb->fb->var.blue);1010			pal[regno] = big_swap(val);1011		}1012		break;1013 1014	case FB_VISUAL_PSEUDOCOLOR:1015		/* color depth 8 bit */1016		sm712_setpalette(regno, red, green, blue, info);1017		break;1018 1019	default:1020		return 1;	/* unknown type */1021	}1022 1023	return 0;1024}1025 1026static ssize_t smtcfb_read(struct fb_info *info, char __user *buf,1027			   size_t count, loff_t *ppos)1028{1029	unsigned long p = *ppos;1030 1031	u32 *buffer, *dst;1032	u32 __iomem *src;1033	int c, i, cnt = 0, err = 0;1034	unsigned long total_size;1035 1036	if (!info->screen_base)1037		return -ENODEV;1038 1039	total_size = info->screen_size;1040 1041	if (total_size == 0)1042		total_size = info->fix.smem_len;1043 1044	if (p >= total_size)1045		return 0;1046 1047	if (count >= total_size)1048		count = total_size;1049 1050	if (count + p > total_size)1051		count = total_size - p;1052 1053	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);1054	if (!buffer)1055		return -ENOMEM;1056 1057	src = (u32 __iomem *)(info->screen_base + p);1058 1059	if (info->fbops->fb_sync)1060		info->fbops->fb_sync(info);1061 1062	while (count) {1063		c = (count > PAGE_SIZE) ? PAGE_SIZE : count;1064		dst = buffer;1065		for (i = (c + 3) >> 2; i--;) {1066			u32 val;1067 1068			val = fb_readl(src);1069			*dst = big_swap(val);1070			src++;1071			dst++;1072		}1073 1074		if (copy_to_user(buf, buffer, c)) {1075			err = -EFAULT;1076			break;1077		}1078		*ppos += c;1079		buf += c;1080		cnt += c;1081		count -= c;1082	}1083 1084	kfree(buffer);1085 1086	return (err) ? err : cnt;1087}1088 1089static ssize_t smtcfb_write(struct fb_info *info, const char __user *buf,1090			    size_t count, loff_t *ppos)1091{1092	unsigned long p = *ppos;1093 1094	u32 *buffer, *src;1095	u32 __iomem *dst;1096	int c, i, cnt = 0, err = 0;1097	unsigned long total_size;1098 1099	if (!info->screen_base)1100		return -ENODEV;1101 1102	total_size = info->screen_size;1103 1104	if (total_size == 0)1105		total_size = info->fix.smem_len;1106 1107	if (p > total_size)1108		return -EFBIG;1109 1110	if (count > total_size) {1111		err = -EFBIG;1112		count = total_size;1113	}1114 1115	if (count + p > total_size) {1116		if (!err)1117			err = -ENOSPC;1118 1119		count = total_size - p;1120	}1121 1122	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);1123	if (!buffer)1124		return -ENOMEM;1125 1126	dst = (u32 __iomem *)(info->screen_base + p);1127 1128	if (info->fbops->fb_sync)1129		info->fbops->fb_sync(info);1130 1131	while (count) {1132		c = (count > PAGE_SIZE) ? PAGE_SIZE : count;1133		src = buffer;1134 1135		if (copy_from_user(src, buf, c)) {1136			err = -EFAULT;1137			break;1138		}1139 1140		for (i = (c + 3) >> 2; i--;) {1141			fb_writel(big_swap(*src), dst);1142			dst++;1143			src++;1144		}1145 1146		*ppos += c;1147		buf += c;1148		cnt += c;1149		count -= c;1150	}1151 1152	kfree(buffer);1153 1154	return (cnt) ? cnt : err;1155}1156 1157static void sm7xx_set_timing(struct smtcfb_info *sfb)1158{1159	int i = 0, j = 0;1160	u32 m_nscreenstride;1161 1162	dev_dbg(&sfb->pdev->dev,1163		"sfb->width=%d sfb->height=%d sfb->fb->var.bits_per_pixel=%d sfb->hz=%d\n",1164		sfb->width, sfb->height, sfb->fb->var.bits_per_pixel, sfb->hz);1165 1166	for (j = 0; j < ARRAY_SIZE(vgamode); j++) {1167		if (vgamode[j].mmsizex != sfb->width ||1168		    vgamode[j].mmsizey != sfb->height ||1169		    vgamode[j].bpp != sfb->fb->var.bits_per_pixel ||1170		    vgamode[j].hz != sfb->hz)1171			continue;1172 1173		dev_dbg(&sfb->pdev->dev,1174			"vgamode[j].mmsizex=%d vgamode[j].mmSizeY=%d vgamode[j].bpp=%d vgamode[j].hz=%d\n",1175			vgamode[j].mmsizex, vgamode[j].mmsizey,1176			vgamode[j].bpp, vgamode[j].hz);1177 1178		dev_dbg(&sfb->pdev->dev, "vgamode index=%d\n", j);1179 1180		smtc_mmiowb(0x0, 0x3c6);1181 1182		smtc_seqw(0, 0x1);1183 1184		smtc_mmiowb(vgamode[j].init_misc, 0x3c2);1185 1186		/* init SEQ register SR00 - SR04 */1187		for (i = 0; i < SIZE_SR00_SR04; i++)1188			smtc_seqw(i, vgamode[j].init_sr00_sr04[i]);1189 1190		/* init SEQ register SR10 - SR24 */1191		for (i = 0; i < SIZE_SR10_SR24; i++)1192			smtc_seqw(i + 0x10, vgamode[j].init_sr10_sr24[i]);1193 1194		/* init SEQ register SR30 - SR75 */1195		for (i = 0; i < SIZE_SR30_SR75; i++)1196			if ((i + 0x30) != 0x30 && (i + 0x30) != 0x62 &&1197			    (i + 0x30) != 0x6a && (i + 0x30) != 0x6b &&1198			    (i + 0x30) != 0x70 && (i + 0x30) != 0x71 &&1199			    (i + 0x30) != 0x74 && (i + 0x30) != 0x75)1200				smtc_seqw(i + 0x30,1201					  vgamode[j].init_sr30_sr75[i]);1202 1203		/* init SEQ register SR80 - SR93 */1204		for (i = 0; i < SIZE_SR80_SR93; i++)1205			smtc_seqw(i + 0x80, vgamode[j].init_sr80_sr93[i]);1206 1207		/* init SEQ register SRA0 - SRAF */1208		for (i = 0; i < SIZE_SRA0_SRAF; i++)1209			smtc_seqw(i + 0xa0, vgamode[j].init_sra0_sraf[i]);1210 1211		/* init Graphic register GR00 - GR08 */1212		for (i = 0; i < SIZE_GR00_GR08; i++)1213			smtc_grphw(i, vgamode[j].init_gr00_gr08[i]);1214 1215		/* init Attribute register AR00 - AR14 */1216		for (i = 0; i < SIZE_AR00_AR14; i++)1217			smtc_attrw(i, vgamode[j].init_ar00_ar14[i]);1218 1219		/* init CRTC register CR00 - CR18 */1220		for (i = 0; i < SIZE_CR00_CR18; i++)1221			smtc_crtcw(i, vgamode[j].init_cr00_cr18[i]);1222 1223		/* init CRTC register CR30 - CR4D */1224		for (i = 0; i < SIZE_CR30_CR4D; i++) {1225			if ((i + 0x30) >= 0x3B && (i + 0x30) <= 0x3F)1226				/* side-effect, don't write to CR3B-CR3F */1227				continue;1228			smtc_crtcw(i + 0x30, vgamode[j].init_cr30_cr4d[i]);1229		}1230 1231		/* init CRTC register CR90 - CRA7 */1232		for (i = 0; i < SIZE_CR90_CRA7; i++)1233			smtc_crtcw(i + 0x90, vgamode[j].init_cr90_cra7[i]);1234	}1235	smtc_mmiowb(0x67, 0x3c2);1236 1237	/* set VPR registers */1238	writel(0x0, sfb->vp_regs + 0x0C);1239	writel(0x0, sfb->vp_regs + 0x40);1240 1241	/* set data width */1242	m_nscreenstride = (sfb->width * sfb->fb->var.bits_per_pixel) / 64;1243	switch (sfb->fb->var.bits_per_pixel) {1244	case 8:1245		writel(0x0, sfb->vp_regs + 0x0);1246		break;1247	case 16:1248		writel(0x00020000, sfb->vp_regs + 0x0);1249		break;1250	case 24:1251		writel(0x00040000, sfb->vp_regs + 0x0);1252		break;1253	case 32:1254		writel(0x00030000, sfb->vp_regs + 0x0);1255		break;1256	}1257	writel((u32)(((m_nscreenstride + 2) << 16) | m_nscreenstride),1258	       sfb->vp_regs + 0x10);1259}1260 1261static void smtc_set_timing(struct smtcfb_info *sfb)1262{1263	switch (sfb->chip_id) {1264	case 0x710:1265	case 0x712:1266	case 0x720:1267		sm7xx_set_timing(sfb);1268		break;1269	}1270}1271 1272static void smtcfb_setmode(struct smtcfb_info *sfb)1273{1274	switch (sfb->fb->var.bits_per_pixel) {1275	case 32:1276		sfb->fb->fix.visual       = FB_VISUAL_TRUECOLOR;1277		sfb->fb->fix.line_length  = sfb->fb->var.xres * 4;1278		sfb->fb->var.red.length   = 8;1279		sfb->fb->var.green.length = 8;1280		sfb->fb->var.blue.length  = 8;1281		sfb->fb->var.red.offset   = 16;1282		sfb->fb->var.green.offset = 8;1283		sfb->fb->var.blue.offset  = 0;1284		break;1285	case 24:1286		sfb->fb->fix.visual       = FB_VISUAL_TRUECOLOR;1287		sfb->fb->fix.line_length  = sfb->fb->var.xres * 3;1288		sfb->fb->var.red.length   = 8;1289		sfb->fb->var.green.length = 8;1290		sfb->fb->var.blue.length  = 8;1291		sfb->fb->var.red.offset   = 16;1292		sfb->fb->var.green.offset = 8;1293		sfb->fb->var.blue.offset  = 0;1294		break;1295	case 8:1296		sfb->fb->fix.visual       = FB_VISUAL_PSEUDOCOLOR;1297		sfb->fb->fix.line_length  = sfb->fb->var.xres;1298		sfb->fb->var.red.length   = 3;1299		sfb->fb->var.green.length = 3;1300		sfb->fb->var.blue.length  = 2;1301		sfb->fb->var.red.offset   = 5;1302		sfb->fb->var.green.offset = 2;1303		sfb->fb->var.blue.offset  = 0;1304		break;1305	case 16:1306	default:1307		sfb->fb->fix.visual       = FB_VISUAL_TRUECOLOR;1308		sfb->fb->fix.line_length  = sfb->fb->var.xres * 2;1309		sfb->fb->var.red.length   = 5;1310		sfb->fb->var.green.length = 6;1311		sfb->fb->var.blue.length  = 5;1312		sfb->fb->var.red.offset   = 11;1313		sfb->fb->var.green.offset = 5;1314		sfb->fb->var.blue.offset  = 0;1315		break;1316	}1317 1318	sfb->width  = sfb->fb->var.xres;1319	sfb->height = sfb->fb->var.yres;1320	sfb->hz = 60;1321	smtc_set_timing(sfb);1322}1323 1324static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info)1325{1326	/* sanity checks */1327	if (var->xres_virtual < var->xres)1328		var->xres_virtual = var->xres;1329 1330	if (var->yres_virtual < var->yres)1331		var->yres_virtual = var->yres;1332 1333	/* set valid default bpp */1334	if ((var->bits_per_pixel != 8)  && (var->bits_per_pixel != 16) &&1335	    (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32))1336		var->bits_per_pixel = 16;1337 1338	return 0;1339}1340 1341static int smtc_set_par(struct fb_info *info)1342{1343	smtcfb_setmode(info->par);1344 1345	return 0;1346}1347 1348static const struct fb_ops smtcfb_ops = {1349	.owner        = THIS_MODULE,1350	.fb_check_var = smtc_check_var,1351	.fb_set_par   = smtc_set_par,1352	.fb_setcolreg = smtc_setcolreg,1353	.fb_blank     = smtc_blank,1354	__FB_DEFAULT_IOMEM_OPS_DRAW,1355	.fb_read      = smtcfb_read,1356	.fb_write     = smtcfb_write,1357	__FB_DEFAULT_IOMEM_OPS_MMAP,1358};1359 1360/*1361 * Unmap in the memory mapped IO registers1362 */1363 1364static void smtc_unmap_mmio(struct smtcfb_info *sfb)1365{1366	if (sfb && smtc_regbaseaddress)1367		smtc_regbaseaddress = NULL;1368}1369 1370/*1371 * Map in the screen memory1372 */1373 1374static int smtc_map_smem(struct smtcfb_info *sfb,1375			 struct pci_dev *pdev, u_long smem_len)1376{1377	sfb->fb->fix.smem_start = pci_resource_start(pdev, 0);1378 1379	if (sfb->chip_id == 0x720)1380		/* on SM720, the framebuffer starts at the 1 MB offset */1381		sfb->fb->fix.smem_start += 0x00200000;1382 1383	/* XXX: is it safe for SM720 on Big-Endian? */1384	if (sfb->fb->var.bits_per_pixel == 32)1385		sfb->fb->fix.smem_start += big_addr;1386 1387	sfb->fb->fix.smem_len = smem_len;1388 1389	sfb->fb->screen_base = sfb->lfb;1390 1391	if (!sfb->fb->screen_base) {1392		dev_err(&pdev->dev,1393			"%s: unable to map screen memory\n", sfb->fb->fix.id);1394		return -ENOMEM;1395	}1396 1397	return 0;1398}1399 1400/*1401 * Unmap in the screen memory1402 *1403 */1404static void smtc_unmap_smem(struct smtcfb_info *sfb)1405{1406	if (sfb && sfb->fb->screen_base) {1407		if (sfb->chip_id == 0x720)1408			sfb->fb->screen_base -= 0x00200000;1409		iounmap(sfb->fb->screen_base);1410		sfb->fb->screen_base = NULL;1411	}1412}1413 1414/*1415 * We need to wake up the device and make sure its in linear memory mode.1416 */1417static inline void sm7xx_init_hw(void)1418{1419	outb_p(0x18, 0x3c4);1420	outb_p(0x11, 0x3c5);1421}1422 1423static u_long sm7xx_vram_probe(struct smtcfb_info *sfb)1424{1425	u8 vram;1426 1427	switch (sfb->chip_id) {1428	case 0x710:1429	case 0x712:1430		/*1431		 * Assume SM712 graphics chip has 4MB VRAM.1432		 *1433		 * FIXME: SM712 can have 2MB VRAM, which is used on earlier1434		 * laptops, such as IBM Thinkpad 240X. This driver would1435		 * probably crash on those machines. If anyone gets one of1436		 * those and is willing to help, run "git blame" and send me1437		 * an E-mail.1438		 */1439		return 0x00400000;1440	case 0x720:1441		outb_p(0x76, 0x3c4);1442		vram = inb_p(0x3c5) >> 6;1443 1444		if (vram == 0x00)1445			return 0x00800000;  /* 8 MB */1446		else if (vram == 0x01)1447			return 0x01000000;  /* 16 MB */1448		else if (vram == 0x02)1449			return 0x00400000;  /* illegal, fallback to 4 MB */1450		else if (vram == 0x03)1451			return 0x00400000;  /* 4 MB */1452	}1453	return 0;  /* unknown hardware */1454}1455 1456static void sm7xx_resolution_probe(struct smtcfb_info *sfb)1457{1458	/* get mode parameter from smtc_scr_info */1459	if (smtc_scr_info.lfb_width != 0) {1460		sfb->fb->var.xres = smtc_scr_info.lfb_width;1461		sfb->fb->var.yres = smtc_scr_info.lfb_height;1462		sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth;1463		goto final;1464	}1465 1466	/*1467	 * No parameter, default resolution is 1024x768-16.1468	 *1469	 * FIXME: earlier laptops, such as IBM Thinkpad 240X, has a 800x6001470	 * panel, also see the comments about Thinkpad 240X above.1471	 */1472	sfb->fb->var.xres = SCREEN_X_RES;1473	sfb->fb->var.yres = SCREEN_Y_RES_PC;1474	sfb->fb->var.bits_per_pixel = SCREEN_BPP;1475 1476#ifdef CONFIG_MIPS1477	/*1478	 * Loongson MIPS netbooks use 1024x600 LCD panels, which is the original1479	 * target platform of this driver, but nearly all old x86 laptops have1480	 * 1024x768. Lighting 768 panels using 600's timings would partially1481	 * garble the display, so we don't want that. But it's not possible to1482	 * distinguish them reliably.1483	 *1484	 * So we change the default to 768, but keep 600 as-is on MIPS.1485	 */1486	sfb->fb->var.yres = SCREEN_Y_RES_NETBOOK;1487#endif1488 1489final:1490	big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth);1491}1492 1493static int smtcfb_pci_probe(struct pci_dev *pdev,1494			    const struct pci_device_id *ent)1495{1496	struct smtcfb_info *sfb;1497	struct fb_info *info;1498	u_long smem_size;1499	int err;1500	unsigned long mmio_base;1501 1502	dev_info(&pdev->dev, "Silicon Motion display driver.\n");1503 1504	err = aperture_remove_conflicting_pci_devices(pdev, "smtcfb");1505	if (err)1506		return err;1507 1508	err = pci_enable_device(pdev);	/* enable SMTC chip */1509	if (err)1510		return err;1511 1512	err = pci_request_region(pdev, 0, "sm7xxfb");1513	if (err < 0) {1514		dev_err(&pdev->dev, "cannot reserve framebuffer region\n");1515		goto failed_regions;1516	}1517 1518	sprintf(smtcfb_fix.id, "sm%Xfb", ent->device);1519 1520	info = framebuffer_alloc(sizeof(*sfb), &pdev->dev);1521	if (!info) {1522		err = -ENOMEM;1523		goto failed_free;1524	}1525 1526	sfb = info->par;1527	sfb->fb = info;1528	sfb->chip_id = ent->device;1529	sfb->pdev = pdev;1530	info->fbops = &smtcfb_ops;1531	info->fix = smtcfb_fix;1532	info->var = smtcfb_var;1533	info->pseudo_palette = sfb->colreg;1534	info->par = sfb;1535 1536	pci_set_drvdata(pdev, sfb);1537 1538	sm7xx_init_hw();1539 1540	/* Map address and memory detection */1541	mmio_base = pci_resource_start(pdev, 0);1542	pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id);1543 1544	smem_size = sm7xx_vram_probe(sfb);1545	dev_info(&pdev->dev, "%lu MiB of VRAM detected.\n",1546					smem_size / 1048576);1547 1548	switch (sfb->chip_id) {1549	case 0x710:1550	case 0x712:1551		sfb->fb->fix.mmio_start = mmio_base + 0x00400000;1552		sfb->fb->fix.mmio_len = 0x00400000;1553		sfb->lfb = ioremap(mmio_base, mmio_addr);1554		if (!sfb->lfb) {1555			dev_err(&pdev->dev,1556				"%s: unable to map memory mapped IO!\n",1557				sfb->fb->fix.id);1558			err = -ENOMEM;1559			goto failed_fb;1560		}1561 1562		sfb->mmio = (smtc_regbaseaddress =1563		    sfb->lfb + 0x00700000);1564		sfb->dp_regs = sfb->lfb + 0x00408000;1565		sfb->vp_regs = sfb->lfb + 0x0040c000;1566		if (sfb->fb->var.bits_per_pixel == 32) {1567			sfb->lfb += big_addr;1568			dev_info(&pdev->dev, "sfb->lfb=%p\n", sfb->lfb);1569		}1570 1571		/* set MCLK = 14.31818 * (0x16 / 0x2) */1572		smtc_seqw(0x6a, 0x16);1573		smtc_seqw(0x6b, 0x02);1574		smtc_seqw(0x62, 0x3e);1575		/* enable PCI burst */1576		smtc_seqw(0x17, 0x20);1577		/* enable word swap */1578		if (sfb->fb->var.bits_per_pixel == 32)1579			seqw17();1580		break;1581	case 0x720:1582		sfb->fb->fix.mmio_start = mmio_base;1583		sfb->fb->fix.mmio_len = 0x00200000;1584		sfb->dp_regs = ioremap(mmio_base, 0x00200000 + smem_size);1585		if (!sfb->dp_regs) {1586			dev_err(&pdev->dev,1587				"%s: unable to map memory mapped IO!\n",1588				sfb->fb->fix.id);1589			err = -ENOMEM;1590			goto failed_fb;1591		}1592 1593		sfb->lfb = sfb->dp_regs + 0x00200000;1594		sfb->mmio = (smtc_regbaseaddress =1595		    sfb->dp_regs + 0x000c0000);1596		sfb->vp_regs = sfb->dp_regs + 0x800;1597 1598		smtc_seqw(0x62, 0xff);1599		smtc_seqw(0x6a, 0x0d);1600		smtc_seqw(0x6b, 0x02);1601		break;1602	default:1603		dev_err(&pdev->dev,1604			"No valid Silicon Motion display chip was detected!\n");1605		err = -ENODEV;1606		goto failed_fb;1607	}1608 1609	/* probe and decide resolution */1610	sm7xx_resolution_probe(sfb);1611 1612	/* can support 32 bpp */1613	if (sfb->fb->var.bits_per_pixel == 15)1614		sfb->fb->var.bits_per_pixel = 16;1615 1616	sfb->fb->var.xres_virtual = sfb->fb->var.xres;1617	sfb->fb->var.yres_virtual = sfb->fb->var.yres;1618	err = smtc_map_smem(sfb, pdev, smem_size);1619	if (err)1620		goto failed;1621 1622	/*1623	 * The screen would be temporarily garbled when sm712fb takes over1624	 * vesafb or VGA text mode. Zero the framebuffer.1625	 */1626	memset_io(sfb->lfb, 0, sfb->fb->fix.smem_len);1627 1628	err = register_framebuffer(info);1629	if (err < 0)1630		goto failed;1631 1632	dev_info(&pdev->dev,1633		 "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.\n",1634		 sfb->chip_id, sfb->chip_rev_id, sfb->fb->var.xres,1635		 sfb->fb->var.yres, sfb->fb->var.bits_per_pixel);1636 1637	return 0;1638 1639failed:1640	dev_err(&pdev->dev, "Silicon Motion, Inc. primary display init fail.\n");1641 1642	smtc_unmap_smem(sfb);1643	smtc_unmap_mmio(sfb);1644failed_fb:1645	framebuffer_release(info);1646 1647failed_free:1648	pci_release_region(pdev, 0);1649 1650failed_regions:1651	pci_disable_device(pdev);1652 1653	return err;1654}1655 1656/*1657 * 0x710 (LynxEM)1658 * 0x712 (LynxEM+)1659 * 0x720 (Lynx3DM, Lynx3DM+)1660 */1661static const struct pci_device_id smtcfb_pci_table[] = {1662	{ PCI_DEVICE(0x126f, 0x710), },1663	{ PCI_DEVICE(0x126f, 0x712), },1664	{ PCI_DEVICE(0x126f, 0x720), },1665	{0,}1666};1667 1668MODULE_DEVICE_TABLE(pci, smtcfb_pci_table);1669 1670static void smtcfb_pci_remove(struct pci_dev *pdev)1671{1672	struct smtcfb_info *sfb;1673 1674	sfb = pci_get_drvdata(pdev);1675	smtc_unmap_smem(sfb);1676	smtc_unmap_mmio(sfb);1677	unregister_framebuffer(sfb->fb);1678	framebuffer_release(sfb->fb);1679	pci_release_region(pdev, 0);1680	pci_disable_device(pdev);1681}1682 1683static int __maybe_unused smtcfb_pci_suspend(struct device *device)1684{1685	struct smtcfb_info *sfb = dev_get_drvdata(device);1686 1687 1688	/* set the hw in sleep mode use external clock and self memory refresh1689	 * so that we can turn off internal PLLs later on1690	 */1691	smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));1692	smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));1693 1694	console_lock();1695	fb_set_suspend(sfb->fb, 1);1696	console_unlock();1697 1698	/* additionally turn off all function blocks including internal PLLs */1699	smtc_seqw(0x21, 0xff);1700 1701	return 0;1702}1703 1704static int __maybe_unused smtcfb_pci_resume(struct device *device)1705{1706	struct smtcfb_info *sfb = dev_get_drvdata(device);1707 1708 1709	/* reinit hardware */1710	sm7xx_init_hw();1711	switch (sfb->chip_id) {1712	case 0x710:1713	case 0x712:1714		/* set MCLK = 14.31818 *  (0x16 / 0x2) */1715		smtc_seqw(0x6a, 0x16);1716		smtc_seqw(0x6b, 0x02);1717		smtc_seqw(0x62, 0x3e);1718		/* enable PCI burst */1719		smtc_seqw(0x17, 0x20);1720		if (sfb->fb->var.bits_per_pixel == 32)1721			seqw17();1722		break;1723	case 0x720:1724		smtc_seqw(0x62, 0xff);1725		smtc_seqw(0x6a, 0x0d);1726		smtc_seqw(0x6b, 0x02);1727		break;1728	}1729 1730	smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0));1731	smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb));1732 1733	smtcfb_setmode(sfb);1734 1735	console_lock();1736	fb_set_suspend(sfb->fb, 0);1737	console_unlock();1738 1739	return 0;1740}1741 1742static SIMPLE_DEV_PM_OPS(sm7xx_pm_ops, smtcfb_pci_suspend, smtcfb_pci_resume);1743 1744static struct pci_driver smtcfb_driver = {1745	.name = "smtcfb",1746	.id_table = smtcfb_pci_table,1747	.probe = smtcfb_pci_probe,1748	.remove = smtcfb_pci_remove,1749	.driver.pm  = &sm7xx_pm_ops,1750};1751 1752static int __init sm712fb_init(void)1753{1754	char *option = NULL;1755 1756	if (fb_modesetting_disabled("sm712fb"))1757		return -ENODEV;1758 1759	if (fb_get_options("sm712fb", &option))1760		return -ENODEV;1761	if (option && *option)1762		mode_option = option;1763	sm7xx_vga_setup(mode_option);1764 1765	return pci_register_driver(&smtcfb_driver);1766}1767 1768module_init(sm712fb_init);1769 1770static void __exit sm712fb_exit(void)1771{1772	pci_unregister_driver(&smtcfb_driver);1773}1774 1775module_exit(sm712fb_exit);1776 1777MODULE_AUTHOR("Siliconmotion ");1778MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards");1779MODULE_LICENSE("GPL");1780