2015-01-19 11:11:00 +03:00
/*
* Silicon Motion SM7XX frame buffer device
*
* Copyright ( C ) 2006 Silicon Motion Technology Corp .
* Authors : Ge Wang , gewang @ siliconmotion . com
* Boyod boyod . yang @ siliconmotion . com . cn
*
* Copyright ( C ) 2009 Lemote , Inc .
* Author : Wu Zhangjin , wuzhangjin @ gmail . com
*
* Copyright ( C ) 2011 Igalia , S . L .
* Author : Javier M . Mellid < jmunhoz @ igalia . com >
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file COPYING in the main directory of this archive for
* more details .
*
* Framebuffer driver for Silicon Motion SM710 , SM712 , SM721 and SM722 chips
*/
# include <linux/io.h>
# include <linux/fb.h>
# include <linux/pci.h>
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/uaccess.h>
# include <linux/module.h>
# include <linux/console.h>
# include <linux/screen_info.h>
# include <linux/pm.h>
2015-08-07 16:01:13 +03:00
# include "sm712.h"
2015-01-19 11:11:00 +03:00
/*
2017-08-01 18:20:38 +03:00
* Private structure
*/
2015-01-19 11:11:00 +03:00
struct smtcfb_info {
struct pci_dev * pdev ;
2015-04-23 16:38:16 +03:00
struct fb_info * fb ;
2015-01-19 11:11:00 +03:00
u16 chip_id ;
u8 chip_rev_id ;
void __iomem * lfb ; /* linear frame buffer */
void __iomem * dp_regs ; /* drawing processor control regs */
void __iomem * vp_regs ; /* video processor control regs */
void __iomem * cp_regs ; /* capture processor control regs */
void __iomem * mmio ; /* memory map IO port */
u_int width ;
u_int height ;
u_int hz ;
u32 colreg [ 17 ] ;
} ;
2015-02-03 17:53:33 +03:00
void __iomem * smtc_regbaseaddress ; /* Memory Map IO starting address */
2015-01-19 11:11:00 +03:00
2016-09-11 18:17:20 +03:00
static const struct fb_var_screeninfo smtcfb_var = {
2015-01-19 11:11:00 +03:00
. xres = 1024 ,
. yres = 600 ,
. xres_virtual = 1024 ,
. yres_virtual = 600 ,
. bits_per_pixel = 16 ,
. red = { 16 , 8 , 0 } ,
. green = { 8 , 8 , 0 } ,
. blue = { 0 , 8 , 0 } ,
. activate = FB_ACTIVATE_NOW ,
. height = - 1 ,
. width = - 1 ,
. vmode = FB_VMODE_NONINTERLACED ,
. nonstd = 0 ,
. accel_flags = FB_ACCELF_TEXT ,
} ;
static struct fb_fix_screeninfo smtcfb_fix = {
. id = " smXXXfb " ,
. type = FB_TYPE_PACKED_PIXELS ,
. visual = FB_VISUAL_TRUECOLOR ,
. line_length = 800 * 3 ,
. accel = FB_ACCEL_SMI_LYNX ,
. type_aux = 0 ,
. xpanstep = 0 ,
. ypanstep = 0 ,
. ywrapstep = 0 ,
} ;
struct vesa_mode {
char index [ 6 ] ;
u16 lfb_width ;
u16 lfb_height ;
u16 lfb_depth ;
} ;
2015-06-17 14:24:40 +03:00
static const struct vesa_mode vesa_mode_table [ ] = {
2015-01-19 11:11:00 +03:00
{ " 0x301 " , 640 , 480 , 8 } ,
{ " 0x303 " , 800 , 600 , 8 } ,
{ " 0x305 " , 1024 , 768 , 8 } ,
{ " 0x307 " , 1280 , 1024 , 8 } ,
{ " 0x311 " , 640 , 480 , 16 } ,
{ " 0x314 " , 800 , 600 , 16 } ,
{ " 0x317 " , 1024 , 768 , 16 } ,
{ " 0x31A " , 1280 , 1024 , 16 } ,
{ " 0x312 " , 640 , 480 , 24 } ,
{ " 0x315 " , 800 , 600 , 24 } ,
{ " 0x318 " , 1024 , 768 , 24 } ,
{ " 0x31B " , 1280 , 1024 , 24 } ,
} ;
2015-06-17 14:24:46 +03:00
/**********************************************************************
SM712 Mode table .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-06-17 14:24:48 +03:00
static const struct modeinit vgamode [ ] = {
2015-06-17 14:24:46 +03:00
{
2015-06-17 14:24:47 +03:00
/* mode#0: 640 x 480 16Bpp 60Hz */
640 , 480 , 16 , 60 ,
/* Init_MISC */
0xE3 ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x00 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xFF , 0xBE , 0xEF , 0xFF , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x30 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x32 , 0x03 , 0xA0 , 0x09 , 0xC0 , 0x32 , 0x32 , 0x32 ,
0x32 , 0x32 , 0x32 , 0x32 , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x32 , 0x32 , 0x32 ,
0x04 , 0x24 , 0x63 , 0x4F , 0x52 , 0x0B , 0xDF , 0xEA ,
0x04 , 0x50 , 0x19 , 0x32 , 0x32 , 0x00 , 0x00 , 0x32 ,
0x01 , 0x80 , 0x7E , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x07 , 0x82 , 0x07 , 0x04 ,
0x00 , 0x45 , 0x30 , 0x30 , 0x40 , 0x30 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0x6F , 0x7F , 0x7F , 0xFF , 0x32 ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xEF , 0xFF , 0x32 , 0x32 ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFF , 0xBF , 0xFF , 0xFF , 0xED , 0xED , 0xED ,
0x7B , 0xFF , 0xFF , 0xFF , 0xBF , 0xEF , 0xFF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0x5F , 0x4F , 0x4F , 0x00 , 0x53 , 0x1F , 0x0B , 0x3E ,
0x00 , 0x40 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xEA , 0x0C , 0xDF , 0x50 , 0x40 , 0xDF , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x55 , 0x03 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xE7 , 0xFF , 0xFD ,
0x5F , 0x4F , 0x00 , 0x54 , 0x00 , 0x0B , 0xDF , 0x00 ,
0xEA , 0x0C , 0x2E , 0x00 , 0x4F , 0xDF ,
} ,
{ /* Init_CR90_CRA7 */
0x56 , 0xDD , 0x5E , 0xEA , 0x87 , 0x44 , 0x8F , 0x55 ,
0x0A , 0x8F , 0x55 , 0x0A , 0x00 , 0x00 , 0x18 , 0x00 ,
0x11 , 0x10 , 0x0B , 0x0A , 0x0A , 0x0A , 0x0A , 0x00 ,
} ,
} ,
2015-06-17 14:24:46 +03:00
{
2015-06-17 14:24:47 +03:00
/* mode#1: 640 x 480 24Bpp 60Hz */
640 , 480 , 24 , 60 ,
/* Init_MISC */
0xE3 ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x00 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xFF , 0xBE , 0xEF , 0xFF , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x30 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x32 , 0x03 , 0xA0 , 0x09 , 0xC0 , 0x32 , 0x32 , 0x32 ,
0x32 , 0x32 , 0x32 , 0x32 , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x32 , 0x32 , 0x32 ,
0x04 , 0x24 , 0x63 , 0x4F , 0x52 , 0x0B , 0xDF , 0xEA ,
0x04 , 0x50 , 0x19 , 0x32 , 0x32 , 0x00 , 0x00 , 0x32 ,
0x01 , 0x80 , 0x7E , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x07 , 0x82 , 0x07 , 0x04 ,
0x00 , 0x45 , 0x30 , 0x30 , 0x40 , 0x30 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0x6F , 0x7F , 0x7F , 0xFF , 0x32 ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xEF , 0xFF , 0x32 , 0x32 ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFF , 0xBF , 0xFF , 0xFF , 0xED , 0xED , 0xED ,
0x7B , 0xFF , 0xFF , 0xFF , 0xBF , 0xEF , 0xFF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0x5F , 0x4F , 0x4F , 0x00 , 0x53 , 0x1F , 0x0B , 0x3E ,
0x00 , 0x40 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xEA , 0x0C , 0xDF , 0x50 , 0x40 , 0xDF , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x55 , 0x03 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xE7 , 0xFF , 0xFD ,
0x5F , 0x4F , 0x00 , 0x54 , 0x00 , 0x0B , 0xDF , 0x00 ,
0xEA , 0x0C , 0x2E , 0x00 , 0x4F , 0xDF ,
} ,
{ /* Init_CR90_CRA7 */
0x56 , 0xDD , 0x5E , 0xEA , 0x87 , 0x44 , 0x8F , 0x55 ,
0x0A , 0x8F , 0x55 , 0x0A , 0x00 , 0x00 , 0x18 , 0x00 ,
0x11 , 0x10 , 0x0B , 0x0A , 0x0A , 0x0A , 0x0A , 0x00 ,
} ,
} ,
2015-06-17 14:24:46 +03:00
{
2015-06-17 14:24:47 +03:00
/* mode#0: 640 x 480 32Bpp 60Hz */
640 , 480 , 32 , 60 ,
/* Init_MISC */
0xE3 ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x00 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xFF , 0xBE , 0xEF , 0xFF , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x30 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x32 , 0x03 , 0xA0 , 0x09 , 0xC0 , 0x32 , 0x32 , 0x32 ,
0x32 , 0x32 , 0x32 , 0x32 , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x32 , 0x32 , 0x32 ,
0x04 , 0x24 , 0x63 , 0x4F , 0x52 , 0x0B , 0xDF , 0xEA ,
0x04 , 0x50 , 0x19 , 0x32 , 0x32 , 0x00 , 0x00 , 0x32 ,
0x01 , 0x80 , 0x7E , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x07 , 0x82 , 0x07 , 0x04 ,
0x00 , 0x45 , 0x30 , 0x30 , 0x40 , 0x30 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0x6F , 0x7F , 0x7F , 0xFF , 0x32 ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xEF , 0xFF , 0x32 , 0x32 ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFF , 0xBF , 0xFF , 0xFF , 0xED , 0xED , 0xED ,
0x7B , 0xFF , 0xFF , 0xFF , 0xBF , 0xEF , 0xFF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0x5F , 0x4F , 0x4F , 0x00 , 0x53 , 0x1F , 0x0B , 0x3E ,
0x00 , 0x40 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xEA , 0x0C , 0xDF , 0x50 , 0x40 , 0xDF , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x55 , 0x03 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xE7 , 0xFF , 0xFD ,
0x5F , 0x4F , 0x00 , 0x54 , 0x00 , 0x0B , 0xDF , 0x00 ,
0xEA , 0x0C , 0x2E , 0x00 , 0x4F , 0xDF ,
} ,
{ /* Init_CR90_CRA7 */
0x56 , 0xDD , 0x5E , 0xEA , 0x87 , 0x44 , 0x8F , 0x55 ,
0x0A , 0x8F , 0x55 , 0x0A , 0x00 , 0x00 , 0x18 , 0x00 ,
0x11 , 0x10 , 0x0B , 0x0A , 0x0A , 0x0A , 0x0A , 0x00 ,
} ,
} ,
2015-06-17 14:24:46 +03:00
2015-06-17 14:24:47 +03:00
{ /* mode#2: 800 x 600 16Bpp 60Hz */
800 , 600 , 16 , 60 ,
/* Init_MISC */
0x2B ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x03 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xFF , 0xBE , 0xEE , 0xFF , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x30 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x34 , 0x03 , 0x20 , 0x09 , 0xC0 , 0x24 , 0x24 , 0x24 ,
0x24 , 0x24 , 0x24 , 0x24 , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x38 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x24 , 0x24 , 0x24 ,
0x04 , 0x48 , 0x83 , 0x63 , 0x68 , 0x72 , 0x57 , 0x58 ,
0x04 , 0x55 , 0x59 , 0x24 , 0x24 , 0x00 , 0x00 , 0x24 ,
0x01 , 0x80 , 0x7A , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x1C , 0x85 , 0x35 , 0x13 ,
0x02 , 0x45 , 0x30 , 0x35 , 0x40 , 0x20 ,
} ,
{ /* Init_SR80_SR93 */
0x00 , 0x00 , 0x00 , 0x6F , 0x7F , 0x7F , 0xFF , 0x24 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x24 , 0x24 ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFF , 0xBF , 0xFF , 0xFF , 0xED , 0xED , 0xED ,
0x7B , 0xFF , 0xFF , 0xFF , 0xBF , 0xEF , 0xBF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0x7F , 0x63 , 0x63 , 0x00 , 0x68 , 0x18 , 0x72 , 0xF0 ,
0x00 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x58 , 0x0C , 0x57 , 0x64 , 0x40 , 0x57 , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x33 , 0x03 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xE7 , 0xBF , 0xFD ,
0x7F , 0x63 , 0x00 , 0x69 , 0x18 , 0x72 , 0x57 , 0x00 ,
0x58 , 0x0C , 0xE0 , 0x20 , 0x63 , 0x57 ,
} ,
{ /* Init_CR90_CRA7 */
0x56 , 0x4B , 0x5E , 0x55 , 0x86 , 0x9D , 0x8E , 0xAA ,
0xDB , 0x2A , 0xDF , 0x33 , 0x00 , 0x00 , 0x18 , 0x00 ,
0x20 , 0x1F , 0x1A , 0x19 , 0x0F , 0x0F , 0x0F , 0x00 ,
} ,
} ,
{ /* mode#3: 800 x 600 24Bpp 60Hz */
800 , 600 , 24 , 60 ,
0x2B ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x03 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xFF , 0xBE , 0xEE , 0xFF , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x30 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x36 , 0x03 , 0x20 , 0x09 , 0xC0 , 0x36 , 0x36 , 0x36 ,
0x36 , 0x36 , 0x36 , 0x36 , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x36 , 0x36 , 0x36 ,
0x04 , 0x48 , 0x83 , 0x63 , 0x68 , 0x72 , 0x57 , 0x58 ,
0x04 , 0x55 , 0x59 , 0x36 , 0x36 , 0x00 , 0x00 , 0x36 ,
0x01 , 0x80 , 0x7E , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x1C , 0x85 , 0x35 , 0x13 ,
0x02 , 0x45 , 0x30 , 0x30 , 0x40 , 0x20 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0x6F , 0x7F , 0x7F , 0xFF , 0x36 ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xEF , 0xFF , 0x36 , 0x36 ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFF , 0xBF , 0xFF , 0xFF , 0xED , 0xED , 0xED ,
0x7B , 0xFF , 0xFF , 0xFF , 0xBF , 0xEF , 0xBF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0x7F , 0x63 , 0x63 , 0x00 , 0x68 , 0x18 , 0x72 , 0xF0 ,
0x00 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x58 , 0x0C , 0x57 , 0x64 , 0x40 , 0x57 , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x33 , 0x03 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xE7 , 0xBF , 0xFD ,
0x7F , 0x63 , 0x00 , 0x69 , 0x18 , 0x72 , 0x57 , 0x00 ,
0x58 , 0x0C , 0xE0 , 0x20 , 0x63 , 0x57 ,
} ,
{ /* Init_CR90_CRA7 */
0x56 , 0x4B , 0x5E , 0x55 , 0x86 , 0x9D , 0x8E , 0xAA ,
0xDB , 0x2A , 0xDF , 0x33 , 0x00 , 0x00 , 0x18 , 0x00 ,
0x20 , 0x1F , 0x1A , 0x19 , 0x0F , 0x0F , 0x0F , 0x00 ,
} ,
} ,
{ /* mode#7: 800 x 600 32Bpp 60Hz */
800 , 600 , 32 , 60 ,
/* Init_MISC */
0x2B ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x03 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xFF , 0xBE , 0xEE , 0xFF , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x30 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x34 , 0x03 , 0x20 , 0x09 , 0xC0 , 0x24 , 0x24 , 0x24 ,
0x24 , 0x24 , 0x24 , 0x24 , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x38 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x24 , 0x24 , 0x24 ,
0x04 , 0x48 , 0x83 , 0x63 , 0x68 , 0x72 , 0x57 , 0x58 ,
0x04 , 0x55 , 0x59 , 0x24 , 0x24 , 0x00 , 0x00 , 0x24 ,
0x01 , 0x80 , 0x7A , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x1C , 0x85 , 0x35 , 0x13 ,
0x02 , 0x45 , 0x30 , 0x35 , 0x40 , 0x20 ,
} ,
{ /* Init_SR80_SR93 */
0x00 , 0x00 , 0x00 , 0x6F , 0x7F , 0x7F , 0xFF , 0x24 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x24 , 0x24 ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFF , 0xBF , 0xFF , 0xFF , 0xED , 0xED , 0xED ,
0x7B , 0xFF , 0xFF , 0xFF , 0xBF , 0xEF , 0xBF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0x7F , 0x63 , 0x63 , 0x00 , 0x68 , 0x18 , 0x72 , 0xF0 ,
0x00 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x58 , 0x0C , 0x57 , 0x64 , 0x40 , 0x57 , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x33 , 0x03 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xE7 , 0xBF , 0xFD ,
0x7F , 0x63 , 0x00 , 0x69 , 0x18 , 0x72 , 0x57 , 0x00 ,
0x58 , 0x0C , 0xE0 , 0x20 , 0x63 , 0x57 ,
} ,
{ /* Init_CR90_CRA7 */
0x56 , 0x4B , 0x5E , 0x55 , 0x86 , 0x9D , 0x8E , 0xAA ,
0xDB , 0x2A , 0xDF , 0x33 , 0x00 , 0x00 , 0x18 , 0x00 ,
0x20 , 0x1F , 0x1A , 0x19 , 0x0F , 0x0F , 0x0F , 0x00 ,
} ,
} ,
2015-06-17 14:24:46 +03:00
/* We use 1024x768 table to light 1024x600 panel for lemote */
2015-06-17 14:24:47 +03:00
{ /* mode#4: 1024 x 600 16Bpp 60Hz */
1024 , 600 , 16 , 60 ,
/* Init_MISC */
0xEB ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x00 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xC8 , 0x40 , 0x14 , 0x60 , 0x00 , 0x0A , 0x17 , 0x20 ,
0x51 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x30 , 0x02 , 0x00 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x22 , 0x03 , 0x24 , 0x09 , 0xC0 , 0x22 , 0x22 , 0x22 ,
0x22 , 0x22 , 0x22 , 0x22 , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x22 , 0x22 , 0x22 ,
0x06 , 0x68 , 0xA7 , 0x7F , 0x83 , 0x24 , 0xFF , 0x03 ,
0x00 , 0x60 , 0x59 , 0x22 , 0x22 , 0x00 , 0x00 , 0x22 ,
0x01 , 0x80 , 0x7A , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x16 , 0x02 , 0x0D , 0x82 , 0x09 , 0x02 ,
0x04 , 0x45 , 0x3F , 0x30 , 0x40 , 0x20 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0x3A ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x3A , 0x3A ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFB , 0x9F , 0x01 , 0x00 , 0xED , 0xED , 0xED ,
0x7B , 0xFB , 0xFF , 0xFF , 0x97 , 0xEF , 0xBF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0xA3 , 0x7F , 0x7F , 0x00 , 0x85 , 0x16 , 0x24 , 0xF5 ,
0x00 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x09 , 0xFF , 0x80 , 0x40 , 0xFF , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 , 0x02 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xFF , 0xBF , 0xFF ,
0xA3 , 0x7F , 0x00 , 0x82 , 0x0b , 0x6f , 0x57 , 0x00 ,
0x5c , 0x0f , 0xE0 , 0xe0 , 0x7F , 0x57 ,
} ,
{ /* Init_CR90_CRA7 */
0x55 , 0xD9 , 0x5D , 0xE1 , 0x86 , 0x1B , 0x8E , 0x26 ,
0xDA , 0x8D , 0xDE , 0x94 , 0x00 , 0x00 , 0x18 , 0x00 ,
0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x15 , 0x03 ,
} ,
} ,
{ /* mode#5: 1024 x 768 24Bpp 60Hz */
1024 , 768 , 24 , 60 ,
/* Init_MISC */
0xEB ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x03 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xF3 , 0xB6 , 0xC0 , 0xDD , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x30 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x38 , 0x03 , 0x20 , 0x09 , 0xC0 , 0x3A , 0x3A , 0x3A ,
0x3A , 0x3A , 0x3A , 0x3A , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x00 , 0x00 , 0x3A ,
0x06 , 0x68 , 0xA7 , 0x7F , 0x83 , 0x24 , 0xFF , 0x03 ,
0x00 , 0x60 , 0x59 , 0x3A , 0x3A , 0x00 , 0x00 , 0x3A ,
0x01 , 0x80 , 0x7E , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x3B , 0x0D , 0x09 , 0x02 ,
0x04 , 0x45 , 0x30 , 0x30 , 0x40 , 0x20 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0x3A ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x3A , 0x3A ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFB , 0x9F , 0x01 , 0x00 , 0xED , 0xED , 0xED ,
0x7B , 0xFB , 0xFF , 0xFF , 0x97 , 0xEF , 0xBF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0xA3 , 0x7F , 0x7F , 0x00 , 0x85 , 0x16 , 0x24 , 0xF5 ,
0x00 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x09 , 0xFF , 0x80 , 0x40 , 0xFF , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 , 0x02 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xFF , 0xBF , 0xFF ,
0xA3 , 0x7F , 0x00 , 0x86 , 0x15 , 0x24 , 0xFF , 0x00 ,
0x01 , 0x07 , 0xE5 , 0x20 , 0x7F , 0xFF ,
} ,
{ /* Init_CR90_CRA7 */
0x55 , 0xD9 , 0x5D , 0xE1 , 0x86 , 0x1B , 0x8E , 0x26 ,
0xDA , 0x8D , 0xDE , 0x94 , 0x00 , 0x00 , 0x18 , 0x00 ,
0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x15 , 0x03 ,
} ,
} ,
{ /* mode#4: 1024 x 768 32Bpp 60Hz */
1024 , 768 , 32 , 60 ,
/* Init_MISC */
0xEB ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x03 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xF3 , 0xB6 , 0xC0 , 0xDD , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x32 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x38 , 0x03 , 0x20 , 0x09 , 0xC0 , 0x3A , 0x3A , 0x3A ,
0x3A , 0x3A , 0x3A , 0x3A , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x00 , 0x00 , 0x3A ,
0x06 , 0x68 , 0xA7 , 0x7F , 0x83 , 0x24 , 0xFF , 0x03 ,
0x00 , 0x60 , 0x59 , 0x3A , 0x3A , 0x00 , 0x00 , 0x3A ,
0x01 , 0x80 , 0x7E , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x3B , 0x0D , 0x09 , 0x02 ,
0x04 , 0x45 , 0x30 , 0x30 , 0x40 , 0x20 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0x3A ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x3A , 0x3A ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFB , 0x9F , 0x01 , 0x00 , 0xED , 0xED , 0xED ,
0x7B , 0xFB , 0xFF , 0xFF , 0x97 , 0xEF , 0xBF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0xA3 , 0x7F , 0x7F , 0x00 , 0x85 , 0x16 , 0x24 , 0xF5 ,
0x00 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x09 , 0xFF , 0x80 , 0x40 , 0xFF , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 , 0x02 , 0x20 ,
0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0xFF , 0xBF , 0xFF ,
0xA3 , 0x7F , 0x00 , 0x86 , 0x15 , 0x24 , 0xFF , 0x00 ,
0x01 , 0x07 , 0xE5 , 0x20 , 0x7F , 0xFF ,
} ,
{ /* Init_CR90_CRA7 */
0x55 , 0xD9 , 0x5D , 0xE1 , 0x86 , 0x1B , 0x8E , 0x26 ,
0xDA , 0x8D , 0xDE , 0x94 , 0x00 , 0x00 , 0x18 , 0x00 ,
0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x15 , 0x03 ,
} ,
} ,
{ /* mode#6: 320 x 240 16Bpp 60Hz */
320 , 240 , 16 , 60 ,
/* Init_MISC */
0xEB ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x03 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xF3 , 0xB6 , 0xC0 , 0xDD , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x32 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x38 , 0x03 , 0x20 , 0x09 , 0xC0 , 0x3A , 0x3A , 0x3A ,
0x3A , 0x3A , 0x3A , 0x3A , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x00 , 0x00 , 0x3A ,
0x06 , 0x68 , 0xA7 , 0x7F , 0x83 , 0x24 , 0xFF , 0x03 ,
0x00 , 0x60 , 0x59 , 0x3A , 0x3A , 0x00 , 0x00 , 0x3A ,
0x01 , 0x80 , 0x7E , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x08 , 0x43 , 0x08 , 0x43 ,
0x04 , 0x45 , 0x30 , 0x30 , 0x40 , 0x20 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0x3A ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x3A , 0x3A ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFB , 0x9F , 0x01 , 0x00 , 0xED , 0xED , 0xED ,
0x7B , 0xFB , 0xFF , 0xFF , 0x97 , 0xEF , 0xBF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0xA3 , 0x7F , 0x7F , 0x00 , 0x85 , 0x16 , 0x24 , 0xF5 ,
0x00 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x09 , 0xFF , 0x80 , 0x40 , 0xFF , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 , 0x02 , 0x20 ,
0x00 , 0x00 , 0x30 , 0x40 , 0x00 , 0xFF , 0xBF , 0xFF ,
0x2E , 0x27 , 0x00 , 0x2b , 0x0c , 0x0F , 0xEF , 0x00 ,
0xFe , 0x0f , 0x01 , 0xC0 , 0x27 , 0xEF ,
} ,
{ /* Init_CR90_CRA7 */
0x55 , 0xD9 , 0x5D , 0xE1 , 0x86 , 0x1B , 0x8E , 0x26 ,
0xDA , 0x8D , 0xDE , 0x94 , 0x00 , 0x00 , 0x18 , 0x00 ,
0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x15 , 0x03 ,
} ,
} ,
2015-06-17 14:24:46 +03:00
2015-06-17 14:24:47 +03:00
{ /* mode#8: 320 x 240 32Bpp 60Hz */
320 , 240 , 32 , 60 ,
/* Init_MISC */
0xEB ,
{ /* Init_SR0_SR4 */
0x03 , 0x01 , 0x0F , 0x03 , 0x0E ,
} ,
{ /* Init_SR10_SR24 */
0xF3 , 0xB6 , 0xC0 , 0xDD , 0x00 , 0x0E , 0x17 , 0x2C ,
0x99 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xC4 , 0x32 , 0x02 , 0x01 , 0x01 ,
} ,
{ /* Init_SR30_SR75 */
0x38 , 0x03 , 0x20 , 0x09 , 0xC0 , 0x3A , 0x3A , 0x3A ,
0x3A , 0x3A , 0x3A , 0x3A , 0x00 , 0x00 , 0x03 , 0xFF ,
0x00 , 0xFC , 0x00 , 0x00 , 0x20 , 0x18 , 0x00 , 0xFC ,
0x20 , 0x0C , 0x44 , 0x20 , 0x00 , 0x00 , 0x00 , 0x3A ,
0x06 , 0x68 , 0xA7 , 0x7F , 0x83 , 0x24 , 0xFF , 0x03 ,
0x00 , 0x60 , 0x59 , 0x3A , 0x3A , 0x00 , 0x00 , 0x3A ,
0x01 , 0x80 , 0x7E , 0x1A , 0x1A , 0x00 , 0x00 , 0x00 ,
0x50 , 0x03 , 0x74 , 0x14 , 0x08 , 0x43 , 0x08 , 0x43 ,
0x04 , 0x45 , 0x30 , 0x30 , 0x40 , 0x20 ,
} ,
{ /* Init_SR80_SR93 */
0xFF , 0x07 , 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0x3A ,
0xF7 , 0x00 , 0x00 , 0x00 , 0xFF , 0xFF , 0x3A , 0x3A ,
0x00 , 0x00 , 0x00 , 0x00 ,
} ,
{ /* Init_SRA0_SRAF */
0x00 , 0xFB , 0x9F , 0x01 , 0x00 , 0xED , 0xED , 0xED ,
0x7B , 0xFB , 0xFF , 0xFF , 0x97 , 0xEF , 0xBF , 0xDF ,
} ,
{ /* Init_GR00_GR08 */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 , 0x05 , 0x0F ,
0xFF ,
} ,
{ /* Init_AR00_AR14 */
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x41 , 0x00 , 0x0F , 0x00 , 0x00 ,
} ,
{ /* Init_CR00_CR18 */
0xA3 , 0x7F , 0x7F , 0x00 , 0x85 , 0x16 , 0x24 , 0xF5 ,
0x00 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x09 , 0xFF , 0x80 , 0x40 , 0xFF , 0x00 , 0xE3 ,
0xFF ,
} ,
{ /* Init_CR30_CR4D */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 , 0x02 , 0x20 ,
0x00 , 0x00 , 0x30 , 0x40 , 0x00 , 0xFF , 0xBF , 0xFF ,
0x2E , 0x27 , 0x00 , 0x2b , 0x0c , 0x0F , 0xEF , 0x00 ,
0xFe , 0x0f , 0x01 , 0xC0 , 0x27 , 0xEF ,
} ,
{ /* Init_CR90_CRA7 */
0x55 , 0xD9 , 0x5D , 0xE1 , 0x86 , 0x1B , 0x8E , 0x26 ,
0xDA , 0x8D , 0xDE , 0x94 , 0x00 , 0x00 , 0x18 , 0x00 ,
0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x03 , 0x15 , 0x03 ,
} ,
} ,
2015-06-17 14:24:46 +03:00
} ;
2015-02-03 11:44:28 +03:00
static struct screen_info smtc_scr_info ;
2015-01-19 11:11:00 +03:00
2015-03-08 20:40:09 +03:00
static char * mode_option ;
2015-01-19 11:11:00 +03:00
/* process command line options, get vga parameter */
2015-03-08 20:40:11 +03:00
static void __init sm7xx_vga_setup ( char * options )
2015-01-19 11:11:00 +03:00
{
int i ;
if ( ! options | | ! * options )
2015-03-08 20:40:11 +03:00
return ;
2015-01-19 11:11:00 +03:00
smtc_scr_info . lfb_width = 0 ;
smtc_scr_info . lfb_height = 0 ;
smtc_scr_info . lfb_depth = 0 ;
2017-08-01 18:20:38 +03:00
pr_debug ( " %s = %s \n " , __func__ , options ) ;
2015-01-19 11:11:00 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( vesa_mode_table ) ; i + + ) {
if ( strstr ( options , vesa_mode_table [ i ] . index ) ) {
smtc_scr_info . lfb_width = vesa_mode_table [ i ] . lfb_width ;
smtc_scr_info . lfb_height =
vesa_mode_table [ i ] . lfb_height ;
smtc_scr_info . lfb_depth = vesa_mode_table [ i ] . lfb_depth ;
2015-03-08 20:40:11 +03:00
return ;
2015-01-19 11:11:00 +03:00
}
}
}
2017-08-01 18:20:38 +03:00
static void sm712_setpalette ( int regno , unsigned int red , unsigned int green ,
unsigned int blue , struct fb_info * info )
2015-01-19 11:11:00 +03:00
{
/* set bit 5:4 = 01 (write LCD RAM only) */
smtc_seqw ( 0x66 , ( smtc_seqr ( 0x66 ) & 0xC3 ) | 0x10 ) ;
smtc_mmiowb ( regno , dac_reg ) ;
smtc_mmiowb ( red > > 10 , dac_val ) ;
smtc_mmiowb ( green > > 10 , dac_val ) ;
smtc_mmiowb ( blue > > 10 , dac_val ) ;
}
/* chan_to_field
*
* convert a colour value into a field position
*
* from pxafb . c
*/
static inline unsigned int chan_to_field ( unsigned int chan ,
struct fb_bitfield * bf )
{
chan & = 0xffff ;
chan > > = 16 - bf - > length ;
return chan < < bf - > offset ;
}
static int smtc_blank ( int blank_mode , struct fb_info * info )
{
/* clear DPMS setting */
switch ( blank_mode ) {
case FB_BLANK_UNBLANK :
/* Screen On: HSync: On, VSync : On */
smtc_seqw ( 0x01 , ( smtc_seqr ( 0x01 ) & ( ~ 0x20 ) ) ) ;
smtc_seqw ( 0x6a , 0x16 ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
smtc_seqw ( 0x21 , ( smtc_seqr ( 0x21 ) & 0x77 ) ) ;
smtc_seqw ( 0x22 , ( smtc_seqr ( 0x22 ) & ( ~ 0x30 ) ) ) ;
smtc_seqw ( 0x23 , ( smtc_seqr ( 0x23 ) & ( ~ 0xc0 ) ) ) ;
smtc_seqw ( 0x24 , ( smtc_seqr ( 0x24 ) | 0x01 ) ) ;
smtc_seqw ( 0x31 , ( smtc_seqr ( 0x31 ) | 0x03 ) ) ;
break ;
case FB_BLANK_NORMAL :
/* Screen Off: HSync: On, VSync : On Soft blank */
smtc_seqw ( 0x01 , ( smtc_seqr ( 0x01 ) & ( ~ 0x20 ) ) ) ;
smtc_seqw ( 0x6a , 0x16 ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
smtc_seqw ( 0x22 , ( smtc_seqr ( 0x22 ) & ( ~ 0x30 ) ) ) ;
smtc_seqw ( 0x23 , ( smtc_seqr ( 0x23 ) & ( ~ 0xc0 ) ) ) ;
smtc_seqw ( 0x24 , ( smtc_seqr ( 0x24 ) | 0x01 ) ) ;
smtc_seqw ( 0x31 , ( ( smtc_seqr ( 0x31 ) & ( ~ 0x07 ) ) | 0x00 ) ) ;
break ;
case FB_BLANK_VSYNC_SUSPEND :
/* Screen On: HSync: On, VSync : Off */
smtc_seqw ( 0x01 , ( smtc_seqr ( 0x01 ) | 0x20 ) ) ;
smtc_seqw ( 0x20 , ( smtc_seqr ( 0x20 ) & ( ~ 0xB0 ) ) ) ;
smtc_seqw ( 0x6a , 0x0c ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
smtc_seqw ( 0x21 , ( smtc_seqr ( 0x21 ) | 0x88 ) ) ;
smtc_seqw ( 0x22 , ( ( smtc_seqr ( 0x22 ) & ( ~ 0x30 ) ) | 0x20 ) ) ;
smtc_seqw ( 0x23 , ( ( smtc_seqr ( 0x23 ) & ( ~ 0xc0 ) ) | 0x20 ) ) ;
smtc_seqw ( 0x24 , ( smtc_seqr ( 0x24 ) & ( ~ 0x01 ) ) ) ;
smtc_seqw ( 0x31 , ( ( smtc_seqr ( 0x31 ) & ( ~ 0x07 ) ) | 0x00 ) ) ;
smtc_seqw ( 0x34 , ( smtc_seqr ( 0x34 ) | 0x80 ) ) ;
break ;
case FB_BLANK_HSYNC_SUSPEND :
/* Screen On: HSync: Off, VSync : On */
smtc_seqw ( 0x01 , ( smtc_seqr ( 0x01 ) | 0x20 ) ) ;
smtc_seqw ( 0x20 , ( smtc_seqr ( 0x20 ) & ( ~ 0xB0 ) ) ) ;
smtc_seqw ( 0x6a , 0x0c ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
smtc_seqw ( 0x21 , ( smtc_seqr ( 0x21 ) | 0x88 ) ) ;
smtc_seqw ( 0x22 , ( ( smtc_seqr ( 0x22 ) & ( ~ 0x30 ) ) | 0x10 ) ) ;
smtc_seqw ( 0x23 , ( ( smtc_seqr ( 0x23 ) & ( ~ 0xc0 ) ) | 0xD8 ) ) ;
smtc_seqw ( 0x24 , ( smtc_seqr ( 0x24 ) & ( ~ 0x01 ) ) ) ;
smtc_seqw ( 0x31 , ( ( smtc_seqr ( 0x31 ) & ( ~ 0x07 ) ) | 0x00 ) ) ;
smtc_seqw ( 0x34 , ( smtc_seqr ( 0x34 ) | 0x80 ) ) ;
break ;
case FB_BLANK_POWERDOWN :
/* Screen On: HSync: Off, VSync : Off */
smtc_seqw ( 0x01 , ( smtc_seqr ( 0x01 ) | 0x20 ) ) ;
smtc_seqw ( 0x20 , ( smtc_seqr ( 0x20 ) & ( ~ 0xB0 ) ) ) ;
smtc_seqw ( 0x6a , 0x0c ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
smtc_seqw ( 0x21 , ( smtc_seqr ( 0x21 ) | 0x88 ) ) ;
smtc_seqw ( 0x22 , ( ( smtc_seqr ( 0x22 ) & ( ~ 0x30 ) ) | 0x30 ) ) ;
smtc_seqw ( 0x23 , ( ( smtc_seqr ( 0x23 ) & ( ~ 0xc0 ) ) | 0xD8 ) ) ;
smtc_seqw ( 0x24 , ( smtc_seqr ( 0x24 ) & ( ~ 0x01 ) ) ) ;
smtc_seqw ( 0x31 , ( ( smtc_seqr ( 0x31 ) & ( ~ 0x07 ) ) | 0x00 ) ) ;
smtc_seqw ( 0x34 , ( smtc_seqr ( 0x34 ) | 0x80 ) ) ;
break ;
default :
return - EINVAL ;
}
return 0 ;
}
2017-08-01 18:20:38 +03:00
static int smtc_setcolreg ( unsigned int regno , unsigned int red ,
unsigned int green , unsigned int blue ,
unsigned int trans , struct fb_info * info )
2015-01-19 11:11:00 +03:00
{
struct smtcfb_info * sfb ;
u32 val ;
sfb = info - > par ;
if ( regno > 255 )
return 1 ;
2015-04-23 16:38:16 +03:00
switch ( sfb - > fb - > fix . visual ) {
2015-01-19 11:11:00 +03:00
case FB_VISUAL_DIRECTCOLOR :
case FB_VISUAL_TRUECOLOR :
/*
* 16 / 32 bit true - colour , use pseudo - palette for 16 base color
*/
2015-06-17 14:24:45 +03:00
if ( regno > = 16 )
break ;
if ( sfb - > fb - > var . bits_per_pixel = = 16 ) {
u32 * pal = sfb - > fb - > pseudo_palette ;
val = chan_to_field ( red , & sfb - > fb - > var . red ) ;
val | = chan_to_field ( green , & sfb - > fb - > var . green ) ;
val | = chan_to_field ( blue , & sfb - > fb - > var . blue ) ;
2015-07-15 11:29:45 +03:00
pal [ regno ] = pal_rgb ( red , green , blue , val ) ;
2015-06-17 14:24:45 +03:00
} else {
u32 * pal = sfb - > fb - > pseudo_palette ;
2015-01-19 11:11:03 +03:00
2015-06-17 14:24:45 +03:00
val = chan_to_field ( red , & sfb - > fb - > var . red ) ;
val | = chan_to_field ( green , & sfb - > fb - > var . green ) ;
val | = chan_to_field ( blue , & sfb - > fb - > var . blue ) ;
2015-07-15 11:29:45 +03:00
pal [ regno ] = big_swap ( val ) ;
2015-01-19 11:11:00 +03:00
}
break ;
case FB_VISUAL_PSEUDOCOLOR :
/* color depth 8 bit */
sm712_setpalette ( regno , red , green , blue , info ) ;
break ;
default :
return 1 ; /* unknown type */
}
return 0 ;
}
2015-06-17 14:24:44 +03:00
static ssize_t smtcfb_read ( struct fb_info * info , char __user * buf ,
size_t count , loff_t * ppos )
2015-01-19 11:11:00 +03:00
{
unsigned long p = * ppos ;
u32 * buffer , * dst ;
u32 __iomem * src ;
int c , i , cnt = 0 , err = 0 ;
unsigned long total_size ;
if ( ! info | | ! info - > screen_base )
return - ENODEV ;
if ( info - > state ! = FBINFO_STATE_RUNNING )
return - EPERM ;
total_size = info - > screen_size ;
if ( total_size = = 0 )
total_size = info - > fix . smem_len ;
if ( p > = total_size )
return 0 ;
if ( count > = total_size )
count = total_size ;
if ( count + p > total_size )
count = total_size - p ;
buffer = kmalloc ( ( count > PAGE_SIZE ) ? PAGE_SIZE : count , GFP_KERNEL ) ;
if ( ! buffer )
return - ENOMEM ;
2015-06-17 14:24:43 +03:00
src = ( u32 __iomem * ) ( info - > screen_base + p ) ;
2015-01-19 11:11:00 +03:00
if ( info - > fbops - > fb_sync )
info - > fbops - > fb_sync ( info ) ;
while ( count ) {
c = ( count > PAGE_SIZE ) ? PAGE_SIZE : count ;
dst = buffer ;
for ( i = c > > 2 ; i - - ; ) {
* dst = fb_readl ( src + + ) ;
2015-07-15 11:29:45 +03:00
* dst = big_swap ( * dst ) ;
2015-01-19 11:11:00 +03:00
dst + + ;
}
if ( c & 3 ) {
2015-01-19 11:11:04 +03:00
u8 * dst8 = ( u8 * ) dst ;
u8 __iomem * src8 = ( u8 __iomem * ) src ;
2015-01-19 11:11:00 +03:00
for ( i = c & 3 ; i - - ; ) {
if ( i & 1 ) {
* dst8 + + = fb_readb ( + + src8 ) ;
} else {
* dst8 + + = fb_readb ( - - src8 ) ;
src8 + = 2 ;
}
}
2015-01-19 11:11:04 +03:00
src = ( u32 __iomem * ) src8 ;
2015-01-19 11:11:00 +03:00
}
if ( copy_to_user ( buf , buffer , c ) ) {
err = - EFAULT ;
break ;
}
* ppos + = c ;
buf + = c ;
cnt + = c ;
count - = c ;
}
kfree ( buffer ) ;
return ( err ) ? err : cnt ;
}
2015-06-17 14:24:44 +03:00
static ssize_t smtcfb_write ( struct fb_info * info , const char __user * buf ,
size_t count , loff_t * ppos )
2015-01-19 11:11:00 +03:00
{
unsigned long p = * ppos ;
u32 * buffer , * src ;
u32 __iomem * dst ;
int c , i , cnt = 0 , err = 0 ;
unsigned long total_size ;
if ( ! info | | ! info - > screen_base )
return - ENODEV ;
if ( info - > state ! = FBINFO_STATE_RUNNING )
return - EPERM ;
total_size = info - > screen_size ;
if ( total_size = = 0 )
total_size = info - > fix . smem_len ;
if ( p > total_size )
return - EFBIG ;
if ( count > total_size ) {
err = - EFBIG ;
count = total_size ;
}
if ( count + p > total_size ) {
if ( ! err )
err = - ENOSPC ;
count = total_size - p ;
}
buffer = kmalloc ( ( count > PAGE_SIZE ) ? PAGE_SIZE : count , GFP_KERNEL ) ;
if ( ! buffer )
return - ENOMEM ;
2015-06-17 14:24:43 +03:00
dst = ( u32 __iomem * ) ( info - > screen_base + p ) ;
2015-01-19 11:11:00 +03:00
if ( info - > fbops - > fb_sync )
info - > fbops - > fb_sync ( info ) ;
while ( count ) {
c = ( count > PAGE_SIZE ) ? PAGE_SIZE : count ;
src = buffer ;
if ( copy_from_user ( src , buf , c ) ) {
err = - EFAULT ;
break ;
}
for ( i = c > > 2 ; i - - ; ) {
2015-07-15 11:29:45 +03:00
fb_writel ( big_swap ( * src ) , dst + + ) ;
2015-01-19 11:11:00 +03:00
src + + ;
}
if ( c & 3 ) {
2015-01-19 11:11:04 +03:00
u8 * src8 = ( u8 * ) src ;
u8 __iomem * dst8 = ( u8 __iomem * ) dst ;
2015-01-19 11:11:00 +03:00
for ( i = c & 3 ; i - - ; ) {
if ( i & 1 ) {
fb_writeb ( * src8 + + , + + dst8 ) ;
} else {
fb_writeb ( * src8 + + , - - dst8 ) ;
dst8 + = 2 ;
}
}
2015-01-19 11:11:04 +03:00
dst = ( u32 __iomem * ) dst8 ;
2015-01-19 11:11:00 +03:00
}
* ppos + = c ;
buf + = c ;
cnt + = c ;
count - = c ;
}
kfree ( buffer ) ;
return ( cnt ) ? cnt : err ;
}
static void sm7xx_set_timing ( struct smtcfb_info * sfb )
{
int i = 0 , j = 0 ;
2015-02-03 17:53:34 +03:00
u32 m_nscreenstride ;
2015-01-19 11:11:00 +03:00
dev_dbg ( & sfb - > pdev - > dev ,
2015-04-23 16:38:16 +03:00
" sfb->width=%d sfb->height=%d sfb->fb->var.bits_per_pixel=%d sfb->hz=%d \n " ,
sfb - > width , sfb - > height , sfb - > fb - > var . bits_per_pixel , sfb - > hz ) ;
2015-01-19 11:11:00 +03:00
2015-06-17 14:24:41 +03:00
for ( j = 0 ; j < ARRAY_SIZE ( vgamode ) ; j + + ) {
2015-06-17 14:24:45 +03:00
if ( vgamode [ j ] . mmsizex ! = sfb - > width | |
vgamode [ j ] . mmsizey ! = sfb - > height | |
vgamode [ j ] . bpp ! = sfb - > fb - > var . bits_per_pixel | |
vgamode [ j ] . hz ! = sfb - > hz )
continue ;
dev_dbg ( & sfb - > pdev - > dev ,
" vgamode[j].mmsizex=%d vgamode[j].mmSizeY=%d vgamode[j].bpp=%d vgamode[j].hz=%d \n " ,
vgamode [ j ] . mmsizex , vgamode [ j ] . mmsizey ,
vgamode [ j ] . bpp , vgamode [ j ] . hz ) ;
dev_dbg ( & sfb - > pdev - > dev , " vgamode index=%d \n " , j ) ;
smtc_mmiowb ( 0x0 , 0x3c6 ) ;
smtc_seqw ( 0 , 0x1 ) ;
smtc_mmiowb ( vgamode [ j ] . init_misc , 0x3c2 ) ;
/* init SEQ register SR00 - SR04 */
for ( i = 0 ; i < SIZE_SR00_SR04 ; i + + )
smtc_seqw ( i , vgamode [ j ] . init_sr00_sr04 [ i ] ) ;
/* init SEQ register SR10 - SR24 */
for ( i = 0 ; i < SIZE_SR10_SR24 ; i + + )
smtc_seqw ( i + 0x10 , vgamode [ j ] . init_sr10_sr24 [ i ] ) ;
/* init SEQ register SR30 - SR75 */
for ( i = 0 ; i < SIZE_SR30_SR75 ; i + + )
if ( ( i + 0x30 ) ! = 0x62 & & ( i + 0x30 ) ! = 0x6a & &
( i + 0x30 ) ! = 0x6b )
smtc_seqw ( i + 0x30 ,
vgamode [ j ] . init_sr30_sr75 [ i ] ) ;
/* init SEQ register SR80 - SR93 */
for ( i = 0 ; i < SIZE_SR80_SR93 ; i + + )
smtc_seqw ( i + 0x80 , vgamode [ j ] . init_sr80_sr93 [ i ] ) ;
/* init SEQ register SRA0 - SRAF */
for ( i = 0 ; i < SIZE_SRA0_SRAF ; i + + )
smtc_seqw ( i + 0xa0 , vgamode [ j ] . init_sra0_sraf [ i ] ) ;
/* init Graphic register GR00 - GR08 */
for ( i = 0 ; i < SIZE_GR00_GR08 ; i + + )
smtc_grphw ( i , vgamode [ j ] . init_gr00_gr08 [ i ] ) ;
/* init Attribute register AR00 - AR14 */
for ( i = 0 ; i < SIZE_AR00_AR14 ; i + + )
smtc_attrw ( i , vgamode [ j ] . init_ar00_ar14 [ i ] ) ;
/* init CRTC register CR00 - CR18 */
for ( i = 0 ; i < SIZE_CR00_CR18 ; i + + )
smtc_crtcw ( i , vgamode [ j ] . init_cr00_cr18 [ i ] ) ;
/* init CRTC register CR30 - CR4D */
for ( i = 0 ; i < SIZE_CR30_CR4D ; i + + )
smtc_crtcw ( i + 0x30 , vgamode [ j ] . init_cr30_cr4d [ i ] ) ;
/* init CRTC register CR90 - CRA7 */
for ( i = 0 ; i < SIZE_CR90_CRA7 ; i + + )
smtc_crtcw ( i + 0x90 , vgamode [ j ] . init_cr90_cra7 [ i ] ) ;
2015-01-19 11:11:00 +03:00
}
smtc_mmiowb ( 0x67 , 0x3c2 ) ;
/* set VPR registers */
writel ( 0x0 , sfb - > vp_regs + 0x0C ) ;
writel ( 0x0 , sfb - > vp_regs + 0x40 ) ;
/* set data width */
2015-06-17 14:24:44 +03:00
m_nscreenstride = ( sfb - > width * sfb - > fb - > var . bits_per_pixel ) / 64 ;
2015-04-23 16:38:16 +03:00
switch ( sfb - > fb - > var . bits_per_pixel ) {
2015-01-19 11:11:00 +03:00
case 8 :
writel ( 0x0 , sfb - > vp_regs + 0x0 ) ;
break ;
case 16 :
writel ( 0x00020000 , sfb - > vp_regs + 0x0 ) ;
break ;
case 24 :
writel ( 0x00040000 , sfb - > vp_regs + 0x0 ) ;
break ;
case 32 :
writel ( 0x00030000 , sfb - > vp_regs + 0x0 ) ;
break ;
}
2015-06-17 14:24:43 +03:00
writel ( ( u32 ) ( ( ( m_nscreenstride + 2 ) < < 16 ) | m_nscreenstride ) ,
2015-01-19 11:11:00 +03:00
sfb - > vp_regs + 0x10 ) ;
}
static void smtc_set_timing ( struct smtcfb_info * sfb )
{
switch ( sfb - > chip_id ) {
case 0x710 :
case 0x712 :
case 0x720 :
sm7xx_set_timing ( sfb ) ;
break ;
}
}
static void smtcfb_setmode ( struct smtcfb_info * sfb )
{
2015-04-23 16:38:16 +03:00
switch ( sfb - > fb - > var . bits_per_pixel ) {
2015-01-19 11:11:00 +03:00
case 32 :
2015-04-23 16:38:16 +03:00
sfb - > fb - > fix . visual = FB_VISUAL_TRUECOLOR ;
sfb - > fb - > fix . line_length = sfb - > fb - > var . xres * 4 ;
sfb - > fb - > var . red . length = 8 ;
sfb - > fb - > var . green . length = 8 ;
sfb - > fb - > var . blue . length = 8 ;
sfb - > fb - > var . red . offset = 16 ;
sfb - > fb - > var . green . offset = 8 ;
sfb - > fb - > var . blue . offset = 0 ;
2015-01-19 11:11:00 +03:00
break ;
case 24 :
2015-04-23 16:38:16 +03:00
sfb - > fb - > fix . visual = FB_VISUAL_TRUECOLOR ;
sfb - > fb - > fix . line_length = sfb - > fb - > var . xres * 3 ;
sfb - > fb - > var . red . length = 8 ;
sfb - > fb - > var . green . length = 8 ;
sfb - > fb - > var . blue . length = 8 ;
sfb - > fb - > var . red . offset = 16 ;
sfb - > fb - > var . green . offset = 8 ;
sfb - > fb - > var . blue . offset = 0 ;
2015-01-19 11:11:00 +03:00
break ;
case 8 :
2015-04-23 16:38:16 +03:00
sfb - > fb - > fix . visual = FB_VISUAL_PSEUDOCOLOR ;
sfb - > fb - > fix . line_length = sfb - > fb - > var . xres ;
sfb - > fb - > var . red . length = 3 ;
sfb - > fb - > var . green . length = 3 ;
sfb - > fb - > var . blue . length = 2 ;
sfb - > fb - > var . red . offset = 5 ;
sfb - > fb - > var . green . offset = 2 ;
sfb - > fb - > var . blue . offset = 0 ;
2015-01-19 11:11:00 +03:00
break ;
case 16 :
default :
2015-04-23 16:38:16 +03:00
sfb - > fb - > fix . visual = FB_VISUAL_TRUECOLOR ;
sfb - > fb - > fix . line_length = sfb - > fb - > var . xres * 2 ;
sfb - > fb - > var . red . length = 5 ;
sfb - > fb - > var . green . length = 6 ;
sfb - > fb - > var . blue . length = 5 ;
sfb - > fb - > var . red . offset = 11 ;
sfb - > fb - > var . green . offset = 5 ;
sfb - > fb - > var . blue . offset = 0 ;
2015-01-19 11:11:00 +03:00
break ;
}
2015-04-23 16:38:16 +03:00
sfb - > width = sfb - > fb - > var . xres ;
sfb - > height = sfb - > fb - > var . yres ;
2015-01-19 11:11:00 +03:00
sfb - > hz = 60 ;
smtc_set_timing ( sfb ) ;
}
static int smtc_check_var ( struct fb_var_screeninfo * var , struct fb_info * info )
{
/* sanity checks */
if ( var - > xres_virtual < var - > xres )
var - > xres_virtual = var - > xres ;
if ( var - > yres_virtual < var - > yres )
var - > yres_virtual = var - > yres ;
/* set valid default bpp */
if ( ( var - > bits_per_pixel ! = 8 ) & & ( var - > bits_per_pixel ! = 16 ) & &
( var - > bits_per_pixel ! = 24 ) & & ( var - > bits_per_pixel ! = 32 ) )
var - > bits_per_pixel = 16 ;
return 0 ;
}
static int smtc_set_par ( struct fb_info * info )
{
smtcfb_setmode ( info - > par ) ;
return 0 ;
}
static struct fb_ops smtcfb_ops = {
. owner = THIS_MODULE ,
. fb_check_var = smtc_check_var ,
. fb_set_par = smtc_set_par ,
. fb_setcolreg = smtc_setcolreg ,
. fb_blank = smtc_blank ,
. fb_fillrect = cfb_fillrect ,
. fb_imageblit = cfb_imageblit ,
. fb_copyarea = cfb_copyarea ,
. fb_read = smtcfb_read ,
. fb_write = smtcfb_write ,
} ;
/*
* Unmap in the memory mapped IO registers
*/
static void smtc_unmap_mmio ( struct smtcfb_info * sfb )
{
2015-02-03 17:53:33 +03:00
if ( sfb & & smtc_regbaseaddress )
smtc_regbaseaddress = NULL ;
2015-01-19 11:11:00 +03:00
}
/*
* Map in the screen memory
*/
static int smtc_map_smem ( struct smtcfb_info * sfb ,
2015-01-19 11:11:06 +03:00
struct pci_dev * pdev , u_long smem_len )
2015-01-19 11:11:00 +03:00
{
2015-04-23 16:38:16 +03:00
sfb - > fb - > fix . smem_start = pci_resource_start ( pdev , 0 ) ;
2015-01-19 11:11:00 +03:00
2015-04-23 16:38:16 +03:00
if ( sfb - > fb - > var . bits_per_pixel = = 32 )
2015-07-15 11:29:45 +03:00
sfb - > fb - > fix . smem_start + = big_addr ;
2015-01-19 11:11:00 +03:00
2015-04-23 16:38:16 +03:00
sfb - > fb - > fix . smem_len = smem_len ;
2015-01-19 11:11:00 +03:00
2015-04-23 16:38:16 +03:00
sfb - > fb - > screen_base = sfb - > lfb ;
2015-01-19 11:11:00 +03:00
2015-04-23 16:38:16 +03:00
if ( ! sfb - > fb - > screen_base ) {
2015-01-19 11:11:00 +03:00
dev_err ( & pdev - > dev ,
2015-04-23 16:38:16 +03:00
" %s: unable to map screen memory \n " , sfb - > fb - > fix . id ) ;
2015-01-19 11:11:00 +03:00
return - ENOMEM ;
}
return 0 ;
}
/*
* Unmap in the screen memory
*
*/
static void smtc_unmap_smem ( struct smtcfb_info * sfb )
{
2015-04-23 16:38:16 +03:00
if ( sfb & & sfb - > fb - > screen_base ) {
iounmap ( sfb - > fb - > screen_base ) ;
sfb - > fb - > screen_base = NULL ;
2015-01-19 11:11:00 +03:00
}
}
/*
* We need to wake up the device and make sure its in linear memory mode .
*/
static inline void sm7xx_init_hw ( void )
{
outb_p ( 0x18 , 0x3c4 ) ;
outb_p ( 0x11 , 0x3c5 ) ;
}
static int smtcfb_pci_probe ( struct pci_dev * pdev ,
2015-01-19 11:11:06 +03:00
const struct pci_device_id * ent )
2015-01-19 11:11:00 +03:00
{
struct smtcfb_info * sfb ;
2015-04-23 16:38:16 +03:00
struct fb_info * info ;
2015-01-19 11:11:00 +03:00
u_long smem_size = 0x00800000 ; /* default 8MB */
int err ;
unsigned long mmio_base ;
2015-06-17 14:24:42 +03:00
dev_info ( & pdev - > dev , " Silicon Motion display driver. \n " ) ;
2015-01-19 11:11:00 +03:00
err = pci_enable_device ( pdev ) ; /* enable SMTC chip */
if ( err )
return err ;
2015-03-28 12:03:40 +03:00
err = pci_request_region ( pdev , 0 , " sm7xxfb " ) ;
if ( err < 0 ) {
dev_err ( & pdev - > dev , " cannot reserve framebuffer region \n " ) ;
goto failed_regions ;
}
2015-01-19 11:11:00 +03:00
sprintf ( smtcfb_fix . id , " sm%Xfb " , ent - > device ) ;
2015-04-23 16:38:16 +03:00
info = framebuffer_alloc ( sizeof ( * sfb ) , & pdev - > dev ) ;
if ( ! info ) {
dev_err ( & pdev - > dev , " framebuffer_alloc failed \n " ) ;
2015-01-19 11:11:00 +03:00
err = - ENOMEM ;
goto failed_free ;
}
2015-04-23 16:38:16 +03:00
sfb = info - > par ;
sfb - > fb = info ;
2015-01-19 11:11:00 +03:00
sfb - > chip_id = ent - > device ;
2015-04-23 16:38:16 +03:00
sfb - > pdev = pdev ;
info - > flags = FBINFO_FLAG_DEFAULT ;
info - > fbops = & smtcfb_ops ;
info - > fix = smtcfb_fix ;
info - > var = smtcfb_var ;
info - > pseudo_palette = sfb - > colreg ;
info - > par = sfb ;
2015-01-19 11:11:00 +03:00
pci_set_drvdata ( pdev , sfb ) ;
sm7xx_init_hw ( ) ;
/* get mode parameter from smtc_scr_info */
if ( smtc_scr_info . lfb_width ! = 0 ) {
2015-04-23 16:38:16 +03:00
sfb - > fb - > var . xres = smtc_scr_info . lfb_width ;
sfb - > fb - > var . yres = smtc_scr_info . lfb_height ;
sfb - > fb - > var . bits_per_pixel = smtc_scr_info . lfb_depth ;
2015-01-19 11:11:00 +03:00
} else {
/* default resolution 1024x600 16bit mode */
2015-04-23 16:38:16 +03:00
sfb - > fb - > var . xres = SCREEN_X_RES ;
sfb - > fb - > var . yres = SCREEN_Y_RES ;
sfb - > fb - > var . bits_per_pixel = SCREEN_BPP ;
2015-01-19 11:11:00 +03:00
}
2015-07-15 11:29:45 +03:00
big_pixel_depth ( sfb - > fb - > var . bits_per_pixel , smtc_scr_info . lfb_depth ) ;
2015-01-19 11:11:00 +03:00
/* Map address and memory detection */
mmio_base = pci_resource_start ( pdev , 0 ) ;
pci_read_config_byte ( pdev , PCI_REVISION_ID , & sfb - > chip_rev_id ) ;
switch ( sfb - > chip_id ) {
case 0x710 :
case 0x712 :
2015-04-23 16:38:16 +03:00
sfb - > fb - > fix . mmio_start = mmio_base + 0x00400000 ;
sfb - > fb - > fix . mmio_len = 0x00400000 ;
2015-01-19 11:11:00 +03:00
smem_size = SM712_VIDEOMEMORYSIZE ;
2015-07-15 11:29:45 +03:00
sfb - > lfb = ioremap ( mmio_base , mmio_addr ) ;
2015-07-07 11:14:34 +03:00
if ( ! sfb - > lfb ) {
dev_err ( & pdev - > dev ,
" %s: unable to map memory mapped IO! \n " ,
sfb - > fb - > fix . id ) ;
err = - ENOMEM ;
goto failed_fb ;
}
2015-02-03 17:53:33 +03:00
sfb - > mmio = ( smtc_regbaseaddress =
2015-01-19 11:11:00 +03:00
sfb - > lfb + 0x00700000 ) ;
sfb - > dp_regs = sfb - > lfb + 0x00408000 ;
sfb - > vp_regs = sfb - > lfb + 0x0040c000 ;
2015-04-23 16:38:16 +03:00
if ( sfb - > fb - > var . bits_per_pixel = = 32 ) {
2015-07-15 11:29:45 +03:00
sfb - > lfb + = big_addr ;
2015-06-17 14:24:42 +03:00
dev_info ( & pdev - > dev , " sfb->lfb=%p \n " , sfb - > lfb ) ;
2015-01-19 11:11:00 +03:00
}
/* set MCLK = 14.31818 * (0x16 / 0x2) */
smtc_seqw ( 0x6a , 0x16 ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
smtc_seqw ( 0x62 , 0x3e ) ;
/* enable PCI burst */
smtc_seqw ( 0x17 , 0x20 ) ;
/* enable word swap */
2015-04-23 16:38:16 +03:00
if ( sfb - > fb - > var . bits_per_pixel = = 32 )
2015-07-15 11:29:45 +03:00
seqw17 ( ) ;
2015-01-19 11:11:00 +03:00
break ;
case 0x720 :
2015-04-23 16:38:16 +03:00
sfb - > fb - > fix . mmio_start = mmio_base ;
sfb - > fb - > fix . mmio_len = 0x00200000 ;
2015-01-19 11:11:00 +03:00
smem_size = SM722_VIDEOMEMORYSIZE ;
sfb - > dp_regs = ioremap ( mmio_base , 0x00a00000 ) ;
sfb - > lfb = sfb - > dp_regs + 0x00200000 ;
2015-02-03 17:53:33 +03:00
sfb - > mmio = ( smtc_regbaseaddress =
2015-01-19 11:11:00 +03:00
sfb - > dp_regs + 0x000c0000 ) ;
sfb - > vp_regs = sfb - > dp_regs + 0x800 ;
smtc_seqw ( 0x62 , 0xff ) ;
smtc_seqw ( 0x6a , 0x0d ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
break ;
default :
dev_err ( & pdev - > dev ,
2015-06-17 14:24:42 +03:00
" No valid Silicon Motion display chip was detected! \n " ) ;
2015-01-19 11:11:00 +03:00
goto failed_fb ;
}
/* can support 32 bpp */
2017-08-01 18:20:38 +03:00
if ( sfb - > fb - > var . bits_per_pixel = = 15 )
2015-04-23 16:38:16 +03:00
sfb - > fb - > var . bits_per_pixel = 16 ;
2015-01-19 11:11:00 +03:00
2015-04-23 16:38:16 +03:00
sfb - > fb - > var . xres_virtual = sfb - > fb - > var . xres ;
sfb - > fb - > var . yres_virtual = sfb - > fb - > var . yres ;
2015-01-19 11:11:00 +03:00
err = smtc_map_smem ( sfb , pdev , smem_size ) ;
if ( err )
goto failed ;
smtcfb_setmode ( sfb ) ;
2015-04-23 16:38:16 +03:00
err = register_framebuffer ( info ) ;
2015-01-19 11:11:00 +03:00
if ( err < 0 )
goto failed ;
dev_info ( & pdev - > dev ,
2015-06-17 14:24:42 +03:00
" Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete. \n " ,
2015-04-23 16:38:16 +03:00
sfb - > chip_id , sfb - > chip_rev_id , sfb - > fb - > var . xres ,
sfb - > fb - > var . yres , sfb - > fb - > var . bits_per_pixel ) ;
2015-01-19 11:11:00 +03:00
return 0 ;
failed :
2015-06-17 14:24:42 +03:00
dev_err ( & pdev - > dev , " Silicon Motion, Inc. primary display init fail. \n " ) ;
2015-01-19 11:11:00 +03:00
smtc_unmap_smem ( sfb ) ;
smtc_unmap_mmio ( sfb ) ;
failed_fb :
2015-04-23 16:38:16 +03:00
framebuffer_release ( info ) ;
2015-01-19 11:11:00 +03:00
failed_free :
2015-03-28 12:03:40 +03:00
pci_release_region ( pdev , 0 ) ;
failed_regions :
2015-01-19 11:11:00 +03:00
pci_disable_device ( pdev ) ;
return err ;
}
/*
* 0x710 ( LynxEM )
* 0x712 ( LynxEM + )
* 0x720 ( Lynx3DM , Lynx3DM + )
*/
static const struct pci_device_id smtcfb_pci_table [ ] = {
{ PCI_DEVICE ( 0x126f , 0x710 ) , } ,
{ PCI_DEVICE ( 0x126f , 0x712 ) , } ,
{ PCI_DEVICE ( 0x126f , 0x720 ) , } ,
{ 0 , }
} ;
2015-03-24 13:52:24 +03:00
MODULE_DEVICE_TABLE ( pci , smtcfb_pci_table ) ;
2015-01-19 11:11:00 +03:00
static void smtcfb_pci_remove ( struct pci_dev * pdev )
{
struct smtcfb_info * sfb ;
sfb = pci_get_drvdata ( pdev ) ;
smtc_unmap_smem ( sfb ) ;
smtc_unmap_mmio ( sfb ) ;
2015-04-23 16:38:16 +03:00
unregister_framebuffer ( sfb - > fb ) ;
framebuffer_release ( sfb - > fb ) ;
2015-03-28 12:03:40 +03:00
pci_release_region ( pdev , 0 ) ;
2015-03-28 12:03:41 +03:00
pci_disable_device ( pdev ) ;
2015-01-19 11:11:00 +03:00
}
2015-11-21 00:48:36 +03:00
static int __maybe_unused smtcfb_pci_suspend ( struct device * device )
2015-01-19 11:11:00 +03:00
{
struct pci_dev * pdev = to_pci_dev ( device ) ;
struct smtcfb_info * sfb ;
sfb = pci_get_drvdata ( pdev ) ;
/* set the hw in sleep mode use external clock and self memory refresh
* so that we can turn off internal PLLs later on
*/
smtc_seqw ( 0x20 , ( smtc_seqr ( 0x20 ) | 0xc0 ) ) ;
smtc_seqw ( 0x69 , ( smtc_seqr ( 0x69 ) & 0xf7 ) ) ;
console_lock ( ) ;
2015-04-23 16:38:16 +03:00
fb_set_suspend ( sfb - > fb , 1 ) ;
2015-01-19 11:11:00 +03:00
console_unlock ( ) ;
/* additionally turn off all function blocks including internal PLLs */
smtc_seqw ( 0x21 , 0xff ) ;
return 0 ;
}
2015-11-21 00:48:36 +03:00
static int __maybe_unused smtcfb_pci_resume ( struct device * device )
2015-01-19 11:11:00 +03:00
{
struct pci_dev * pdev = to_pci_dev ( device ) ;
struct smtcfb_info * sfb ;
sfb = pci_get_drvdata ( pdev ) ;
/* reinit hardware */
sm7xx_init_hw ( ) ;
switch ( sfb - > chip_id ) {
case 0x710 :
case 0x712 :
/* set MCLK = 14.31818 * (0x16 / 0x2) */
smtc_seqw ( 0x6a , 0x16 ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
smtc_seqw ( 0x62 , 0x3e ) ;
/* enable PCI burst */
smtc_seqw ( 0x17 , 0x20 ) ;
2015-04-23 16:38:16 +03:00
if ( sfb - > fb - > var . bits_per_pixel = = 32 )
2015-07-15 11:29:45 +03:00
seqw17 ( ) ;
2015-01-19 11:11:00 +03:00
break ;
case 0x720 :
smtc_seqw ( 0x62 , 0xff ) ;
smtc_seqw ( 0x6a , 0x0d ) ;
smtc_seqw ( 0x6b , 0x02 ) ;
break ;
}
smtc_seqw ( 0x34 , ( smtc_seqr ( 0x34 ) | 0xc0 ) ) ;
smtc_seqw ( 0x33 , ( ( smtc_seqr ( 0x33 ) | 0x08 ) & 0xfb ) ) ;
smtcfb_setmode ( sfb ) ;
console_lock ( ) ;
2015-04-23 16:38:16 +03:00
fb_set_suspend ( sfb - > fb , 0 ) ;
2015-01-19 11:11:00 +03:00
console_unlock ( ) ;
return 0 ;
}
static SIMPLE_DEV_PM_OPS ( sm7xx_pm_ops , smtcfb_pci_suspend , smtcfb_pci_resume ) ;
static struct pci_driver smtcfb_driver = {
. name = " smtcfb " ,
. id_table = smtcfb_pci_table ,
. probe = smtcfb_pci_probe ,
. remove = smtcfb_pci_remove ,
2015-11-21 00:48:36 +03:00
. driver . pm = & sm7xx_pm_ops ,
2015-01-19 11:11:00 +03:00
} ;
2015-03-08 20:40:09 +03:00
static int __init sm712fb_init ( void )
{
char * option = NULL ;
if ( fb_get_options ( " sm712fb " , & option ) )
return - ENODEV ;
if ( option & & * option )
mode_option = option ;
sm7xx_vga_setup ( mode_option ) ;
return pci_register_driver ( & smtcfb_driver ) ;
}
module_init ( sm712fb_init ) ;
static void __exit sm712fb_exit ( void )
{
pci_unregister_driver ( & smtcfb_driver ) ;
}
module_exit ( sm712fb_exit ) ;
2015-01-19 11:11:00 +03:00
MODULE_AUTHOR ( " Siliconmotion " ) ;
MODULE_DESCRIPTION ( " Framebuffer driver for SMI Graphic Cards " ) ;
MODULE_LICENSE ( " GPL " ) ;