diff options
author | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-05-01 07:00:17 +0000 |
---|---|---|
committer | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-05-01 07:00:17 +0000 |
commit | 7e7649baa9de9d592a76e150970e3079d7610138 (patch) | |
tree | 7e3c3b52269e3c7564c6a88d67dc4ea6219b041c /target/linux/coldfire/patches/038-Add-PCI-Framebuffer-support-for-Silicon-Motion-s-Lyn.patch | |
parent | 7877ca154f130fe0c83a5f151320c3ce902195d1 (diff) |
[coldfire]: switch to 2.6.38
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31546 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/coldfire/patches/038-Add-PCI-Framebuffer-support-for-Silicon-Motion-s-Lyn.patch')
-rw-r--r-- | target/linux/coldfire/patches/038-Add-PCI-Framebuffer-support-for-Silicon-Motion-s-Lyn.patch | 1287 |
1 files changed, 1287 insertions, 0 deletions
diff --git a/target/linux/coldfire/patches/038-Add-PCI-Framebuffer-support-for-Silicon-Motion-s-Lyn.patch b/target/linux/coldfire/patches/038-Add-PCI-Framebuffer-support-for-Silicon-Motion-s-Lyn.patch new file mode 100644 index 0000000000..bd0462926a --- /dev/null +++ b/target/linux/coldfire/patches/038-Add-PCI-Framebuffer-support-for-Silicon-Motion-s-Lyn.patch @@ -0,0 +1,1287 @@ +From d984818481320cf4a1b44cefbc99448205cc7673 Mon Sep 17 00:00:00 2001 +From: Jingchang Lu <b35083@freescale.com> +Date: Thu, 4 Aug 2011 09:59:48 +0800 +Subject: [PATCH 38/52] Add PCI Framebuffer support for Silicon Motion's Lynx family + +The driver may support SM710, SM712, SM720, and the SM712 +has been tested on ColdFire M547X_8XEVB. + +Signed-off-by: Alison Wang <b18965@freescale.com> +Signed-off-by: Jingchang Lu <b35083@freescale.com> +--- + drivers/video/Kconfig | 15 + + drivers/video/Makefile | 1 + + drivers/video/console/bitblit.c | 12 + + drivers/video/console/fbcon.c | 4 + + drivers/video/fbmem.c | 2 +- + drivers/video/smifb.c | 963 +++++++++++++++++++++++++++++++++++++++ + drivers/video/smifb.h | 150 ++++++ + include/linux/fb.h | 18 +- + 8 files changed, 1163 insertions(+), 2 deletions(-) + create mode 100644 drivers/video/smifb.c + create mode 100644 drivers/video/smifb.h + +--- a/drivers/video/Kconfig ++++ b/drivers/video/Kconfig +@@ -204,6 +204,7 @@ config FB_WMT_GE_ROPS + config FB_DEFERRED_IO + bool + depends on FB ++ default y + + config FB_HECUBA + tristate +@@ -262,6 +263,20 @@ config FB_TILEBLITTING + comment "Frame buffer hardware drivers" + depends on FB + ++config FB_SMI ++ tristate "Silicon Motion Lynx support" ++ depends on FB && PCI ++ select FB_CFB_FILLRECT ++ select FB_CFB_COPYAREA ++ select FB_CFB_IMAGEBLIT ++ ---help--- ++ This enables support for the Silicon Motion Lynx family of graphic ++ chips. ++ ++ The SM712 has been tested on ColdFire M547X_8Xevb. ++ ++ If unsure, say N. ++ + config FB_CIRRUS + tristate "Cirrus Logic support" + depends on FB && (ZORRO || PCI) +--- a/drivers/video/Makefile ++++ b/drivers/video/Makefile +@@ -29,6 +29,7 @@ obj-$(CONFIG_FB_DEFERRED_IO) += fb_def + obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o + + # Hardware specific drivers go first ++obj-$(CONFIG_FB_SMI) += smifb.o + obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o + obj-$(CONFIG_FB_ARC) += arcfb.o + obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o +--- a/drivers/video/console/bitblit.c ++++ b/drivers/video/console/bitblit.c +@@ -79,7 +79,11 @@ static inline void bit_putcs_aligned(str + u32 d_pitch, u32 s_pitch, u32 cellsize, + struct fb_image *image, u8 *buf, u8 *dst) + { ++#ifndef CONFIG_COLDFIRE + u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; ++#else ++ u32 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; ++#endif + u32 idx = vc->vc_font.width >> 3; + u8 *src; + +@@ -112,7 +116,11 @@ static inline void bit_putcs_unaligned(s + struct fb_image *image, u8 *buf, + u8 *dst) + { ++#ifndef CONFIG_COLDFIRE + u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; ++#else ++ u32 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; ++#endif + u32 shift_low = 0, mod = vc->vc_font.width % 8; + u32 shift_high = 8; + u32 idx = vc->vc_font.width >> 3; +@@ -239,7 +247,11 @@ static void bit_cursor(struct vc_data *v + { + struct fb_cursor cursor; + struct fbcon_ops *ops = info->fbcon_par; ++#ifndef CONFIG_COLDFIRE + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; ++#else ++ unsigned long charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; ++#endif + int w = DIV_ROUND_UP(vc->vc_font.width, 8), c; + int y = real_y(ops->p, vc->vc_y); + int attribute, use_sw = (vc->vc_cursor_type & 0x10); +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -2636,7 +2636,11 @@ static int fbcon_set_palette(struct vc_d + { + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + int i, j, k, depth; ++#ifndef CONFIG_COLDFIRE + u8 val; ++#else ++ u32 val; ++#endif + + if (fbcon_is_inactive(vc, info)) + return -EINVAL; +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -1433,7 +1433,7 @@ static int fb_check_foreignness(struct f + + fi->flags &= ~FBINFO_FOREIGN_ENDIAN; + +-#ifdef __BIG_ENDIAN ++#if defined(__BIG_ENDIAN) && !defined(CONFIG_COLDFIRE) + fi->flags |= foreign_endian ? 0 : FBINFO_BE_MATH; + #else + fi->flags |= foreign_endian ? FBINFO_BE_MATH : 0; +--- /dev/null ++++ b/drivers/video/smifb.c +@@ -0,0 +1,963 @@ ++/*************************************************************************** ++ smifb.c - Silicon Motion, Inc. LynxEM+ frame buffer device ++ ------------------- ++ begin : Thu Aug 9 2001 ++ copyright : (C) 2001 by Szu-Tao Huang ++ email : johuang@siliconmotion.com ++ ***************************************************************************/ ++/* Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.*/ ++/*************************************************************************** ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ ***************************************************************************/ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/errno.h> ++#include <linux/string.h> ++#include <linux/mm.h> ++#include <linux/tty.h> ++#include <linux/slab.h> ++#include <linux/delay.h> ++#include <linux/fb.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++ ++#include <linux/io.h> ++#include <asm/irq.h> ++#include <asm/pgtable.h> ++#include <asm/system.h> ++#include <linux/uaccess.h> ++ ++#include "console/fbcon.h" ++ ++/* ++#include <video/fbcon.h> ++#include <video/fbcon-cfb8.h> ++#include <video/fbcon-cfb16.h> ++#include <video/fbcon-cfb24.h> ++*/ ++ ++#include <linux/fb.h> ++/*point to virtual Memory Map IO starting address*/ ++static char *SMIRegs; ++/*point to virtual video memory starting address*/ ++static char *SMILFB; ++/*used to record hardware information*/ ++static struct par_info hw; ++#ifdef DEBUG_FB ++#define debug_printk(x...) printk(x) ++#else ++#define debug_printk(x...) ++#endif ++#include "smifb.h" ++ ++struct ModeInit VGAMode[numVGAModes] = { ++ { ++ /* mode#0: 640 x 480 8Bpp 60Hz */ ++ 640, 480, 8, 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, ++ }, ++ }, ++ { ++ /* mode#1: 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, ++ }, ++ }, ++ { ++ /* mode#2: 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, ++ }, ++ }, ++ {/* mode#3: 800 x 600 8Bpp 60Hz */ ++ 800, 600, 8, 60, ++ 0x2B, /* Init_MISC */ ++ { /* 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 */ ++ 0x24, 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 */ ++ 0xFF, 0x87, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, ++ 0x90, 0x01, 0x2C, 0x01, 0xFF, 0x00, 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#4: 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 */ ++ 0x24, 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#5: 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, ++ }, ++ }, ++}; ++ ++static void smi_set_timing(struct smifb_info *sfb, struct par_info *hw) ++{ ++ int i = 0, j = 0; ++ u32 m_nScreenStride; ++ debug_printk("set timing:hw->width %x,hw->height %x,bpp %x\n", ++ hw->width, hw->height, sfb->fb.var.bits_per_pixel); ++ ++ for (j = 0; j < numVGAModes; j++) { ++ if (VGAMode[j].mmSizeX == hw->width && ++ VGAMode[j].mmSizeY == hw->height && ++ VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && ++ VGAMode[j].hz == hw->hz) { ++ debug_printk("VGAMode[%d]\n", j); ++ smi_mmiowb(0x0, 0x3c6); ++ ++ smi_seqw(0, 0x1); ++ ++ smi_mmiowb(VGAMode[j].Init_MISC, 0x3c2); ++ ++ for (i = 0; i < SIZE_SR00_SR04; i++) { ++ /* init SEQ register SR00 - SR04 */ ++ smi_seqw(i, ++ VGAMode[j].Init_SR00_SR04[i]); ++ } ++ ++ for (i = 0; i < SIZE_SR10_SR24; i++) { ++ /* init SEQ register SR10 - SR24*/ ++ smi_seqw(i + 0x10, ++ VGAMode[j].Init_SR10_SR24[i]); ++ } ++ ++ for (i = 0; i < SIZE_SR30_SR75; i++) { ++ /* init SEQ register SR30 - SR75*/ ++ if (((i + 0x30) != 0x62) && ++ ((i + 0x30) != 0x6a) && ++ ((i + 0x30) != 0x6b)) ++ smi_seqw(i + 0x30, ++ VGAMode[j].Init_SR30_SR75[i]); ++ } ++ for (i = 0; i < SIZE_SR80_SR93; i++) { ++ /* init SEQ register SR80 - SR93*/ ++ smi_seqw(i + 0x80, ++ VGAMode[j].Init_SR80_SR93[i]); ++ } ++ for (i = 0; i < SIZE_SRA0_SRAF; i++) { ++ /* init SEQ register SRA0 - SRAF */ ++ smi_seqw(i + 0xa0, ++ VGAMode[j].Init_SRA0_SRAF[i]); ++ } ++ ++ for (i = 0; i < SIZE_GR00_GR08; i++) { ++ /* init Graphic register GR00 - GR08*/ ++ smi_grphw(i, ++ VGAMode[j].Init_GR00_GR08[i]); ++ } ++ ++ for (i = 0; i < SIZE_AR00_AR14; i++) { ++ /* init Attribute register AR00 - AR14*/ ++ smi_attrw(i, ++ VGAMode[j].Init_AR00_AR14[i]); ++ } ++ ++ for (i = 0; i < SIZE_CR00_CR18; i++) { ++ /* init CRTC register CR00 - CR18 */ ++ smi_crtcw(i, ++ VGAMode[j].Init_CR00_CR18[i]); ++ } ++ ++ for (i = 0; i < SIZE_CR30_CR4D; i++) { ++ /* init CRTC register CR30 - CR4D*/ ++ smi_crtcw(i + 0x30, ++ VGAMode[j].Init_CR30_CR4D[i]); ++ } ++ ++ for (i = 0; i < SIZE_CR90_CRA7; i++) { ++ /*init CRTC register CR90 - CRA7*/ ++ smi_crtcw(i + 0x90, ++ VGAMode[j].Init_CR90_CRA7[i]); ++ } ++ } ++ } ++ smi_mmiowb(0x67, 0x3c2); ++ /* set VPR registers */ ++ writel(0x0, hw->m_pVPR+0x0C); ++ writel(0x0, hw->m_pVPR+0x40); ++ /* set data width */ ++ m_nScreenStride = (hw->width * sfb->fb.var.bits_per_pixel) / 64; ++ switch (sfb->fb.var.bits_per_pixel) { ++ case 8: ++ writel(0x0, hw->m_pVPR+0x0); ++ break; ++ case 16: ++ writel(0x00020000, hw->m_pVPR+0x0); ++ break; ++ case 24: ++ writel(0x00040000, hw->m_pVPR+0x0); ++ break; ++ } ++ writel((u32)(((m_nScreenStride + 2) << 16) | ++ m_nScreenStride), hw->m_pVPR+0x10); ++} ++ ++/* ++ * Set the color palette ++ */ ++static int ++smifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ++ u_int trans, struct fb_info *info) ++{ ++ struct smifb_info *sfb = (struct smifb_info *)info; ++ u32 *pal; ++ ++ switch (sfb->fb.fix.visual) { ++ case FB_VISUAL_TRUECOLOR: /* RGB 5:6:5 True Colour */ ++ pal = sfb->fb.pseudo_palette; ++ /* System has 16 default color */ ++ if (regno >= 16) ++ return 1; ++ ++ pal[regno] = (red & 0xf800) | ++ ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); ++ break; ++ } ++ ++ return 0; ++} ++ ++/* ++ * smifb_decode_var(): ++ * Get the video params out of 'var'. If a value doesn't fit, round it up, ++ * if it's too big, return -EINVAL. ++ * ++ * Suggestion: Round up in the following order: bits_per_pixel, xres, ++ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, ++ * bitfields, horizontal timing, vertical timing. ++ */ ++static int smifb_decode_var(struct fb_var_screeninfo *var, ++ struct smifb_info *sfb, struct par_info *hw) ++{ ++ hw->width = var->xres; ++ hw->height = var->yres; ++ hw->hz = 60; ++ ++ return 0; ++} ++ ++static int smifb_set_par(struct fb_info *info) ++{ ++ struct smifb_info *sfb = (struct smifb_info *)info; ++ int err, chgvar = 0; ++ struct fb_var_screeninfo *var = &info->var; ++ struct fb_cmap *cmap; ++ ++ ++ /* ++ * Decode var contents into a par structure, adjusting any ++ * out of range values. ++ */ ++ err = smifb_decode_var(var, sfb, &hw); ++ if (err) ++ return err; ++ ++ if (hw.width != var->xres) ++ chgvar = 1; ++ if (hw.height != var->yres) ++ chgvar = 1; ++ ++ var->activate &= ~FB_ACTIVATE_ALL; ++ ++ smi_set_timing(sfb, &hw); ++ ++ sfb->palette_size = var->bits_per_pixel == 8 ? 256 : 16; ++ cmap = (struct fb_cmap *)fb_default_cmap(sfb->palette_size); ++ fb_set_cmap(cmap, &sfb->fb); ++ ++ return 0; ++} ++ ++static int smifb_check_var(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ var->bits_per_pixel += 7; ++ var->bits_per_pixel &= ~7; ++ ++ var->xres_virtual = ++ var->xres_virtual < var->xres ? var->xres : var->xres_virtual; ++ var->yres_virtual = ++ var->yres_virtual < var->yres ? var->yres : var->yres_virtual; ++ debug_printk("var->bits_per_pixel %x\n", var->bits_per_pixel); ++ switch (var->bits_per_pixel) { ++ case 8: ++ case 16: /* RGB 565 */ ++ case 24: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ switch (var->bits_per_pixel) { ++ case 16: ++ var->red.offset = 11; ++ var->red.length = 5; ++ var->green.offset = 5; ++ var->green.length = 6; ++ var->blue.offset = 0; ++ var->blue.length = 5; ++ ++ info->fix.visual = FB_VISUAL_TRUECOLOR; ++ info->fix.line_length = var->xres * 2; ++ ++ break; ++ default: ++ return -EINVAL; ++ /* We don't support anything other than 16bpp for now. --NL */ ++ break; ++ } ++ return 0; ++ ++ /*smifb_set_color_bitfields(var);*/ ++ ++ return 0; ++} ++ ++/* ++ * Formal definition of the VESA spec: ++ * On ++ * This refers to the state of the display when it is in full operation ++ * Stand-By ++ * This defines an optional operating state of minimal power reduction with ++ * the shortest recovery time ++ * Suspend ++ * This refers to a level of power management in which substantial power ++ * reduction is achieved by the display. The display can have a longer ++ * recovery time from this state than from the Stand-by state ++ * Off ++ * This indicates that the display is consuming the lowest level of power ++ * and is non-operational. Recovery from this state may optionally require ++ * the user to manually power on the monitor ++ * ++ * Now, the fbdev driver adds an additional state, (blank), where they ++ * turn off the video (maybe by colormap tricks), but don't mess with the ++ * video itself: think of it semantically between on and Stand-By. ++ * ++ * So here's what we should do in our fbdev blank routine: ++ * ++ * VESA_NO_BLANKING (mode 0) Video on, front/back light on ++ * VESA_VSYNC_SUSPEND (mode 1) Video on, front/back light off ++ * VESA_HSYNC_SUSPEND (mode 2) Video on, front/back light off ++ * VESA_POWERDOWN (mode 3) Video off, front/back light off ++ * ++ * This will match the matrox implementation. ++ */ ++/* ++ * smifb_blank(): ++ * Blank the display by setting all palette values to zero. Note, the ++ * 12 and 16 bpp modes don't really use the palette, so this will not ++ * blank the display in all modes. ++ */ ++static int smifb_blank(int blank, struct fb_info *info) ++{ ++/* struct smifb_info *sfb = (struct smifb_info *)info; */ ++#if 0 ++ switch (blank) { ++ case VESA_POWERDOWN: ++ case VESA_VSYNC_SUSPEND: ++ case VESA_HSYNC_SUSPEND: ++ case VESA_NO_BLANKING: ++ } ++#endif ++ return 1; ++} ++ ++static struct fb_ops smifb_ops = { ++ .owner = THIS_MODULE, ++ .fb_check_var = smifb_check_var, ++ .fb_set_par = smifb_set_par, ++ .fb_setcolreg = smifb_setcolreg, ++ .fb_blank = smifb_blank, ++ ++ /* Accelerated functions, using softversions, per se */ ++ .fb_fillrect = cfb_fillrect, ++ .fb_copyarea = cfb_copyarea, ++ .fb_imageblit = cfb_imageblit, ++ .fb_cursor = soft_cursor, ++}; ++ ++/* ++ * Alloc struct smifb_info and assign the default value ++ */ ++static struct smifb_info * __devinit ++smi_alloc_fb_info(struct pci_dev *dev, char *name) ++{ ++ struct smifb_info *sfb; ++ ++ sfb = kmalloc(sizeof(struct smifb_info) + sizeof(u32) * 16, GFP_KERNEL); ++ ++ if (!sfb) ++ return NULL; ++ ++ memset(sfb, 0, sizeof(struct smifb_info)); ++ ++ sfb->currcon = -1; ++ sfb->dev = dev; ++ ++ strcpy(sfb->fb.fix.id, name); ++ ++ sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; ++ sfb->fb.fix.type_aux = 0; ++ sfb->fb.fix.xpanstep = 0; ++ sfb->fb.fix.ypanstep = 0; ++ sfb->fb.fix.ywrapstep = 0; ++ sfb->fb.fix.accel = FB_ACCEL_NONE; ++ ++ sfb->fb.var.nonstd = 0; ++ sfb->fb.var.activate = FB_ACTIVATE_NOW; ++ sfb->fb.var.height = -1; ++ sfb->fb.var.width = -1; ++ sfb->fb.var.accel_flags = 0; ++ sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; ++ ++ sfb->fb.fbops = &smifb_ops; ++ sfb->fb.flags = FBINFO_FLAG_DEFAULT; ++ sfb->fb.node = -1; ++ sfb->fb.pseudo_palette = (void *)(&sfb->palette_size + 1); ++ ++ return sfb; ++} ++ ++/* ++ * Unmap in the memory mapped IO registers ++ * ++ */ ++ ++static void __devinit ++smi_unmap_mmio(struct smifb_info *sfb) ++{ ++ if (sfb && SMILFB) { ++ iounmap(SMILFB); ++ SMIRegs = NULL; ++ } ++} ++ ++/* ++ * Map in the screen memory ++ * ++ */ ++static int __devinit ++smi_map_smem(struct smifb_info *sfb, struct pci_dev *dev, u_long smem_len) ++{ ++ sfb->fb.fix.smem_start = pci_resource_start(dev, 0); ++ sfb->fb.fix.smem_len = smem_len; ++ ++ debug_printk("%s:smem %x,len %x\n", __func__, ++ sfb->fb.fix.smem_start, ++ sfb->fb.fix.smem_len); ++ ++ sfb->fb.screen_base = SMILFB; ++ ++ if (!sfb->fb.screen_base) { ++ printk("%s: unable to map screen memory\n", sfb->fb.fix.id); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++ ++/* ++ * Unmap in the screen memory ++ * ++ */ ++static void __devinit ++smi_unmap_smem(struct smifb_info *sfb) ++{ ++ if (sfb && sfb->fb.screen_base) { ++ iounmap(sfb->fb.screen_base); ++ sfb->fb.screen_base = NULL; ++ } ++} ++ ++/* ++ * We need to wake up the LynxEM+, and make sure its in linear memory mode. ++ */ ++static inline void __devinit ++smi_init_hw(void) ++{ ++ /* The delays prevent the ColdFire PCI host from locking up. :/ --NL */ ++ udelay(1000); ++ outb(0x18, 0x3c4); ++ ++ udelay(1000); ++ outb(0x11, 0x3c5); ++ udelay(1000); ++ ++ debug_printk("%s: 0x3c4 =%x 0x3c5 %x\n", ++ __func__, inw(0x3c4), inw(0x3c5)); ++} ++ ++static void __devinit ++smi_free_fb_info(struct smifb_info *sfb) ++{ ++ if (sfb) { ++ fb_alloc_cmap(&sfb->fb.cmap, 0, 0); ++ kfree(sfb); ++ } ++} ++ ++ ++u16 SMI_ChipIDs[numChipIDs] = {0x710, 0x712, 0x720}; ++ ++int __devinit smifb_init(struct pci_dev *pdev, const struct pci_device_id *ent) ++{ ++ struct smifb_info *sfb; ++ unsigned long smem_size; ++ char name[16]; ++ int err; ++ char *m_pLAW; ++ unsigned long m_pLAWPhysical; ++ ++ debug_printk("%s start\n", __func__); ++ sprintf(name, "smifb"); ++ hw.chipID = pdev->device; ++ err = -ENOMEM; ++ sfb = smi_alloc_fb_info(pdev, name); ++ if (!sfb) ++ goto failed; ++ ++ smi_init_hw(); ++ ++ /* Map address and memory detection */ ++ m_pLAWPhysical = pci_resource_start(pdev, 0); ++ printk(KERN_INFO "%s:Physical addr %x,hw.chipID %x\n", ++ __func__, (unsigned int)m_pLAWPhysical, ++ (unsigned int)hw.chipID); ++ switch (hw.chipID) { ++ case 0x710: ++ case 0x712: ++ sfb->fb.fix.mmio_start = m_pLAWPhysical + 0x00700000; ++ sfb->fb.fix.mmio_len = 0x00100000; ++ ++ hw.m_pLFB = SMILFB = ++ ioremap(m_pLAWPhysical, 0x00800000); ++ debug_printk("%s:SMILFB%x\n", __func__, SMILFB); ++ hw.m_pMMIO = SMIRegs = SMILFB + 0x00700000; ++ hw.m_pDPR = hw.m_pLFB + 0x00408000; ++ hw.m_pVPR = hw.m_pLFB + 0x0040c000; ++ ++ if (!SMIRegs) { ++ printk(KERN_ERR "%s: unable to map " ++ "memory mapped IO\n", sfb->fb.fix.id); ++ return -ENOMEM; ++ } ++ ++ smi_seqw(0x62, 0x7A); ++ smi_seqw(0x6a, 0x0c); ++ smi_seqw(0x6b, 0x02); ++ smem_size = 0x00400000; ++ ++ /* LynxEM+ memory dection */ ++ *(u32 *)(SMILFB + 4) = 0xAA551133; ++ if (*(u32 *)(SMILFB + 4) != 0xAA551133) { ++ smem_size = 0x00200000; ++ /* Program the MCLK to 130 MHz */ ++ smi_seqw(0x6a, 0x12); ++ smi_seqw(0x6b, 0x02); ++ smi_seqw(0x62, 0x3e); ++ } ++ break; ++ case 0x720: ++ sfb->fb.fix.mmio_start = m_pLAWPhysical + 0x000c0000; ++ sfb->fb.fix.mmio_len = 0x00040000; ++ ++ m_pLAW = ioremap(m_pLAWPhysical, 0x00a00000); ++ hw.m_pLFB = SMILFB = m_pLAW + 0x00200000; ++ hw.m_pMMIO = SMIRegs = m_pLAW + 0x000c0000; ++ hw.m_pDPR = m_pLAW; ++ hw.m_pVPR = m_pLAW + 0x800; ++ ++ smi_seqw(0x62, 0xff); ++ smi_seqw(0x6a, 0x0d); ++ smi_seqw(0x6b, 0x02); ++ smem_size = 0x00400000; ++ ++ break; ++ } ++ ++ sfb->fb.var.xres = 640; ++ sfb->fb.var.yres = 480; ++ sfb->fb.var.bits_per_pixel = 16; ++ ++ sfb->fb.var.xres_virtual = sfb->fb.var.xres; ++ ++ sfb->fb.var.yres_virtual = sfb->fb.var.yres; ++ ++ sfb->fb.flags = FBINFO_FLAG_DEFAULT; ++ ++ debug_printk("%s:smem_size %x\n", __func__, smem_size); ++ err = smi_map_smem(sfb, pdev, smem_size); ++ debug_printk("%s:smi_map_smem error %x\n", __func__, err); ++ if (err) ++ goto failed; ++ ++ fb_set_var(&sfb->fb, &sfb->fb.var); ++ smifb_check_var(&sfb->fb.var, &sfb->fb); ++ smifb_set_par((struct fb_info *)sfb); ++ debug_printk("%s:register_framebuffer\n", __func__); ++ err = register_framebuffer(&sfb->fb); ++ if (err < 0) ++ goto failed; ++ ++ printk(KERN_INFO "Silicon Motion, Inc. " ++ "LynxEM+ Init complete.\n"); ++ return 0; ++ ++failed: ++ smi_unmap_smem(sfb); ++ smi_unmap_mmio(sfb); ++ smi_free_fb_info(sfb); ++ printk(KERN_INFO "Silicon Motion, Inc. " ++ "LynxEM+ Init FAILED.n"); ++ ++ return err; ++} ++ ++static DEFINE_PCI_DEVICE_TABLE(smifb_pci_tbl) = { ++ { 0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID }, ++ { 0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID }, ++ { 0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(pci, smifb_pci_tbl); ++ ++struct pci_driver smifb_driver = { ++ .name = "smifb", ++ .id_table = smifb_pci_tbl, ++ .probe = smifb_init, ++}; ++ ++int __init smi_init(void) ++{ ++ /*return pci_module_init(&smifb_driver);*/ ++ return pci_register_driver(&smifb_driver); ++} ++ ++module_init(smi_init); ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/drivers/video/smifb.h +@@ -0,0 +1,150 @@ ++/*************************************************************************** ++ smifb.h - SiliconMotion LynxEM+ frame buffer device ++ ------------------- ++ begin : Thu Aug 9 2001 ++ copyright : (C) 2001 by Szu-Tao Huang ++ email : johuang@siliconmotion.com ++ ***************************************************************************/ ++/* Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.*/ ++/*************************************************************************** ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ ***************************************************************************/ ++ ++#define smi_mmiowb(dat, reg) writeb(dat, SMIRegs + reg) ++#define smi_mmioww(dat, reg) writew(dat, SMIRegs + reg) ++#define smi_mmiowl(dat, reg) writel(dat, SMIRegs + reg) ++ ++#define smi_mmiorb(reg) readb(SMIRegs + reg) ++#define smi_mmiorw(reg) readw(SMIRegs + reg) ++#define smi_mmiorl(reg) readl(SMIRegs + reg) ++ ++#define SIZE_SR00_SR04 (0x04 - 0x00 + 1) ++#define SIZE_SR10_SR24 (0x24 - 0x10 + 1) ++#define SIZE_SR30_SR75 (0x75 - 0x30 + 1) ++#define SIZE_SR80_SR93 (0x93 - 0x80 + 1) ++#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1) ++#define SIZE_GR00_GR08 (0x08 - 0x00 + 1) ++#define SIZE_AR00_AR14 (0x14 - 0x00 + 1) ++#define SIZE_CR00_CR18 (0x18 - 0x00 + 1) ++#define SIZE_CR30_CR4D (0x4D - 0x30 + 1) ++#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1) ++#define SIZE_VPR (0x6C + 1) ++#define SIZE_DPR (0x44 + 1) ++ ++#define numVGAModes 6 ++#define numChipIDs 3 ++ ++#define NR_PALETTE 256 ++#define NR_RGB 2 ++ ++/* ++ * Minimum X and Y resolutions ++ */ ++#define MIN_XRES 640 ++#define MIN_YRES 480 ++ ++static inline void smi_crtcw(int reg, int val) ++{ ++ smi_mmiowb(reg, 0x3d4); ++ smi_mmiowb(val, 0x3d5); ++} ++ ++static inline unsigned int smi_crtcr(int reg) ++{ ++ smi_mmiowb(reg, 0x3d4); ++ return smi_mmiorb(0x3d5); ++} ++ ++static inline void smi_grphw(int reg, int val) ++{ ++ smi_mmiowb(reg, 0x3ce); ++ smi_mmiowb(val, 0x3cf); ++} ++ ++static inline unsigned int smi_grphr(int reg) ++{ ++ smi_mmiowb(reg, 0x3ce); ++ return smi_mmiorb(0x3cf); ++} ++ ++static inline void smi_attrw(int reg, int val) ++{ ++ smi_mmiorb(0x3da); ++ smi_mmiowb(reg, 0x3c0); ++ smi_mmiorb(0x3c1); ++ smi_mmiowb(val, 0x3c0); ++} ++ ++static inline void smi_seqw(int reg, int val) ++{ ++ smi_mmiowb(reg, 0x3c4); ++ smi_mmiowb(val, 0x3c5); ++} ++ ++static inline unsigned int smi_seqr(int reg) ++{ ++ smi_mmiowb(reg, 0x3c4); ++ return smi_mmiorb(0x3c5); ++} ++/* ++* Private structure ++*/ ++struct smifb_info { ++ /* ++ * The following is a pointer to be passed into the ++ * functions below. The modules outside the main ++ * smifb.c driver have no knowledge as to what ++ * is within this structure. ++ */ ++ struct fb_info fb; ++ struct display_switch *dispsw; ++ struct pci_dev *dev; ++ signed int currcon; ++ ++ struct { ++ u8 red, green, blue; ++ } palette[NR_RGB]; ++ ++ u_int palette_size; ++}; ++ ++struct par_info { ++ /* ++ * Hardware ++ */ ++ u16 chipID; ++ char *m_pLFB; ++ char *m_pMMIO; ++ char *m_pDPR; ++ char *m_pVPR; ++ ++ u_int width; ++ u_int height; ++ u_int hz; ++}; ++ ++/*The next structure holds all information relevant for ++ *a specific video mode. ++ */ ++struct ModeInit { ++ int mmSizeX; ++ int mmSizeY; ++ int bpp; ++ int hz; ++ unsigned char Init_MISC; ++ unsigned char Init_SR00_SR04[SIZE_SR00_SR04]; ++ unsigned char Init_SR10_SR24[SIZE_SR10_SR24]; ++ unsigned char Init_SR30_SR75[SIZE_SR30_SR75]; ++ unsigned char Init_SR80_SR93[SIZE_SR80_SR93]; ++ unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF]; ++ unsigned char Init_GR00_GR08[SIZE_GR00_GR08]; ++ unsigned char Init_AR00_AR14[SIZE_AR00_AR14]; ++ unsigned char Init_CR00_CR18[SIZE_CR00_CR18]; ++ unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D]; ++ unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7]; ++}; +--- a/include/linux/fb.h ++++ b/include/linux/fb.h +@@ -935,6 +935,19 @@ static inline struct apertures_struct *a + #define fb_memcpy_fromfb sbus_memcpy_fromio + #define fb_memcpy_tofb sbus_memcpy_toio + ++#elif defined(CONFIG_COLDFIRE) ++#define fb_readb readb ++#define fb_readw readw ++#define fb_readl readl ++#define fb_readq readq ++#define fb_writeb writeb ++#define fb_writew writew ++#define fb_writel writel ++#define fb_writeq writeq ++#define fb_memset memset_io ++#define fb_memcpy_fromfb memcpy_fromio ++#define fb_memcpy_tofb memcpy_toio ++ + #elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) + + #define fb_readb __raw_readb +@@ -1045,6 +1058,9 @@ extern int fb_deferred_io_fsync(struct f + + static inline bool fb_be_math(struct fb_info *info) + { ++#if defined(CONFIG_COLDFIRE) ++ return false; ++#endif + #ifdef CONFIG_FB_FOREIGN_ENDIAN + #if defined(CONFIG_FB_BOTH_ENDIAN) + return info->flags & FBINFO_BE_MATH; +@@ -1054,7 +1070,7 @@ static inline bool fb_be_math(struct fb_ + return false; + #endif /* CONFIG_FB_BOTH_ENDIAN */ + #else +-#ifdef __BIG_ENDIAN ++#if defined(__BIG_ENDIAN) && !defined(CONFIG_COLDFIRE) + return true; + #else + return false; |