162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Silicon Motion SM7XX frame buffer device 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2006 Silicon Motion Technology Corp. 562306a36Sopenharmony_ci * Authors: Ge Wang, gewang@siliconmotion.com 662306a36Sopenharmony_ci * Boyod boyod.yang@siliconmotion.com.cn 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Copyright (C) 2009 Lemote, Inc. 962306a36Sopenharmony_ci * Author: Wu Zhangjin, wuzhangjin@gmail.com 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Copyright (C) 2011 Igalia, S.L. 1262306a36Sopenharmony_ci * Author: Javier M. Mellid <jmunhoz@igalia.com> 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 1562306a36Sopenharmony_ci * License. See the file COPYING in the main directory of this archive for 1662306a36Sopenharmony_ci * more details. 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * Framebuffer driver for Silicon Motion SM710, SM712, SM721 and SM722 chips 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <linux/aperture.h> 2262306a36Sopenharmony_ci#include <linux/io.h> 2362306a36Sopenharmony_ci#include <linux/fb.h> 2462306a36Sopenharmony_ci#include <linux/pci.h> 2562306a36Sopenharmony_ci#include <linux/init.h> 2662306a36Sopenharmony_ci#include <linux/slab.h> 2762306a36Sopenharmony_ci#include <linux/uaccess.h> 2862306a36Sopenharmony_ci#include <linux/module.h> 2962306a36Sopenharmony_ci#include <linux/console.h> 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#include <linux/pm.h> 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#include "sm712.h" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistruct smtcfb_screen_info { 3662306a36Sopenharmony_ci u16 lfb_width; 3762306a36Sopenharmony_ci u16 lfb_height; 3862306a36Sopenharmony_ci u16 lfb_depth; 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* 4262306a36Sopenharmony_ci * Private structure 4362306a36Sopenharmony_ci */ 4462306a36Sopenharmony_cistruct smtcfb_info { 4562306a36Sopenharmony_ci struct pci_dev *pdev; 4662306a36Sopenharmony_ci struct fb_info *fb; 4762306a36Sopenharmony_ci u16 chip_id; 4862306a36Sopenharmony_ci u8 chip_rev_id; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci void __iomem *lfb; /* linear frame buffer */ 5162306a36Sopenharmony_ci void __iomem *dp_regs; /* drawing processor control regs */ 5262306a36Sopenharmony_ci void __iomem *vp_regs; /* video processor control regs */ 5362306a36Sopenharmony_ci void __iomem *cp_regs; /* capture processor control regs */ 5462306a36Sopenharmony_ci void __iomem *mmio; /* memory map IO port */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci u_int width; 5762306a36Sopenharmony_ci u_int height; 5862306a36Sopenharmony_ci u_int hz; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci u32 colreg[17]; 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_civoid __iomem *smtc_regbaseaddress; /* Memory Map IO starting address */ 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic const struct fb_var_screeninfo smtcfb_var = { 6662306a36Sopenharmony_ci .xres = 1024, 6762306a36Sopenharmony_ci .yres = 600, 6862306a36Sopenharmony_ci .xres_virtual = 1024, 6962306a36Sopenharmony_ci .yres_virtual = 600, 7062306a36Sopenharmony_ci .bits_per_pixel = 16, 7162306a36Sopenharmony_ci .red = {16, 8, 0}, 7262306a36Sopenharmony_ci .green = {8, 8, 0}, 7362306a36Sopenharmony_ci .blue = {0, 8, 0}, 7462306a36Sopenharmony_ci .activate = FB_ACTIVATE_NOW, 7562306a36Sopenharmony_ci .height = -1, 7662306a36Sopenharmony_ci .width = -1, 7762306a36Sopenharmony_ci .vmode = FB_VMODE_NONINTERLACED, 7862306a36Sopenharmony_ci .nonstd = 0, 7962306a36Sopenharmony_ci .accel_flags = FB_ACCELF_TEXT, 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic struct fb_fix_screeninfo smtcfb_fix = { 8362306a36Sopenharmony_ci .id = "smXXXfb", 8462306a36Sopenharmony_ci .type = FB_TYPE_PACKED_PIXELS, 8562306a36Sopenharmony_ci .visual = FB_VISUAL_TRUECOLOR, 8662306a36Sopenharmony_ci .line_length = 800 * 3, 8762306a36Sopenharmony_ci .accel = FB_ACCEL_SMI_LYNX, 8862306a36Sopenharmony_ci .type_aux = 0, 8962306a36Sopenharmony_ci .xpanstep = 0, 9062306a36Sopenharmony_ci .ypanstep = 0, 9162306a36Sopenharmony_ci .ywrapstep = 0, 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistruct vesa_mode { 9562306a36Sopenharmony_ci char index[6]; 9662306a36Sopenharmony_ci u16 lfb_width; 9762306a36Sopenharmony_ci u16 lfb_height; 9862306a36Sopenharmony_ci u16 lfb_depth; 9962306a36Sopenharmony_ci}; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic const struct vesa_mode vesa_mode_table[] = { 10262306a36Sopenharmony_ci {"0x301", 640, 480, 8}, 10362306a36Sopenharmony_ci {"0x303", 800, 600, 8}, 10462306a36Sopenharmony_ci {"0x305", 1024, 768, 8}, 10562306a36Sopenharmony_ci {"0x307", 1280, 1024, 8}, 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci {"0x311", 640, 480, 16}, 10862306a36Sopenharmony_ci {"0x314", 800, 600, 16}, 10962306a36Sopenharmony_ci {"0x317", 1024, 768, 16}, 11062306a36Sopenharmony_ci {"0x31A", 1280, 1024, 16}, 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci {"0x312", 640, 480, 24}, 11362306a36Sopenharmony_ci {"0x315", 800, 600, 24}, 11462306a36Sopenharmony_ci {"0x318", 1024, 768, 24}, 11562306a36Sopenharmony_ci {"0x31B", 1280, 1024, 24}, 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/********************************************************************** 11962306a36Sopenharmony_ci SM712 Mode table. 12062306a36Sopenharmony_ci **********************************************************************/ 12162306a36Sopenharmony_cistatic const struct modeinit vgamode[] = { 12262306a36Sopenharmony_ci { 12362306a36Sopenharmony_ci /* mode#0: 640 x 480 16Bpp 60Hz */ 12462306a36Sopenharmony_ci 640, 480, 16, 60, 12562306a36Sopenharmony_ci /* Init_MISC */ 12662306a36Sopenharmony_ci 0xE3, 12762306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 12862306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x00, 0x0E, 12962306a36Sopenharmony_ci }, 13062306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 13162306a36Sopenharmony_ci 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, 13262306a36Sopenharmony_ci 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13362306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x01, 0x01, 13462306a36Sopenharmony_ci }, 13562306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 13662306a36Sopenharmony_ci 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, 13762306a36Sopenharmony_ci 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, 13862306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 13962306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, 14062306a36Sopenharmony_ci 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, 14162306a36Sopenharmony_ci 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, 14262306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 14362306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, 14462306a36Sopenharmony_ci 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, 14562306a36Sopenharmony_ci }, 14662306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 14762306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, 14862306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, 14962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 15062306a36Sopenharmony_ci }, 15162306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 15262306a36Sopenharmony_ci 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, 15362306a36Sopenharmony_ci 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, 15462306a36Sopenharmony_ci }, 15562306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 15662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 15762306a36Sopenharmony_ci 0xFF, 15862306a36Sopenharmony_ci }, 15962306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 16062306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 16162306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 16262306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 16362306a36Sopenharmony_ci }, 16462306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 16562306a36Sopenharmony_ci 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, 16662306a36Sopenharmony_ci 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16762306a36Sopenharmony_ci 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, 16862306a36Sopenharmony_ci 0xFF, 16962306a36Sopenharmony_ci }, 17062306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 17162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, 17262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, 17362306a36Sopenharmony_ci 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, 17462306a36Sopenharmony_ci 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, 17562306a36Sopenharmony_ci }, 17662306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 17762306a36Sopenharmony_ci 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, 17862306a36Sopenharmony_ci 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, 17962306a36Sopenharmony_ci 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, 18062306a36Sopenharmony_ci }, 18162306a36Sopenharmony_ci }, 18262306a36Sopenharmony_ci { 18362306a36Sopenharmony_ci /* mode#1: 640 x 480 24Bpp 60Hz */ 18462306a36Sopenharmony_ci 640, 480, 24, 60, 18562306a36Sopenharmony_ci /* Init_MISC */ 18662306a36Sopenharmony_ci 0xE3, 18762306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 18862306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x00, 0x0E, 18962306a36Sopenharmony_ci }, 19062306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 19162306a36Sopenharmony_ci 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, 19262306a36Sopenharmony_ci 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19362306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x01, 0x01, 19462306a36Sopenharmony_ci }, 19562306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 19662306a36Sopenharmony_ci 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, 19762306a36Sopenharmony_ci 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, 19862306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 19962306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, 20062306a36Sopenharmony_ci 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, 20162306a36Sopenharmony_ci 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, 20262306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 20362306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, 20462306a36Sopenharmony_ci 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, 20562306a36Sopenharmony_ci }, 20662306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 20762306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, 20862306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, 20962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 21062306a36Sopenharmony_ci }, 21162306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 21262306a36Sopenharmony_ci 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, 21362306a36Sopenharmony_ci 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, 21462306a36Sopenharmony_ci }, 21562306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 21662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 21762306a36Sopenharmony_ci 0xFF, 21862306a36Sopenharmony_ci }, 21962306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 22062306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 22162306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 22262306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 22362306a36Sopenharmony_ci }, 22462306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 22562306a36Sopenharmony_ci 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, 22662306a36Sopenharmony_ci 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22762306a36Sopenharmony_ci 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, 22862306a36Sopenharmony_ci 0xFF, 22962306a36Sopenharmony_ci }, 23062306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 23162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, 23262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, 23362306a36Sopenharmony_ci 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, 23462306a36Sopenharmony_ci 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, 23562306a36Sopenharmony_ci }, 23662306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 23762306a36Sopenharmony_ci 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, 23862306a36Sopenharmony_ci 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, 23962306a36Sopenharmony_ci 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, 24062306a36Sopenharmony_ci }, 24162306a36Sopenharmony_ci }, 24262306a36Sopenharmony_ci { 24362306a36Sopenharmony_ci /* mode#0: 640 x 480 32Bpp 60Hz */ 24462306a36Sopenharmony_ci 640, 480, 32, 60, 24562306a36Sopenharmony_ci /* Init_MISC */ 24662306a36Sopenharmony_ci 0xE3, 24762306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 24862306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x00, 0x0E, 24962306a36Sopenharmony_ci }, 25062306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 25162306a36Sopenharmony_ci 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, 25262306a36Sopenharmony_ci 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25362306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x01, 0x01, 25462306a36Sopenharmony_ci }, 25562306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 25662306a36Sopenharmony_ci 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, 25762306a36Sopenharmony_ci 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, 25862306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 25962306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, 26062306a36Sopenharmony_ci 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, 26162306a36Sopenharmony_ci 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, 26262306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 26362306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, 26462306a36Sopenharmony_ci 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, 26562306a36Sopenharmony_ci }, 26662306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 26762306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, 26862306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, 26962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 27062306a36Sopenharmony_ci }, 27162306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 27262306a36Sopenharmony_ci 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, 27362306a36Sopenharmony_ci 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, 27462306a36Sopenharmony_ci }, 27562306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 27662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 27762306a36Sopenharmony_ci 0xFF, 27862306a36Sopenharmony_ci }, 27962306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 28062306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 28162306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 28262306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 28362306a36Sopenharmony_ci }, 28462306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 28562306a36Sopenharmony_ci 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, 28662306a36Sopenharmony_ci 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28762306a36Sopenharmony_ci 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, 28862306a36Sopenharmony_ci 0xFF, 28962306a36Sopenharmony_ci }, 29062306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 29162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, 29262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, 29362306a36Sopenharmony_ci 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, 29462306a36Sopenharmony_ci 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, 29562306a36Sopenharmony_ci }, 29662306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 29762306a36Sopenharmony_ci 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, 29862306a36Sopenharmony_ci 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, 29962306a36Sopenharmony_ci 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, 30062306a36Sopenharmony_ci }, 30162306a36Sopenharmony_ci }, 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci { /* mode#2: 800 x 600 16Bpp 60Hz */ 30462306a36Sopenharmony_ci 800, 600, 16, 60, 30562306a36Sopenharmony_ci /* Init_MISC */ 30662306a36Sopenharmony_ci 0x2B, 30762306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 30862306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x03, 0x0E, 30962306a36Sopenharmony_ci }, 31062306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 31162306a36Sopenharmony_ci 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, 31262306a36Sopenharmony_ci 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 31362306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x01, 0x01, 31462306a36Sopenharmony_ci }, 31562306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 31662306a36Sopenharmony_ci 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, 31762306a36Sopenharmony_ci 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, 31862306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, 31962306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, 32062306a36Sopenharmony_ci 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, 32162306a36Sopenharmony_ci 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, 32262306a36Sopenharmony_ci 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 32362306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, 32462306a36Sopenharmony_ci 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, 32562306a36Sopenharmony_ci }, 32662306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 32762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, 32862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, 32962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 33062306a36Sopenharmony_ci }, 33162306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 33262306a36Sopenharmony_ci 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, 33362306a36Sopenharmony_ci 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, 33462306a36Sopenharmony_ci }, 33562306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 33662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 33762306a36Sopenharmony_ci 0xFF, 33862306a36Sopenharmony_ci }, 33962306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 34062306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 34162306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 34262306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 34362306a36Sopenharmony_ci }, 34462306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 34562306a36Sopenharmony_ci 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, 34662306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34762306a36Sopenharmony_ci 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, 34862306a36Sopenharmony_ci 0xFF, 34962306a36Sopenharmony_ci }, 35062306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 35162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, 35262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, 35362306a36Sopenharmony_ci 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, 35462306a36Sopenharmony_ci 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, 35562306a36Sopenharmony_ci }, 35662306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 35762306a36Sopenharmony_ci 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, 35862306a36Sopenharmony_ci 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, 35962306a36Sopenharmony_ci 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, 36062306a36Sopenharmony_ci }, 36162306a36Sopenharmony_ci }, 36262306a36Sopenharmony_ci { /* mode#3: 800 x 600 24Bpp 60Hz */ 36362306a36Sopenharmony_ci 800, 600, 24, 60, 36462306a36Sopenharmony_ci 0x2B, 36562306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 36662306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x03, 0x0E, 36762306a36Sopenharmony_ci }, 36862306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 36962306a36Sopenharmony_ci 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, 37062306a36Sopenharmony_ci 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37162306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x01, 0x01, 37262306a36Sopenharmony_ci }, 37362306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 37462306a36Sopenharmony_ci 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36, 37562306a36Sopenharmony_ci 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF, 37662306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 37762306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36, 37862306a36Sopenharmony_ci 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, 37962306a36Sopenharmony_ci 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36, 38062306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 38162306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, 38262306a36Sopenharmony_ci 0x02, 0x45, 0x30, 0x30, 0x40, 0x20, 38362306a36Sopenharmony_ci }, 38462306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 38562306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36, 38662306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36, 38762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 38862306a36Sopenharmony_ci }, 38962306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 39062306a36Sopenharmony_ci 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, 39162306a36Sopenharmony_ci 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, 39262306a36Sopenharmony_ci }, 39362306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 39462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 39562306a36Sopenharmony_ci 0xFF, 39662306a36Sopenharmony_ci }, 39762306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 39862306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 39962306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 40062306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 40162306a36Sopenharmony_ci }, 40262306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 40362306a36Sopenharmony_ci 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, 40462306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40562306a36Sopenharmony_ci 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, 40662306a36Sopenharmony_ci 0xFF, 40762306a36Sopenharmony_ci }, 40862306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 40962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, 41062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, 41162306a36Sopenharmony_ci 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, 41262306a36Sopenharmony_ci 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, 41362306a36Sopenharmony_ci }, 41462306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 41562306a36Sopenharmony_ci 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, 41662306a36Sopenharmony_ci 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, 41762306a36Sopenharmony_ci 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, 41862306a36Sopenharmony_ci }, 41962306a36Sopenharmony_ci }, 42062306a36Sopenharmony_ci { /* mode#7: 800 x 600 32Bpp 60Hz */ 42162306a36Sopenharmony_ci 800, 600, 32, 60, 42262306a36Sopenharmony_ci /* Init_MISC */ 42362306a36Sopenharmony_ci 0x2B, 42462306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 42562306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x03, 0x0E, 42662306a36Sopenharmony_ci }, 42762306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 42862306a36Sopenharmony_ci 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, 42962306a36Sopenharmony_ci 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 43062306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x01, 0x01, 43162306a36Sopenharmony_ci }, 43262306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 43362306a36Sopenharmony_ci 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, 43462306a36Sopenharmony_ci 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, 43562306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, 43662306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, 43762306a36Sopenharmony_ci 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, 43862306a36Sopenharmony_ci 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, 43962306a36Sopenharmony_ci 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 44062306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, 44162306a36Sopenharmony_ci 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, 44262306a36Sopenharmony_ci }, 44362306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 44462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, 44562306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, 44662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 44762306a36Sopenharmony_ci }, 44862306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 44962306a36Sopenharmony_ci 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, 45062306a36Sopenharmony_ci 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, 45162306a36Sopenharmony_ci }, 45262306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 45362306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 45462306a36Sopenharmony_ci 0xFF, 45562306a36Sopenharmony_ci }, 45662306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 45762306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 45862306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 45962306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 46062306a36Sopenharmony_ci }, 46162306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 46262306a36Sopenharmony_ci 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, 46362306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46462306a36Sopenharmony_ci 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, 46562306a36Sopenharmony_ci 0xFF, 46662306a36Sopenharmony_ci }, 46762306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 46862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, 46962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, 47062306a36Sopenharmony_ci 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, 47162306a36Sopenharmony_ci 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, 47262306a36Sopenharmony_ci }, 47362306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 47462306a36Sopenharmony_ci 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, 47562306a36Sopenharmony_ci 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, 47662306a36Sopenharmony_ci 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, 47762306a36Sopenharmony_ci }, 47862306a36Sopenharmony_ci }, 47962306a36Sopenharmony_ci /* We use 1024x768 table to light 1024x600 panel for lemote */ 48062306a36Sopenharmony_ci { /* mode#4: 1024 x 600 16Bpp 60Hz */ 48162306a36Sopenharmony_ci 1024, 600, 16, 60, 48262306a36Sopenharmony_ci /* Init_MISC */ 48362306a36Sopenharmony_ci 0xEB, 48462306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 48562306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x00, 0x0E, 48662306a36Sopenharmony_ci }, 48762306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 48862306a36Sopenharmony_ci 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20, 48962306a36Sopenharmony_ci 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 49062306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x00, 0x01, 49162306a36Sopenharmony_ci }, 49262306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 49362306a36Sopenharmony_ci 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22, 49462306a36Sopenharmony_ci 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF, 49562306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 49662306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22, 49762306a36Sopenharmony_ci 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, 49862306a36Sopenharmony_ci 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22, 49962306a36Sopenharmony_ci 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 50062306a36Sopenharmony_ci 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02, 50162306a36Sopenharmony_ci 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20, 50262306a36Sopenharmony_ci }, 50362306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 50462306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, 50562306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, 50662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 50762306a36Sopenharmony_ci }, 50862306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 50962306a36Sopenharmony_ci 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, 51062306a36Sopenharmony_ci 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, 51162306a36Sopenharmony_ci }, 51262306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 51362306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 51462306a36Sopenharmony_ci 0xFF, 51562306a36Sopenharmony_ci }, 51662306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 51762306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 51862306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 51962306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 52062306a36Sopenharmony_ci }, 52162306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 52262306a36Sopenharmony_ci 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, 52362306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52462306a36Sopenharmony_ci 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, 52562306a36Sopenharmony_ci 0xFF, 52662306a36Sopenharmony_ci }, 52762306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 52862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, 52962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, 53062306a36Sopenharmony_ci 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00, 53162306a36Sopenharmony_ci 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57, 53262306a36Sopenharmony_ci }, 53362306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 53462306a36Sopenharmony_ci 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, 53562306a36Sopenharmony_ci 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, 53662306a36Sopenharmony_ci 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, 53762306a36Sopenharmony_ci }, 53862306a36Sopenharmony_ci }, 53962306a36Sopenharmony_ci { /* 1024 x 768 16Bpp 60Hz */ 54062306a36Sopenharmony_ci 1024, 768, 16, 60, 54162306a36Sopenharmony_ci /* Init_MISC */ 54262306a36Sopenharmony_ci 0xEB, 54362306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 54462306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x03, 0x0E, 54562306a36Sopenharmony_ci }, 54662306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 54762306a36Sopenharmony_ci 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, 54862306a36Sopenharmony_ci 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 54962306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x01, 0x01, 55062306a36Sopenharmony_ci }, 55162306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 55262306a36Sopenharmony_ci 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, 55362306a36Sopenharmony_ci 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, 55462306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 55562306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, 55662306a36Sopenharmony_ci 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, 55762306a36Sopenharmony_ci 0x0F, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, 55862306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 55962306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, 56062306a36Sopenharmony_ci 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, 56162306a36Sopenharmony_ci }, 56262306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 56362306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, 56462306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, 56562306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 56662306a36Sopenharmony_ci }, 56762306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 56862306a36Sopenharmony_ci 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, 56962306a36Sopenharmony_ci 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, 57062306a36Sopenharmony_ci }, 57162306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 57262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 57362306a36Sopenharmony_ci 0xFF, 57462306a36Sopenharmony_ci }, 57562306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 57662306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 57762306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 57862306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 57962306a36Sopenharmony_ci }, 58062306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 58162306a36Sopenharmony_ci 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, 58262306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58362306a36Sopenharmony_ci 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, 58462306a36Sopenharmony_ci 0xFF, 58562306a36Sopenharmony_ci }, 58662306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 58762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, 58862306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, 58962306a36Sopenharmony_ci 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, 59062306a36Sopenharmony_ci 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, 59162306a36Sopenharmony_ci }, 59262306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 59362306a36Sopenharmony_ci 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, 59462306a36Sopenharmony_ci 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, 59562306a36Sopenharmony_ci 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, 59662306a36Sopenharmony_ci }, 59762306a36Sopenharmony_ci }, 59862306a36Sopenharmony_ci { /* mode#5: 1024 x 768 24Bpp 60Hz */ 59962306a36Sopenharmony_ci 1024, 768, 24, 60, 60062306a36Sopenharmony_ci /* Init_MISC */ 60162306a36Sopenharmony_ci 0xEB, 60262306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 60362306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x03, 0x0E, 60462306a36Sopenharmony_ci }, 60562306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 60662306a36Sopenharmony_ci 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, 60762306a36Sopenharmony_ci 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 60862306a36Sopenharmony_ci 0xC4, 0x30, 0x02, 0x01, 0x01, 60962306a36Sopenharmony_ci }, 61062306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 61162306a36Sopenharmony_ci 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, 61262306a36Sopenharmony_ci 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, 61362306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 61462306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, 61562306a36Sopenharmony_ci 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, 61662306a36Sopenharmony_ci 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, 61762306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 61862306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, 61962306a36Sopenharmony_ci 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, 62062306a36Sopenharmony_ci }, 62162306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 62262306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, 62362306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, 62462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 62562306a36Sopenharmony_ci }, 62662306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 62762306a36Sopenharmony_ci 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, 62862306a36Sopenharmony_ci 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, 62962306a36Sopenharmony_ci }, 63062306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 63162306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 63262306a36Sopenharmony_ci 0xFF, 63362306a36Sopenharmony_ci }, 63462306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 63562306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 63662306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 63762306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 63862306a36Sopenharmony_ci }, 63962306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 64062306a36Sopenharmony_ci 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, 64162306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64262306a36Sopenharmony_ci 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, 64362306a36Sopenharmony_ci 0xFF, 64462306a36Sopenharmony_ci }, 64562306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 64662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, 64762306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, 64862306a36Sopenharmony_ci 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, 64962306a36Sopenharmony_ci 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, 65062306a36Sopenharmony_ci }, 65162306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 65262306a36Sopenharmony_ci 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, 65362306a36Sopenharmony_ci 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, 65462306a36Sopenharmony_ci 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, 65562306a36Sopenharmony_ci }, 65662306a36Sopenharmony_ci }, 65762306a36Sopenharmony_ci { /* mode#4: 1024 x 768 32Bpp 60Hz */ 65862306a36Sopenharmony_ci 1024, 768, 32, 60, 65962306a36Sopenharmony_ci /* Init_MISC */ 66062306a36Sopenharmony_ci 0xEB, 66162306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 66262306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x03, 0x0E, 66362306a36Sopenharmony_ci }, 66462306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 66562306a36Sopenharmony_ci 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, 66662306a36Sopenharmony_ci 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 66762306a36Sopenharmony_ci 0xC4, 0x32, 0x02, 0x01, 0x01, 66862306a36Sopenharmony_ci }, 66962306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 67062306a36Sopenharmony_ci 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, 67162306a36Sopenharmony_ci 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, 67262306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 67362306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, 67462306a36Sopenharmony_ci 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, 67562306a36Sopenharmony_ci 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, 67662306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 67762306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, 67862306a36Sopenharmony_ci 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, 67962306a36Sopenharmony_ci }, 68062306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 68162306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, 68262306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, 68362306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 68462306a36Sopenharmony_ci }, 68562306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 68662306a36Sopenharmony_ci 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, 68762306a36Sopenharmony_ci 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, 68862306a36Sopenharmony_ci }, 68962306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 69062306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 69162306a36Sopenharmony_ci 0xFF, 69262306a36Sopenharmony_ci }, 69362306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 69462306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 69562306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 69662306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 69762306a36Sopenharmony_ci }, 69862306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 69962306a36Sopenharmony_ci 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, 70062306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70162306a36Sopenharmony_ci 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, 70262306a36Sopenharmony_ci 0xFF, 70362306a36Sopenharmony_ci }, 70462306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 70562306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, 70662306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, 70762306a36Sopenharmony_ci 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, 70862306a36Sopenharmony_ci 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, 70962306a36Sopenharmony_ci }, 71062306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 71162306a36Sopenharmony_ci 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, 71262306a36Sopenharmony_ci 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, 71362306a36Sopenharmony_ci 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, 71462306a36Sopenharmony_ci }, 71562306a36Sopenharmony_ci }, 71662306a36Sopenharmony_ci { /* mode#6: 320 x 240 16Bpp 60Hz */ 71762306a36Sopenharmony_ci 320, 240, 16, 60, 71862306a36Sopenharmony_ci /* Init_MISC */ 71962306a36Sopenharmony_ci 0xEB, 72062306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 72162306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x03, 0x0E, 72262306a36Sopenharmony_ci }, 72362306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 72462306a36Sopenharmony_ci 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, 72562306a36Sopenharmony_ci 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 72662306a36Sopenharmony_ci 0xC4, 0x32, 0x02, 0x01, 0x01, 72762306a36Sopenharmony_ci }, 72862306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 72962306a36Sopenharmony_ci 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, 73062306a36Sopenharmony_ci 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, 73162306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 73262306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, 73362306a36Sopenharmony_ci 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, 73462306a36Sopenharmony_ci 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, 73562306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 73662306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, 73762306a36Sopenharmony_ci 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, 73862306a36Sopenharmony_ci }, 73962306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 74062306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, 74162306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, 74262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 74362306a36Sopenharmony_ci }, 74462306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 74562306a36Sopenharmony_ci 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, 74662306a36Sopenharmony_ci 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, 74762306a36Sopenharmony_ci }, 74862306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 74962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 75062306a36Sopenharmony_ci 0xFF, 75162306a36Sopenharmony_ci }, 75262306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 75362306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 75462306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 75562306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 75662306a36Sopenharmony_ci }, 75762306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 75862306a36Sopenharmony_ci 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, 75962306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76062306a36Sopenharmony_ci 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, 76162306a36Sopenharmony_ci 0xFF, 76262306a36Sopenharmony_ci }, 76362306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 76462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, 76562306a36Sopenharmony_ci 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, 76662306a36Sopenharmony_ci 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, 76762306a36Sopenharmony_ci 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, 76862306a36Sopenharmony_ci }, 76962306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 77062306a36Sopenharmony_ci 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, 77162306a36Sopenharmony_ci 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, 77262306a36Sopenharmony_ci 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, 77362306a36Sopenharmony_ci }, 77462306a36Sopenharmony_ci }, 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci { /* mode#8: 320 x 240 32Bpp 60Hz */ 77762306a36Sopenharmony_ci 320, 240, 32, 60, 77862306a36Sopenharmony_ci /* Init_MISC */ 77962306a36Sopenharmony_ci 0xEB, 78062306a36Sopenharmony_ci { /* Init_SR0_SR4 */ 78162306a36Sopenharmony_ci 0x03, 0x01, 0x0F, 0x03, 0x0E, 78262306a36Sopenharmony_ci }, 78362306a36Sopenharmony_ci { /* Init_SR10_SR24 */ 78462306a36Sopenharmony_ci 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, 78562306a36Sopenharmony_ci 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 78662306a36Sopenharmony_ci 0xC4, 0x32, 0x02, 0x01, 0x01, 78762306a36Sopenharmony_ci }, 78862306a36Sopenharmony_ci { /* Init_SR30_SR75 */ 78962306a36Sopenharmony_ci 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, 79062306a36Sopenharmony_ci 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, 79162306a36Sopenharmony_ci 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, 79262306a36Sopenharmony_ci 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, 79362306a36Sopenharmony_ci 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, 79462306a36Sopenharmony_ci 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, 79562306a36Sopenharmony_ci 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, 79662306a36Sopenharmony_ci 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, 79762306a36Sopenharmony_ci 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, 79862306a36Sopenharmony_ci }, 79962306a36Sopenharmony_ci { /* Init_SR80_SR93 */ 80062306a36Sopenharmony_ci 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, 80162306a36Sopenharmony_ci 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, 80262306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 80362306a36Sopenharmony_ci }, 80462306a36Sopenharmony_ci { /* Init_SRA0_SRAF */ 80562306a36Sopenharmony_ci 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, 80662306a36Sopenharmony_ci 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, 80762306a36Sopenharmony_ci }, 80862306a36Sopenharmony_ci { /* Init_GR00_GR08 */ 80962306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 81062306a36Sopenharmony_ci 0xFF, 81162306a36Sopenharmony_ci }, 81262306a36Sopenharmony_ci { /* Init_AR00_AR14 */ 81362306a36Sopenharmony_ci 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 81462306a36Sopenharmony_ci 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 81562306a36Sopenharmony_ci 0x41, 0x00, 0x0F, 0x00, 0x00, 81662306a36Sopenharmony_ci }, 81762306a36Sopenharmony_ci { /* Init_CR00_CR18 */ 81862306a36Sopenharmony_ci 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, 81962306a36Sopenharmony_ci 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82062306a36Sopenharmony_ci 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, 82162306a36Sopenharmony_ci 0xFF, 82262306a36Sopenharmony_ci }, 82362306a36Sopenharmony_ci { /* Init_CR30_CR4D */ 82462306a36Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, 82562306a36Sopenharmony_ci 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, 82662306a36Sopenharmony_ci 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, 82762306a36Sopenharmony_ci 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, 82862306a36Sopenharmony_ci }, 82962306a36Sopenharmony_ci { /* Init_CR90_CRA7 */ 83062306a36Sopenharmony_ci 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, 83162306a36Sopenharmony_ci 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, 83262306a36Sopenharmony_ci 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, 83362306a36Sopenharmony_ci }, 83462306a36Sopenharmony_ci }, 83562306a36Sopenharmony_ci}; 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_cistatic struct smtcfb_screen_info smtc_scr_info; 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_cistatic char *mode_option; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci/* process command line options, get vga parameter */ 84262306a36Sopenharmony_cistatic void __init sm7xx_vga_setup(char *options) 84362306a36Sopenharmony_ci{ 84462306a36Sopenharmony_ci int i; 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci if (!options || !*options) 84762306a36Sopenharmony_ci return; 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci smtc_scr_info.lfb_width = 0; 85062306a36Sopenharmony_ci smtc_scr_info.lfb_height = 0; 85162306a36Sopenharmony_ci smtc_scr_info.lfb_depth = 0; 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci pr_debug("%s = %s\n", __func__, options); 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(vesa_mode_table); i++) { 85662306a36Sopenharmony_ci if (strstr(options, vesa_mode_table[i].index)) { 85762306a36Sopenharmony_ci smtc_scr_info.lfb_width = vesa_mode_table[i].lfb_width; 85862306a36Sopenharmony_ci smtc_scr_info.lfb_height = 85962306a36Sopenharmony_ci vesa_mode_table[i].lfb_height; 86062306a36Sopenharmony_ci smtc_scr_info.lfb_depth = vesa_mode_table[i].lfb_depth; 86162306a36Sopenharmony_ci return; 86262306a36Sopenharmony_ci } 86362306a36Sopenharmony_ci } 86462306a36Sopenharmony_ci} 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_cistatic void sm712_setpalette(int regno, unsigned int red, unsigned int green, 86762306a36Sopenharmony_ci unsigned int blue, struct fb_info *info) 86862306a36Sopenharmony_ci{ 86962306a36Sopenharmony_ci /* set bit 5:4 = 01 (write LCD RAM only) */ 87062306a36Sopenharmony_ci smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10); 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci smtc_mmiowb(regno, dac_reg); 87362306a36Sopenharmony_ci smtc_mmiowb(red >> 10, dac_val); 87462306a36Sopenharmony_ci smtc_mmiowb(green >> 10, dac_val); 87562306a36Sopenharmony_ci smtc_mmiowb(blue >> 10, dac_val); 87662306a36Sopenharmony_ci} 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci/* chan_to_field 87962306a36Sopenharmony_ci * 88062306a36Sopenharmony_ci * convert a colour value into a field position 88162306a36Sopenharmony_ci * 88262306a36Sopenharmony_ci * from pxafb.c 88362306a36Sopenharmony_ci */ 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_cistatic inline unsigned int chan_to_field(unsigned int chan, 88662306a36Sopenharmony_ci struct fb_bitfield *bf) 88762306a36Sopenharmony_ci{ 88862306a36Sopenharmony_ci chan &= 0xffff; 88962306a36Sopenharmony_ci chan >>= 16 - bf->length; 89062306a36Sopenharmony_ci return chan << bf->offset; 89162306a36Sopenharmony_ci} 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_cistatic int smtc_blank(int blank_mode, struct fb_info *info) 89462306a36Sopenharmony_ci{ 89562306a36Sopenharmony_ci struct smtcfb_info *sfb = info->par; 89662306a36Sopenharmony_ci 89762306a36Sopenharmony_ci /* clear DPMS setting */ 89862306a36Sopenharmony_ci switch (blank_mode) { 89962306a36Sopenharmony_ci case FB_BLANK_UNBLANK: 90062306a36Sopenharmony_ci /* Screen On: HSync: On, VSync : On */ 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci switch (sfb->chip_id) { 90362306a36Sopenharmony_ci case 0x710: 90462306a36Sopenharmony_ci case 0x712: 90562306a36Sopenharmony_ci smtc_seqw(0x6a, 0x16); 90662306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 90762306a36Sopenharmony_ci break; 90862306a36Sopenharmony_ci case 0x720: 90962306a36Sopenharmony_ci smtc_seqw(0x6a, 0x0d); 91062306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 91162306a36Sopenharmony_ci break; 91262306a36Sopenharmony_ci } 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); 91562306a36Sopenharmony_ci smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); 91662306a36Sopenharmony_ci smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77)); 91762306a36Sopenharmony_ci smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); 91862306a36Sopenharmony_ci smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03)); 91962306a36Sopenharmony_ci smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); 92062306a36Sopenharmony_ci break; 92162306a36Sopenharmony_ci case FB_BLANK_NORMAL: 92262306a36Sopenharmony_ci /* Screen Off: HSync: On, VSync : On Soft blank */ 92362306a36Sopenharmony_ci smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); 92462306a36Sopenharmony_ci smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); 92562306a36Sopenharmony_ci smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); 92662306a36Sopenharmony_ci smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); 92762306a36Sopenharmony_ci smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); 92862306a36Sopenharmony_ci smtc_seqw(0x6a, 0x16); 92962306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 93062306a36Sopenharmony_ci break; 93162306a36Sopenharmony_ci case FB_BLANK_VSYNC_SUSPEND: 93262306a36Sopenharmony_ci /* Screen On: HSync: On, VSync : Off */ 93362306a36Sopenharmony_ci smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); 93462306a36Sopenharmony_ci smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); 93562306a36Sopenharmony_ci smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20)); 93662306a36Sopenharmony_ci smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); 93762306a36Sopenharmony_ci smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); 93862306a36Sopenharmony_ci smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); 93962306a36Sopenharmony_ci smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20)); 94062306a36Sopenharmony_ci smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); 94162306a36Sopenharmony_ci smtc_seqw(0x6a, 0x0c); 94262306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 94362306a36Sopenharmony_ci break; 94462306a36Sopenharmony_ci case FB_BLANK_HSYNC_SUSPEND: 94562306a36Sopenharmony_ci /* Screen On: HSync: Off, VSync : On */ 94662306a36Sopenharmony_ci smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); 94762306a36Sopenharmony_ci smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); 94862306a36Sopenharmony_ci smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); 94962306a36Sopenharmony_ci smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); 95062306a36Sopenharmony_ci smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); 95162306a36Sopenharmony_ci smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); 95262306a36Sopenharmony_ci smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10)); 95362306a36Sopenharmony_ci smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); 95462306a36Sopenharmony_ci smtc_seqw(0x6a, 0x0c); 95562306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 95662306a36Sopenharmony_ci break; 95762306a36Sopenharmony_ci case FB_BLANK_POWERDOWN: 95862306a36Sopenharmony_ci /* Screen On: HSync: Off, VSync : Off */ 95962306a36Sopenharmony_ci smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); 96062306a36Sopenharmony_ci smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); 96162306a36Sopenharmony_ci smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); 96262306a36Sopenharmony_ci smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); 96362306a36Sopenharmony_ci smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); 96462306a36Sopenharmony_ci smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); 96562306a36Sopenharmony_ci smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30)); 96662306a36Sopenharmony_ci smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); 96762306a36Sopenharmony_ci smtc_seqw(0x6a, 0x0c); 96862306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 96962306a36Sopenharmony_ci break; 97062306a36Sopenharmony_ci default: 97162306a36Sopenharmony_ci return -EINVAL; 97262306a36Sopenharmony_ci } 97362306a36Sopenharmony_ci 97462306a36Sopenharmony_ci return 0; 97562306a36Sopenharmony_ci} 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_cistatic int smtc_setcolreg(unsigned int regno, unsigned int red, 97862306a36Sopenharmony_ci unsigned int green, unsigned int blue, 97962306a36Sopenharmony_ci unsigned int trans, struct fb_info *info) 98062306a36Sopenharmony_ci{ 98162306a36Sopenharmony_ci struct smtcfb_info *sfb; 98262306a36Sopenharmony_ci u32 val; 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ci sfb = info->par; 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci if (regno > 255) 98762306a36Sopenharmony_ci return 1; 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci switch (sfb->fb->fix.visual) { 99062306a36Sopenharmony_ci case FB_VISUAL_DIRECTCOLOR: 99162306a36Sopenharmony_ci case FB_VISUAL_TRUECOLOR: 99262306a36Sopenharmony_ci /* 99362306a36Sopenharmony_ci * 16/32 bit true-colour, use pseudo-palette for 16 base color 99462306a36Sopenharmony_ci */ 99562306a36Sopenharmony_ci if (regno >= 16) 99662306a36Sopenharmony_ci break; 99762306a36Sopenharmony_ci if (sfb->fb->var.bits_per_pixel == 16) { 99862306a36Sopenharmony_ci u32 *pal = sfb->fb->pseudo_palette; 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci val = chan_to_field(red, &sfb->fb->var.red); 100162306a36Sopenharmony_ci val |= chan_to_field(green, &sfb->fb->var.green); 100262306a36Sopenharmony_ci val |= chan_to_field(blue, &sfb->fb->var.blue); 100362306a36Sopenharmony_ci pal[regno] = pal_rgb(red, green, blue, val); 100462306a36Sopenharmony_ci } else { 100562306a36Sopenharmony_ci u32 *pal = sfb->fb->pseudo_palette; 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_ci val = chan_to_field(red, &sfb->fb->var.red); 100862306a36Sopenharmony_ci val |= chan_to_field(green, &sfb->fb->var.green); 100962306a36Sopenharmony_ci val |= chan_to_field(blue, &sfb->fb->var.blue); 101062306a36Sopenharmony_ci pal[regno] = big_swap(val); 101162306a36Sopenharmony_ci } 101262306a36Sopenharmony_ci break; 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci case FB_VISUAL_PSEUDOCOLOR: 101562306a36Sopenharmony_ci /* color depth 8 bit */ 101662306a36Sopenharmony_ci sm712_setpalette(regno, red, green, blue, info); 101762306a36Sopenharmony_ci break; 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci default: 102062306a36Sopenharmony_ci return 1; /* unknown type */ 102162306a36Sopenharmony_ci } 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci return 0; 102462306a36Sopenharmony_ci} 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_cistatic ssize_t smtcfb_read(struct fb_info *info, char __user *buf, 102762306a36Sopenharmony_ci size_t count, loff_t *ppos) 102862306a36Sopenharmony_ci{ 102962306a36Sopenharmony_ci unsigned long p = *ppos; 103062306a36Sopenharmony_ci 103162306a36Sopenharmony_ci u32 *buffer, *dst; 103262306a36Sopenharmony_ci u32 __iomem *src; 103362306a36Sopenharmony_ci int c, i, cnt = 0, err = 0; 103462306a36Sopenharmony_ci unsigned long total_size; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci if (!info->screen_base) 103762306a36Sopenharmony_ci return -ENODEV; 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_ci total_size = info->screen_size; 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci if (total_size == 0) 104262306a36Sopenharmony_ci total_size = info->fix.smem_len; 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ci if (p >= total_size) 104562306a36Sopenharmony_ci return 0; 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci if (count >= total_size) 104862306a36Sopenharmony_ci count = total_size; 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_ci if (count + p > total_size) 105162306a36Sopenharmony_ci count = total_size - p; 105262306a36Sopenharmony_ci 105362306a36Sopenharmony_ci buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); 105462306a36Sopenharmony_ci if (!buffer) 105562306a36Sopenharmony_ci return -ENOMEM; 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_ci src = (u32 __iomem *)(info->screen_base + p); 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci if (info->fbops->fb_sync) 106062306a36Sopenharmony_ci info->fbops->fb_sync(info); 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ci while (count) { 106362306a36Sopenharmony_ci c = (count > PAGE_SIZE) ? PAGE_SIZE : count; 106462306a36Sopenharmony_ci dst = buffer; 106562306a36Sopenharmony_ci for (i = (c + 3) >> 2; i--;) { 106662306a36Sopenharmony_ci u32 val; 106762306a36Sopenharmony_ci 106862306a36Sopenharmony_ci val = fb_readl(src); 106962306a36Sopenharmony_ci *dst = big_swap(val); 107062306a36Sopenharmony_ci src++; 107162306a36Sopenharmony_ci dst++; 107262306a36Sopenharmony_ci } 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_ci if (copy_to_user(buf, buffer, c)) { 107562306a36Sopenharmony_ci err = -EFAULT; 107662306a36Sopenharmony_ci break; 107762306a36Sopenharmony_ci } 107862306a36Sopenharmony_ci *ppos += c; 107962306a36Sopenharmony_ci buf += c; 108062306a36Sopenharmony_ci cnt += c; 108162306a36Sopenharmony_ci count -= c; 108262306a36Sopenharmony_ci } 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci kfree(buffer); 108562306a36Sopenharmony_ci 108662306a36Sopenharmony_ci return (err) ? err : cnt; 108762306a36Sopenharmony_ci} 108862306a36Sopenharmony_ci 108962306a36Sopenharmony_cistatic ssize_t smtcfb_write(struct fb_info *info, const char __user *buf, 109062306a36Sopenharmony_ci size_t count, loff_t *ppos) 109162306a36Sopenharmony_ci{ 109262306a36Sopenharmony_ci unsigned long p = *ppos; 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_ci u32 *buffer, *src; 109562306a36Sopenharmony_ci u32 __iomem *dst; 109662306a36Sopenharmony_ci int c, i, cnt = 0, err = 0; 109762306a36Sopenharmony_ci unsigned long total_size; 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci if (!info->screen_base) 110062306a36Sopenharmony_ci return -ENODEV; 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci total_size = info->screen_size; 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ci if (total_size == 0) 110562306a36Sopenharmony_ci total_size = info->fix.smem_len; 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_ci if (p > total_size) 110862306a36Sopenharmony_ci return -EFBIG; 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_ci if (count > total_size) { 111162306a36Sopenharmony_ci err = -EFBIG; 111262306a36Sopenharmony_ci count = total_size; 111362306a36Sopenharmony_ci } 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci if (count + p > total_size) { 111662306a36Sopenharmony_ci if (!err) 111762306a36Sopenharmony_ci err = -ENOSPC; 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_ci count = total_size - p; 112062306a36Sopenharmony_ci } 112162306a36Sopenharmony_ci 112262306a36Sopenharmony_ci buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); 112362306a36Sopenharmony_ci if (!buffer) 112462306a36Sopenharmony_ci return -ENOMEM; 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ci dst = (u32 __iomem *)(info->screen_base + p); 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci if (info->fbops->fb_sync) 112962306a36Sopenharmony_ci info->fbops->fb_sync(info); 113062306a36Sopenharmony_ci 113162306a36Sopenharmony_ci while (count) { 113262306a36Sopenharmony_ci c = (count > PAGE_SIZE) ? PAGE_SIZE : count; 113362306a36Sopenharmony_ci src = buffer; 113462306a36Sopenharmony_ci 113562306a36Sopenharmony_ci if (copy_from_user(src, buf, c)) { 113662306a36Sopenharmony_ci err = -EFAULT; 113762306a36Sopenharmony_ci break; 113862306a36Sopenharmony_ci } 113962306a36Sopenharmony_ci 114062306a36Sopenharmony_ci for (i = (c + 3) >> 2; i--;) { 114162306a36Sopenharmony_ci fb_writel(big_swap(*src), dst); 114262306a36Sopenharmony_ci dst++; 114362306a36Sopenharmony_ci src++; 114462306a36Sopenharmony_ci } 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci *ppos += c; 114762306a36Sopenharmony_ci buf += c; 114862306a36Sopenharmony_ci cnt += c; 114962306a36Sopenharmony_ci count -= c; 115062306a36Sopenharmony_ci } 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci kfree(buffer); 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci return (cnt) ? cnt : err; 115562306a36Sopenharmony_ci} 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_cistatic void sm7xx_set_timing(struct smtcfb_info *sfb) 115862306a36Sopenharmony_ci{ 115962306a36Sopenharmony_ci int i = 0, j = 0; 116062306a36Sopenharmony_ci u32 m_nscreenstride; 116162306a36Sopenharmony_ci 116262306a36Sopenharmony_ci dev_dbg(&sfb->pdev->dev, 116362306a36Sopenharmony_ci "sfb->width=%d sfb->height=%d sfb->fb->var.bits_per_pixel=%d sfb->hz=%d\n", 116462306a36Sopenharmony_ci sfb->width, sfb->height, sfb->fb->var.bits_per_pixel, sfb->hz); 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci for (j = 0; j < ARRAY_SIZE(vgamode); j++) { 116762306a36Sopenharmony_ci if (vgamode[j].mmsizex != sfb->width || 116862306a36Sopenharmony_ci vgamode[j].mmsizey != sfb->height || 116962306a36Sopenharmony_ci vgamode[j].bpp != sfb->fb->var.bits_per_pixel || 117062306a36Sopenharmony_ci vgamode[j].hz != sfb->hz) 117162306a36Sopenharmony_ci continue; 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_ci dev_dbg(&sfb->pdev->dev, 117462306a36Sopenharmony_ci "vgamode[j].mmsizex=%d vgamode[j].mmSizeY=%d vgamode[j].bpp=%d vgamode[j].hz=%d\n", 117562306a36Sopenharmony_ci vgamode[j].mmsizex, vgamode[j].mmsizey, 117662306a36Sopenharmony_ci vgamode[j].bpp, vgamode[j].hz); 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_ci dev_dbg(&sfb->pdev->dev, "vgamode index=%d\n", j); 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci smtc_mmiowb(0x0, 0x3c6); 118162306a36Sopenharmony_ci 118262306a36Sopenharmony_ci smtc_seqw(0, 0x1); 118362306a36Sopenharmony_ci 118462306a36Sopenharmony_ci smtc_mmiowb(vgamode[j].init_misc, 0x3c2); 118562306a36Sopenharmony_ci 118662306a36Sopenharmony_ci /* init SEQ register SR00 - SR04 */ 118762306a36Sopenharmony_ci for (i = 0; i < SIZE_SR00_SR04; i++) 118862306a36Sopenharmony_ci smtc_seqw(i, vgamode[j].init_sr00_sr04[i]); 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_ci /* init SEQ register SR10 - SR24 */ 119162306a36Sopenharmony_ci for (i = 0; i < SIZE_SR10_SR24; i++) 119262306a36Sopenharmony_ci smtc_seqw(i + 0x10, vgamode[j].init_sr10_sr24[i]); 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_ci /* init SEQ register SR30 - SR75 */ 119562306a36Sopenharmony_ci for (i = 0; i < SIZE_SR30_SR75; i++) 119662306a36Sopenharmony_ci if ((i + 0x30) != 0x30 && (i + 0x30) != 0x62 && 119762306a36Sopenharmony_ci (i + 0x30) != 0x6a && (i + 0x30) != 0x6b && 119862306a36Sopenharmony_ci (i + 0x30) != 0x70 && (i + 0x30) != 0x71 && 119962306a36Sopenharmony_ci (i + 0x30) != 0x74 && (i + 0x30) != 0x75) 120062306a36Sopenharmony_ci smtc_seqw(i + 0x30, 120162306a36Sopenharmony_ci vgamode[j].init_sr30_sr75[i]); 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_ci /* init SEQ register SR80 - SR93 */ 120462306a36Sopenharmony_ci for (i = 0; i < SIZE_SR80_SR93; i++) 120562306a36Sopenharmony_ci smtc_seqw(i + 0x80, vgamode[j].init_sr80_sr93[i]); 120662306a36Sopenharmony_ci 120762306a36Sopenharmony_ci /* init SEQ register SRA0 - SRAF */ 120862306a36Sopenharmony_ci for (i = 0; i < SIZE_SRA0_SRAF; i++) 120962306a36Sopenharmony_ci smtc_seqw(i + 0xa0, vgamode[j].init_sra0_sraf[i]); 121062306a36Sopenharmony_ci 121162306a36Sopenharmony_ci /* init Graphic register GR00 - GR08 */ 121262306a36Sopenharmony_ci for (i = 0; i < SIZE_GR00_GR08; i++) 121362306a36Sopenharmony_ci smtc_grphw(i, vgamode[j].init_gr00_gr08[i]); 121462306a36Sopenharmony_ci 121562306a36Sopenharmony_ci /* init Attribute register AR00 - AR14 */ 121662306a36Sopenharmony_ci for (i = 0; i < SIZE_AR00_AR14; i++) 121762306a36Sopenharmony_ci smtc_attrw(i, vgamode[j].init_ar00_ar14[i]); 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci /* init CRTC register CR00 - CR18 */ 122062306a36Sopenharmony_ci for (i = 0; i < SIZE_CR00_CR18; i++) 122162306a36Sopenharmony_ci smtc_crtcw(i, vgamode[j].init_cr00_cr18[i]); 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci /* init CRTC register CR30 - CR4D */ 122462306a36Sopenharmony_ci for (i = 0; i < SIZE_CR30_CR4D; i++) { 122562306a36Sopenharmony_ci if ((i + 0x30) >= 0x3B && (i + 0x30) <= 0x3F) 122662306a36Sopenharmony_ci /* side-effect, don't write to CR3B-CR3F */ 122762306a36Sopenharmony_ci continue; 122862306a36Sopenharmony_ci smtc_crtcw(i + 0x30, vgamode[j].init_cr30_cr4d[i]); 122962306a36Sopenharmony_ci } 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci /* init CRTC register CR90 - CRA7 */ 123262306a36Sopenharmony_ci for (i = 0; i < SIZE_CR90_CRA7; i++) 123362306a36Sopenharmony_ci smtc_crtcw(i + 0x90, vgamode[j].init_cr90_cra7[i]); 123462306a36Sopenharmony_ci } 123562306a36Sopenharmony_ci smtc_mmiowb(0x67, 0x3c2); 123662306a36Sopenharmony_ci 123762306a36Sopenharmony_ci /* set VPR registers */ 123862306a36Sopenharmony_ci writel(0x0, sfb->vp_regs + 0x0C); 123962306a36Sopenharmony_ci writel(0x0, sfb->vp_regs + 0x40); 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_ci /* set data width */ 124262306a36Sopenharmony_ci m_nscreenstride = (sfb->width * sfb->fb->var.bits_per_pixel) / 64; 124362306a36Sopenharmony_ci switch (sfb->fb->var.bits_per_pixel) { 124462306a36Sopenharmony_ci case 8: 124562306a36Sopenharmony_ci writel(0x0, sfb->vp_regs + 0x0); 124662306a36Sopenharmony_ci break; 124762306a36Sopenharmony_ci case 16: 124862306a36Sopenharmony_ci writel(0x00020000, sfb->vp_regs + 0x0); 124962306a36Sopenharmony_ci break; 125062306a36Sopenharmony_ci case 24: 125162306a36Sopenharmony_ci writel(0x00040000, sfb->vp_regs + 0x0); 125262306a36Sopenharmony_ci break; 125362306a36Sopenharmony_ci case 32: 125462306a36Sopenharmony_ci writel(0x00030000, sfb->vp_regs + 0x0); 125562306a36Sopenharmony_ci break; 125662306a36Sopenharmony_ci } 125762306a36Sopenharmony_ci writel((u32)(((m_nscreenstride + 2) << 16) | m_nscreenstride), 125862306a36Sopenharmony_ci sfb->vp_regs + 0x10); 125962306a36Sopenharmony_ci} 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_cistatic void smtc_set_timing(struct smtcfb_info *sfb) 126262306a36Sopenharmony_ci{ 126362306a36Sopenharmony_ci switch (sfb->chip_id) { 126462306a36Sopenharmony_ci case 0x710: 126562306a36Sopenharmony_ci case 0x712: 126662306a36Sopenharmony_ci case 0x720: 126762306a36Sopenharmony_ci sm7xx_set_timing(sfb); 126862306a36Sopenharmony_ci break; 126962306a36Sopenharmony_ci } 127062306a36Sopenharmony_ci} 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_cistatic void smtcfb_setmode(struct smtcfb_info *sfb) 127362306a36Sopenharmony_ci{ 127462306a36Sopenharmony_ci switch (sfb->fb->var.bits_per_pixel) { 127562306a36Sopenharmony_ci case 32: 127662306a36Sopenharmony_ci sfb->fb->fix.visual = FB_VISUAL_TRUECOLOR; 127762306a36Sopenharmony_ci sfb->fb->fix.line_length = sfb->fb->var.xres * 4; 127862306a36Sopenharmony_ci sfb->fb->var.red.length = 8; 127962306a36Sopenharmony_ci sfb->fb->var.green.length = 8; 128062306a36Sopenharmony_ci sfb->fb->var.blue.length = 8; 128162306a36Sopenharmony_ci sfb->fb->var.red.offset = 16; 128262306a36Sopenharmony_ci sfb->fb->var.green.offset = 8; 128362306a36Sopenharmony_ci sfb->fb->var.blue.offset = 0; 128462306a36Sopenharmony_ci break; 128562306a36Sopenharmony_ci case 24: 128662306a36Sopenharmony_ci sfb->fb->fix.visual = FB_VISUAL_TRUECOLOR; 128762306a36Sopenharmony_ci sfb->fb->fix.line_length = sfb->fb->var.xres * 3; 128862306a36Sopenharmony_ci sfb->fb->var.red.length = 8; 128962306a36Sopenharmony_ci sfb->fb->var.green.length = 8; 129062306a36Sopenharmony_ci sfb->fb->var.blue.length = 8; 129162306a36Sopenharmony_ci sfb->fb->var.red.offset = 16; 129262306a36Sopenharmony_ci sfb->fb->var.green.offset = 8; 129362306a36Sopenharmony_ci sfb->fb->var.blue.offset = 0; 129462306a36Sopenharmony_ci break; 129562306a36Sopenharmony_ci case 8: 129662306a36Sopenharmony_ci sfb->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR; 129762306a36Sopenharmony_ci sfb->fb->fix.line_length = sfb->fb->var.xres; 129862306a36Sopenharmony_ci sfb->fb->var.red.length = 3; 129962306a36Sopenharmony_ci sfb->fb->var.green.length = 3; 130062306a36Sopenharmony_ci sfb->fb->var.blue.length = 2; 130162306a36Sopenharmony_ci sfb->fb->var.red.offset = 5; 130262306a36Sopenharmony_ci sfb->fb->var.green.offset = 2; 130362306a36Sopenharmony_ci sfb->fb->var.blue.offset = 0; 130462306a36Sopenharmony_ci break; 130562306a36Sopenharmony_ci case 16: 130662306a36Sopenharmony_ci default: 130762306a36Sopenharmony_ci sfb->fb->fix.visual = FB_VISUAL_TRUECOLOR; 130862306a36Sopenharmony_ci sfb->fb->fix.line_length = sfb->fb->var.xres * 2; 130962306a36Sopenharmony_ci sfb->fb->var.red.length = 5; 131062306a36Sopenharmony_ci sfb->fb->var.green.length = 6; 131162306a36Sopenharmony_ci sfb->fb->var.blue.length = 5; 131262306a36Sopenharmony_ci sfb->fb->var.red.offset = 11; 131362306a36Sopenharmony_ci sfb->fb->var.green.offset = 5; 131462306a36Sopenharmony_ci sfb->fb->var.blue.offset = 0; 131562306a36Sopenharmony_ci break; 131662306a36Sopenharmony_ci } 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_ci sfb->width = sfb->fb->var.xres; 131962306a36Sopenharmony_ci sfb->height = sfb->fb->var.yres; 132062306a36Sopenharmony_ci sfb->hz = 60; 132162306a36Sopenharmony_ci smtc_set_timing(sfb); 132262306a36Sopenharmony_ci} 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_cistatic int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 132562306a36Sopenharmony_ci{ 132662306a36Sopenharmony_ci /* sanity checks */ 132762306a36Sopenharmony_ci if (var->xres_virtual < var->xres) 132862306a36Sopenharmony_ci var->xres_virtual = var->xres; 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci if (var->yres_virtual < var->yres) 133162306a36Sopenharmony_ci var->yres_virtual = var->yres; 133262306a36Sopenharmony_ci 133362306a36Sopenharmony_ci /* set valid default bpp */ 133462306a36Sopenharmony_ci if ((var->bits_per_pixel != 8) && (var->bits_per_pixel != 16) && 133562306a36Sopenharmony_ci (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32)) 133662306a36Sopenharmony_ci var->bits_per_pixel = 16; 133762306a36Sopenharmony_ci 133862306a36Sopenharmony_ci return 0; 133962306a36Sopenharmony_ci} 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_cistatic int smtc_set_par(struct fb_info *info) 134262306a36Sopenharmony_ci{ 134362306a36Sopenharmony_ci smtcfb_setmode(info->par); 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_ci return 0; 134662306a36Sopenharmony_ci} 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_cistatic const struct fb_ops smtcfb_ops = { 134962306a36Sopenharmony_ci .owner = THIS_MODULE, 135062306a36Sopenharmony_ci .fb_check_var = smtc_check_var, 135162306a36Sopenharmony_ci .fb_set_par = smtc_set_par, 135262306a36Sopenharmony_ci .fb_setcolreg = smtc_setcolreg, 135362306a36Sopenharmony_ci .fb_blank = smtc_blank, 135462306a36Sopenharmony_ci .fb_fillrect = cfb_fillrect, 135562306a36Sopenharmony_ci .fb_imageblit = cfb_imageblit, 135662306a36Sopenharmony_ci .fb_copyarea = cfb_copyarea, 135762306a36Sopenharmony_ci .fb_read = smtcfb_read, 135862306a36Sopenharmony_ci .fb_write = smtcfb_write, 135962306a36Sopenharmony_ci}; 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci/* 136262306a36Sopenharmony_ci * Unmap in the memory mapped IO registers 136362306a36Sopenharmony_ci */ 136462306a36Sopenharmony_ci 136562306a36Sopenharmony_cistatic void smtc_unmap_mmio(struct smtcfb_info *sfb) 136662306a36Sopenharmony_ci{ 136762306a36Sopenharmony_ci if (sfb && smtc_regbaseaddress) 136862306a36Sopenharmony_ci smtc_regbaseaddress = NULL; 136962306a36Sopenharmony_ci} 137062306a36Sopenharmony_ci 137162306a36Sopenharmony_ci/* 137262306a36Sopenharmony_ci * Map in the screen memory 137362306a36Sopenharmony_ci */ 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_cistatic int smtc_map_smem(struct smtcfb_info *sfb, 137662306a36Sopenharmony_ci struct pci_dev *pdev, u_long smem_len) 137762306a36Sopenharmony_ci{ 137862306a36Sopenharmony_ci sfb->fb->fix.smem_start = pci_resource_start(pdev, 0); 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_ci if (sfb->chip_id == 0x720) 138162306a36Sopenharmony_ci /* on SM720, the framebuffer starts at the 1 MB offset */ 138262306a36Sopenharmony_ci sfb->fb->fix.smem_start += 0x00200000; 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci /* XXX: is it safe for SM720 on Big-Endian? */ 138562306a36Sopenharmony_ci if (sfb->fb->var.bits_per_pixel == 32) 138662306a36Sopenharmony_ci sfb->fb->fix.smem_start += big_addr; 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci sfb->fb->fix.smem_len = smem_len; 138962306a36Sopenharmony_ci 139062306a36Sopenharmony_ci sfb->fb->screen_base = sfb->lfb; 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci if (!sfb->fb->screen_base) { 139362306a36Sopenharmony_ci dev_err(&pdev->dev, 139462306a36Sopenharmony_ci "%s: unable to map screen memory\n", sfb->fb->fix.id); 139562306a36Sopenharmony_ci return -ENOMEM; 139662306a36Sopenharmony_ci } 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci return 0; 139962306a36Sopenharmony_ci} 140062306a36Sopenharmony_ci 140162306a36Sopenharmony_ci/* 140262306a36Sopenharmony_ci * Unmap in the screen memory 140362306a36Sopenharmony_ci * 140462306a36Sopenharmony_ci */ 140562306a36Sopenharmony_cistatic void smtc_unmap_smem(struct smtcfb_info *sfb) 140662306a36Sopenharmony_ci{ 140762306a36Sopenharmony_ci if (sfb && sfb->fb->screen_base) { 140862306a36Sopenharmony_ci if (sfb->chip_id == 0x720) 140962306a36Sopenharmony_ci sfb->fb->screen_base -= 0x00200000; 141062306a36Sopenharmony_ci iounmap(sfb->fb->screen_base); 141162306a36Sopenharmony_ci sfb->fb->screen_base = NULL; 141262306a36Sopenharmony_ci } 141362306a36Sopenharmony_ci} 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_ci/* 141662306a36Sopenharmony_ci * We need to wake up the device and make sure its in linear memory mode. 141762306a36Sopenharmony_ci */ 141862306a36Sopenharmony_cistatic inline void sm7xx_init_hw(void) 141962306a36Sopenharmony_ci{ 142062306a36Sopenharmony_ci outb_p(0x18, 0x3c4); 142162306a36Sopenharmony_ci outb_p(0x11, 0x3c5); 142262306a36Sopenharmony_ci} 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_cistatic u_long sm7xx_vram_probe(struct smtcfb_info *sfb) 142562306a36Sopenharmony_ci{ 142662306a36Sopenharmony_ci u8 vram; 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci switch (sfb->chip_id) { 142962306a36Sopenharmony_ci case 0x710: 143062306a36Sopenharmony_ci case 0x712: 143162306a36Sopenharmony_ci /* 143262306a36Sopenharmony_ci * Assume SM712 graphics chip has 4MB VRAM. 143362306a36Sopenharmony_ci * 143462306a36Sopenharmony_ci * FIXME: SM712 can have 2MB VRAM, which is used on earlier 143562306a36Sopenharmony_ci * laptops, such as IBM Thinkpad 240X. This driver would 143662306a36Sopenharmony_ci * probably crash on those machines. If anyone gets one of 143762306a36Sopenharmony_ci * those and is willing to help, run "git blame" and send me 143862306a36Sopenharmony_ci * an E-mail. 143962306a36Sopenharmony_ci */ 144062306a36Sopenharmony_ci return 0x00400000; 144162306a36Sopenharmony_ci case 0x720: 144262306a36Sopenharmony_ci outb_p(0x76, 0x3c4); 144362306a36Sopenharmony_ci vram = inb_p(0x3c5) >> 6; 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ci if (vram == 0x00) 144662306a36Sopenharmony_ci return 0x00800000; /* 8 MB */ 144762306a36Sopenharmony_ci else if (vram == 0x01) 144862306a36Sopenharmony_ci return 0x01000000; /* 16 MB */ 144962306a36Sopenharmony_ci else if (vram == 0x02) 145062306a36Sopenharmony_ci return 0x00400000; /* illegal, fallback to 4 MB */ 145162306a36Sopenharmony_ci else if (vram == 0x03) 145262306a36Sopenharmony_ci return 0x00400000; /* 4 MB */ 145362306a36Sopenharmony_ci } 145462306a36Sopenharmony_ci return 0; /* unknown hardware */ 145562306a36Sopenharmony_ci} 145662306a36Sopenharmony_ci 145762306a36Sopenharmony_cistatic void sm7xx_resolution_probe(struct smtcfb_info *sfb) 145862306a36Sopenharmony_ci{ 145962306a36Sopenharmony_ci /* get mode parameter from smtc_scr_info */ 146062306a36Sopenharmony_ci if (smtc_scr_info.lfb_width != 0) { 146162306a36Sopenharmony_ci sfb->fb->var.xres = smtc_scr_info.lfb_width; 146262306a36Sopenharmony_ci sfb->fb->var.yres = smtc_scr_info.lfb_height; 146362306a36Sopenharmony_ci sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth; 146462306a36Sopenharmony_ci goto final; 146562306a36Sopenharmony_ci } 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_ci /* 146862306a36Sopenharmony_ci * No parameter, default resolution is 1024x768-16. 146962306a36Sopenharmony_ci * 147062306a36Sopenharmony_ci * FIXME: earlier laptops, such as IBM Thinkpad 240X, has a 800x600 147162306a36Sopenharmony_ci * panel, also see the comments about Thinkpad 240X above. 147262306a36Sopenharmony_ci */ 147362306a36Sopenharmony_ci sfb->fb->var.xres = SCREEN_X_RES; 147462306a36Sopenharmony_ci sfb->fb->var.yres = SCREEN_Y_RES_PC; 147562306a36Sopenharmony_ci sfb->fb->var.bits_per_pixel = SCREEN_BPP; 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_ci#ifdef CONFIG_MIPS 147862306a36Sopenharmony_ci /* 147962306a36Sopenharmony_ci * Loongson MIPS netbooks use 1024x600 LCD panels, which is the original 148062306a36Sopenharmony_ci * target platform of this driver, but nearly all old x86 laptops have 148162306a36Sopenharmony_ci * 1024x768. Lighting 768 panels using 600's timings would partially 148262306a36Sopenharmony_ci * garble the display, so we don't want that. But it's not possible to 148362306a36Sopenharmony_ci * distinguish them reliably. 148462306a36Sopenharmony_ci * 148562306a36Sopenharmony_ci * So we change the default to 768, but keep 600 as-is on MIPS. 148662306a36Sopenharmony_ci */ 148762306a36Sopenharmony_ci sfb->fb->var.yres = SCREEN_Y_RES_NETBOOK; 148862306a36Sopenharmony_ci#endif 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_cifinal: 149162306a36Sopenharmony_ci big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth); 149262306a36Sopenharmony_ci} 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_cistatic int smtcfb_pci_probe(struct pci_dev *pdev, 149562306a36Sopenharmony_ci const struct pci_device_id *ent) 149662306a36Sopenharmony_ci{ 149762306a36Sopenharmony_ci struct smtcfb_info *sfb; 149862306a36Sopenharmony_ci struct fb_info *info; 149962306a36Sopenharmony_ci u_long smem_size; 150062306a36Sopenharmony_ci int err; 150162306a36Sopenharmony_ci unsigned long mmio_base; 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_ci dev_info(&pdev->dev, "Silicon Motion display driver.\n"); 150462306a36Sopenharmony_ci 150562306a36Sopenharmony_ci err = aperture_remove_conflicting_pci_devices(pdev, "smtcfb"); 150662306a36Sopenharmony_ci if (err) 150762306a36Sopenharmony_ci return err; 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci err = pci_enable_device(pdev); /* enable SMTC chip */ 151062306a36Sopenharmony_ci if (err) 151162306a36Sopenharmony_ci return err; 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci err = pci_request_region(pdev, 0, "sm7xxfb"); 151462306a36Sopenharmony_ci if (err < 0) { 151562306a36Sopenharmony_ci dev_err(&pdev->dev, "cannot reserve framebuffer region\n"); 151662306a36Sopenharmony_ci goto failed_regions; 151762306a36Sopenharmony_ci } 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_ci sprintf(smtcfb_fix.id, "sm%Xfb", ent->device); 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_ci info = framebuffer_alloc(sizeof(*sfb), &pdev->dev); 152262306a36Sopenharmony_ci if (!info) { 152362306a36Sopenharmony_ci err = -ENOMEM; 152462306a36Sopenharmony_ci goto failed_free; 152562306a36Sopenharmony_ci } 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_ci sfb = info->par; 152862306a36Sopenharmony_ci sfb->fb = info; 152962306a36Sopenharmony_ci sfb->chip_id = ent->device; 153062306a36Sopenharmony_ci sfb->pdev = pdev; 153162306a36Sopenharmony_ci info->fbops = &smtcfb_ops; 153262306a36Sopenharmony_ci info->fix = smtcfb_fix; 153362306a36Sopenharmony_ci info->var = smtcfb_var; 153462306a36Sopenharmony_ci info->pseudo_palette = sfb->colreg; 153562306a36Sopenharmony_ci info->par = sfb; 153662306a36Sopenharmony_ci 153762306a36Sopenharmony_ci pci_set_drvdata(pdev, sfb); 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci sm7xx_init_hw(); 154062306a36Sopenharmony_ci 154162306a36Sopenharmony_ci /* Map address and memory detection */ 154262306a36Sopenharmony_ci mmio_base = pci_resource_start(pdev, 0); 154362306a36Sopenharmony_ci pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id); 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci smem_size = sm7xx_vram_probe(sfb); 154662306a36Sopenharmony_ci dev_info(&pdev->dev, "%lu MiB of VRAM detected.\n", 154762306a36Sopenharmony_ci smem_size / 1048576); 154862306a36Sopenharmony_ci 154962306a36Sopenharmony_ci switch (sfb->chip_id) { 155062306a36Sopenharmony_ci case 0x710: 155162306a36Sopenharmony_ci case 0x712: 155262306a36Sopenharmony_ci sfb->fb->fix.mmio_start = mmio_base + 0x00400000; 155362306a36Sopenharmony_ci sfb->fb->fix.mmio_len = 0x00400000; 155462306a36Sopenharmony_ci sfb->lfb = ioremap(mmio_base, mmio_addr); 155562306a36Sopenharmony_ci if (!sfb->lfb) { 155662306a36Sopenharmony_ci dev_err(&pdev->dev, 155762306a36Sopenharmony_ci "%s: unable to map memory mapped IO!\n", 155862306a36Sopenharmony_ci sfb->fb->fix.id); 155962306a36Sopenharmony_ci err = -ENOMEM; 156062306a36Sopenharmony_ci goto failed_fb; 156162306a36Sopenharmony_ci } 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_ci sfb->mmio = (smtc_regbaseaddress = 156462306a36Sopenharmony_ci sfb->lfb + 0x00700000); 156562306a36Sopenharmony_ci sfb->dp_regs = sfb->lfb + 0x00408000; 156662306a36Sopenharmony_ci sfb->vp_regs = sfb->lfb + 0x0040c000; 156762306a36Sopenharmony_ci if (sfb->fb->var.bits_per_pixel == 32) { 156862306a36Sopenharmony_ci sfb->lfb += big_addr; 156962306a36Sopenharmony_ci dev_info(&pdev->dev, "sfb->lfb=%p\n", sfb->lfb); 157062306a36Sopenharmony_ci } 157162306a36Sopenharmony_ci 157262306a36Sopenharmony_ci /* set MCLK = 14.31818 * (0x16 / 0x2) */ 157362306a36Sopenharmony_ci smtc_seqw(0x6a, 0x16); 157462306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 157562306a36Sopenharmony_ci smtc_seqw(0x62, 0x3e); 157662306a36Sopenharmony_ci /* enable PCI burst */ 157762306a36Sopenharmony_ci smtc_seqw(0x17, 0x20); 157862306a36Sopenharmony_ci /* enable word swap */ 157962306a36Sopenharmony_ci if (sfb->fb->var.bits_per_pixel == 32) 158062306a36Sopenharmony_ci seqw17(); 158162306a36Sopenharmony_ci break; 158262306a36Sopenharmony_ci case 0x720: 158362306a36Sopenharmony_ci sfb->fb->fix.mmio_start = mmio_base; 158462306a36Sopenharmony_ci sfb->fb->fix.mmio_len = 0x00200000; 158562306a36Sopenharmony_ci sfb->dp_regs = ioremap(mmio_base, 0x00200000 + smem_size); 158662306a36Sopenharmony_ci if (!sfb->dp_regs) { 158762306a36Sopenharmony_ci dev_err(&pdev->dev, 158862306a36Sopenharmony_ci "%s: unable to map memory mapped IO!\n", 158962306a36Sopenharmony_ci sfb->fb->fix.id); 159062306a36Sopenharmony_ci err = -ENOMEM; 159162306a36Sopenharmony_ci goto failed_fb; 159262306a36Sopenharmony_ci } 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci sfb->lfb = sfb->dp_regs + 0x00200000; 159562306a36Sopenharmony_ci sfb->mmio = (smtc_regbaseaddress = 159662306a36Sopenharmony_ci sfb->dp_regs + 0x000c0000); 159762306a36Sopenharmony_ci sfb->vp_regs = sfb->dp_regs + 0x800; 159862306a36Sopenharmony_ci 159962306a36Sopenharmony_ci smtc_seqw(0x62, 0xff); 160062306a36Sopenharmony_ci smtc_seqw(0x6a, 0x0d); 160162306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 160262306a36Sopenharmony_ci break; 160362306a36Sopenharmony_ci default: 160462306a36Sopenharmony_ci dev_err(&pdev->dev, 160562306a36Sopenharmony_ci "No valid Silicon Motion display chip was detected!\n"); 160662306a36Sopenharmony_ci err = -ENODEV; 160762306a36Sopenharmony_ci goto failed_fb; 160862306a36Sopenharmony_ci } 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci /* probe and decide resolution */ 161162306a36Sopenharmony_ci sm7xx_resolution_probe(sfb); 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_ci /* can support 32 bpp */ 161462306a36Sopenharmony_ci if (sfb->fb->var.bits_per_pixel == 15) 161562306a36Sopenharmony_ci sfb->fb->var.bits_per_pixel = 16; 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci sfb->fb->var.xres_virtual = sfb->fb->var.xres; 161862306a36Sopenharmony_ci sfb->fb->var.yres_virtual = sfb->fb->var.yres; 161962306a36Sopenharmony_ci err = smtc_map_smem(sfb, pdev, smem_size); 162062306a36Sopenharmony_ci if (err) 162162306a36Sopenharmony_ci goto failed; 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_ci /* 162462306a36Sopenharmony_ci * The screen would be temporarily garbled when sm712fb takes over 162562306a36Sopenharmony_ci * vesafb or VGA text mode. Zero the framebuffer. 162662306a36Sopenharmony_ci */ 162762306a36Sopenharmony_ci memset_io(sfb->lfb, 0, sfb->fb->fix.smem_len); 162862306a36Sopenharmony_ci 162962306a36Sopenharmony_ci err = register_framebuffer(info); 163062306a36Sopenharmony_ci if (err < 0) 163162306a36Sopenharmony_ci goto failed; 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci dev_info(&pdev->dev, 163462306a36Sopenharmony_ci "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.\n", 163562306a36Sopenharmony_ci sfb->chip_id, sfb->chip_rev_id, sfb->fb->var.xres, 163662306a36Sopenharmony_ci sfb->fb->var.yres, sfb->fb->var.bits_per_pixel); 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci return 0; 163962306a36Sopenharmony_ci 164062306a36Sopenharmony_cifailed: 164162306a36Sopenharmony_ci dev_err(&pdev->dev, "Silicon Motion, Inc. primary display init fail.\n"); 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci smtc_unmap_smem(sfb); 164462306a36Sopenharmony_ci smtc_unmap_mmio(sfb); 164562306a36Sopenharmony_cifailed_fb: 164662306a36Sopenharmony_ci framebuffer_release(info); 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_cifailed_free: 164962306a36Sopenharmony_ci pci_release_region(pdev, 0); 165062306a36Sopenharmony_ci 165162306a36Sopenharmony_cifailed_regions: 165262306a36Sopenharmony_ci pci_disable_device(pdev); 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ci return err; 165562306a36Sopenharmony_ci} 165662306a36Sopenharmony_ci 165762306a36Sopenharmony_ci/* 165862306a36Sopenharmony_ci * 0x710 (LynxEM) 165962306a36Sopenharmony_ci * 0x712 (LynxEM+) 166062306a36Sopenharmony_ci * 0x720 (Lynx3DM, Lynx3DM+) 166162306a36Sopenharmony_ci */ 166262306a36Sopenharmony_cistatic const struct pci_device_id smtcfb_pci_table[] = { 166362306a36Sopenharmony_ci { PCI_DEVICE(0x126f, 0x710), }, 166462306a36Sopenharmony_ci { PCI_DEVICE(0x126f, 0x712), }, 166562306a36Sopenharmony_ci { PCI_DEVICE(0x126f, 0x720), }, 166662306a36Sopenharmony_ci {0,} 166762306a36Sopenharmony_ci}; 166862306a36Sopenharmony_ci 166962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, smtcfb_pci_table); 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_cistatic void smtcfb_pci_remove(struct pci_dev *pdev) 167262306a36Sopenharmony_ci{ 167362306a36Sopenharmony_ci struct smtcfb_info *sfb; 167462306a36Sopenharmony_ci 167562306a36Sopenharmony_ci sfb = pci_get_drvdata(pdev); 167662306a36Sopenharmony_ci smtc_unmap_smem(sfb); 167762306a36Sopenharmony_ci smtc_unmap_mmio(sfb); 167862306a36Sopenharmony_ci unregister_framebuffer(sfb->fb); 167962306a36Sopenharmony_ci framebuffer_release(sfb->fb); 168062306a36Sopenharmony_ci pci_release_region(pdev, 0); 168162306a36Sopenharmony_ci pci_disable_device(pdev); 168262306a36Sopenharmony_ci} 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_cistatic int __maybe_unused smtcfb_pci_suspend(struct device *device) 168562306a36Sopenharmony_ci{ 168662306a36Sopenharmony_ci struct smtcfb_info *sfb = dev_get_drvdata(device); 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci 168962306a36Sopenharmony_ci /* set the hw in sleep mode use external clock and self memory refresh 169062306a36Sopenharmony_ci * so that we can turn off internal PLLs later on 169162306a36Sopenharmony_ci */ 169262306a36Sopenharmony_ci smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0)); 169362306a36Sopenharmony_ci smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7)); 169462306a36Sopenharmony_ci 169562306a36Sopenharmony_ci console_lock(); 169662306a36Sopenharmony_ci fb_set_suspend(sfb->fb, 1); 169762306a36Sopenharmony_ci console_unlock(); 169862306a36Sopenharmony_ci 169962306a36Sopenharmony_ci /* additionally turn off all function blocks including internal PLLs */ 170062306a36Sopenharmony_ci smtc_seqw(0x21, 0xff); 170162306a36Sopenharmony_ci 170262306a36Sopenharmony_ci return 0; 170362306a36Sopenharmony_ci} 170462306a36Sopenharmony_ci 170562306a36Sopenharmony_cistatic int __maybe_unused smtcfb_pci_resume(struct device *device) 170662306a36Sopenharmony_ci{ 170762306a36Sopenharmony_ci struct smtcfb_info *sfb = dev_get_drvdata(device); 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci 171062306a36Sopenharmony_ci /* reinit hardware */ 171162306a36Sopenharmony_ci sm7xx_init_hw(); 171262306a36Sopenharmony_ci switch (sfb->chip_id) { 171362306a36Sopenharmony_ci case 0x710: 171462306a36Sopenharmony_ci case 0x712: 171562306a36Sopenharmony_ci /* set MCLK = 14.31818 * (0x16 / 0x2) */ 171662306a36Sopenharmony_ci smtc_seqw(0x6a, 0x16); 171762306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 171862306a36Sopenharmony_ci smtc_seqw(0x62, 0x3e); 171962306a36Sopenharmony_ci /* enable PCI burst */ 172062306a36Sopenharmony_ci smtc_seqw(0x17, 0x20); 172162306a36Sopenharmony_ci if (sfb->fb->var.bits_per_pixel == 32) 172262306a36Sopenharmony_ci seqw17(); 172362306a36Sopenharmony_ci break; 172462306a36Sopenharmony_ci case 0x720: 172562306a36Sopenharmony_ci smtc_seqw(0x62, 0xff); 172662306a36Sopenharmony_ci smtc_seqw(0x6a, 0x0d); 172762306a36Sopenharmony_ci smtc_seqw(0x6b, 0x02); 172862306a36Sopenharmony_ci break; 172962306a36Sopenharmony_ci } 173062306a36Sopenharmony_ci 173162306a36Sopenharmony_ci smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0)); 173262306a36Sopenharmony_ci smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb)); 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_ci smtcfb_setmode(sfb); 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci console_lock(); 173762306a36Sopenharmony_ci fb_set_suspend(sfb->fb, 0); 173862306a36Sopenharmony_ci console_unlock(); 173962306a36Sopenharmony_ci 174062306a36Sopenharmony_ci return 0; 174162306a36Sopenharmony_ci} 174262306a36Sopenharmony_ci 174362306a36Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(sm7xx_pm_ops, smtcfb_pci_suspend, smtcfb_pci_resume); 174462306a36Sopenharmony_ci 174562306a36Sopenharmony_cistatic struct pci_driver smtcfb_driver = { 174662306a36Sopenharmony_ci .name = "smtcfb", 174762306a36Sopenharmony_ci .id_table = smtcfb_pci_table, 174862306a36Sopenharmony_ci .probe = smtcfb_pci_probe, 174962306a36Sopenharmony_ci .remove = smtcfb_pci_remove, 175062306a36Sopenharmony_ci .driver.pm = &sm7xx_pm_ops, 175162306a36Sopenharmony_ci}; 175262306a36Sopenharmony_ci 175362306a36Sopenharmony_cistatic int __init sm712fb_init(void) 175462306a36Sopenharmony_ci{ 175562306a36Sopenharmony_ci char *option = NULL; 175662306a36Sopenharmony_ci 175762306a36Sopenharmony_ci if (fb_modesetting_disabled("sm712fb")) 175862306a36Sopenharmony_ci return -ENODEV; 175962306a36Sopenharmony_ci 176062306a36Sopenharmony_ci if (fb_get_options("sm712fb", &option)) 176162306a36Sopenharmony_ci return -ENODEV; 176262306a36Sopenharmony_ci if (option && *option) 176362306a36Sopenharmony_ci mode_option = option; 176462306a36Sopenharmony_ci sm7xx_vga_setup(mode_option); 176562306a36Sopenharmony_ci 176662306a36Sopenharmony_ci return pci_register_driver(&smtcfb_driver); 176762306a36Sopenharmony_ci} 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_cimodule_init(sm712fb_init); 177062306a36Sopenharmony_ci 177162306a36Sopenharmony_cistatic void __exit sm712fb_exit(void) 177262306a36Sopenharmony_ci{ 177362306a36Sopenharmony_ci pci_unregister_driver(&smtcfb_driver); 177462306a36Sopenharmony_ci} 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_cimodule_exit(sm712fb_exit); 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ciMODULE_AUTHOR("Siliconmotion "); 177962306a36Sopenharmony_ciMODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards"); 178062306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 1781