/*
* 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>
#ifdef CONFIG_PM
#include <linux/pm.h>
#endif
#include "smtcfb.h"
struct screen_info smtc_screen_info;
/*
* Private structure
*/
struct smtcfb_info {
struct fb_info fb;
struct pci_dev *pdev;
struct {
u8 red, green, blue;
} palette[NR_RGB];
u_int palette_size;
u16 chipID;
unsigned char __iomem *m_pMMIO;
char __iomem *m_pLFB;
char *m_pDPR;
char *m_pVPR;
char *m_pCPR;
u_int width;
u_int height;
u_int hz;
u_long BaseAddressInVRAM;
u8 chipRevID;
};
struct vesa_mode_table {
char mode_index[6];
u16 lfb_width;
u16 lfb_height;
u16 lfb_depth;
};
static struct vesa_mode_table vesa_mode[] = {
{"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},
};
char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */
static u32 colreg[17];
static struct fb_var_screeninfo smtcfb_var = {
.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,
};
static struct fb_fix_screeninfo smtcfb_fix = {
.id = "sm712fb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
.line_length = 800 * 3,
.accel = FB_ACCEL_SMI_LYNX,
};
static void sm712_set_timing(struct smtcfb_info *sfb)
{
int i = 0, j = 0;
u32 m_nScreenStride;
dev_dbg(&sfb->pdev->dev,
"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);
for (j = 0; j < numVGAModes; j++) {
if (VGAMode[j].mmSizeX