diff --git a/Makefile b/Makefile index e3c5eb6..7d6a733 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 26 EXTRAVERSION = +# Comment added to have git-diff include these lines in the diff. NAME = Rotary Wombat # *DOCUMENTATION* diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index e0c5f96..950a92c 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1418,6 +1418,20 @@ config FB_ATY_BACKLIGHT help Say Y here if you want to control the backlight of your display. +config FB_SMI + tristate "SMI - Silicon Motion SM722 support (Lynx 3DM+) (EXPERIMENTAL)" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_TILEBLITTING + select FB_SVGALIB + select VGASTATE + select FONT_8x16 if FRAMEBUFFER_CONSOLE + select FB_MACMODES if PPC + help + Say Y here if you want to support the SMI Lynx 3DM+ chip : SM722 + config FB_S3 tristate "S3 Trio/Virge support" depends on FB && PCI diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 04bca35..d457bb3 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_FB_KYRO) += kyro/ obj-$(CONFIG_FB_SAVAGE) += savage/ obj-$(CONFIG_FB_GEODE) += geode/ obj-$(CONFIG_FB_MBX) += mbx/ +obj-$(CONFIG_FB_SMI) += smi/ obj-$(CONFIG_FB_NEOMAGIC) += neofb.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o obj-$(CONFIG_FB_CONTROL) += controlfb.o diff --git a/drivers/video/smi/Makefile b/drivers/video/smi/Makefile new file mode 100644 index 0000000..3611c1b --- /dev/null +++ b/drivers/video/smi/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for LynxEM+/EM4+(Silicon Motion Inc.) fb driver for VR5701-SG2 +# under Linux. +# + +obj-$(CONFIG_FB_SM) += smifb.o + +smifb-objs := smi_base.o smi_hw.o + diff --git a/drivers/video/smi/smi_base.c b/drivers/video/smi/smi_base.c new file mode 100644 index 0000000..79f1989 --- /dev/null +++ b/drivers/video/smi/smi_base.c @@ -0,0 +1,384 @@ +/* + * drivers/video/smi/smi_base.c + * + * LynxEM+/EM4+(Silicon Motion Inc.) fb driver for VR5701-SG2 + * + * Author: Sergey Podstavin + * + * Modifications: Nathael Pajani + * Port to linux 2.6.22-rc5 for powerpc based board xcom9347 + * with MPC8347E processor and LYNX_3DM+ graphic chip. + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../console/fbcon.h" +#include "smifb.h" +#include "smi_hw.h" + +#define pr_debug(fmt,arg...) printk(KERN_INFO fmt,##arg) + + +/* + * Card Identification + * + */ +static struct pci_device_id smifb_pci_tbl[] __devinitdata = { + {PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_LYNX_3DM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* Lynx 3DM/3DM+/3DM4+ */ + {0,} /* terminate list */ +}; + +MODULE_DEVICE_TABLE(pci, smifb_pci_tbl); + +static struct fb_var_screeninfo smifb_default_var = { + .xres = 1024, + .yres = 768, + .xres_virtual = 1024, + .yres_virtual = 768, + .xoffset = 0, + .yoffset = 0, + .bits_per_pixel = 8, + .grayscale = 0, + .red = {5, 3, 0}, /* offset, mask */ + .green = {2, 3, 0}, + .blue = {0, 2, 0}, + .transp = {0, 0, 0}, + .nonstd = 0, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .accel_flags = 0, + .pixclock = 15727, + .left_margin = 168, + .right_margin = 0, + .upper_margin = 22, + .lower_margin = 0, + .hsync_len = 104, + .vsync_len = 6, + .sync = FB_SYNC_HOR_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + .rotate = 0, +}; + +static char drvrname[] = "Video driver for SMI Lynx 3DM+"; + + +/* + * + * framebuffer operations + * + */ +static int smifb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) +{ + struct smifb_info *sinfo = (struct smifb_info *)info; + + pr_debug("smifb: smifb_get_fix\n"); + fix->smem_start = sinfo->fb_base_phys; + fix->smem_len = sinfo->fbsize; + fix->mmio_start = sinfo->dpr_base_phys; + fix->mmio_len = sinfo->dpport_size; + + fix->xpanstep = 0; /* FIXME: no xpanstep for now */ + fix->ypanstep = 0; /* FIXME: no ypanstep for now */ + fix->ywrapstep = 0; /* FIXME: no ywrap for now */ + + return 0; +} + +/* +static int smifb_open(struct fb_info *info, int user); +static int smifb_release(struct fb_info *info, int user); +static int smifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); +static int smifb_set_par(struct fb_info *info); + +static int smifb_blank(int blank, struct fb_info *info) +{ + return 0; +} +static int smifb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); +*/ + +static int smifb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, struct fb_info *info) +{ + if (regno > 15) + return 1; + + ((u8 *)(info->pseudo_palette))[regno] = ((red & 0x07) << 5) | ((green & 0x07) << 2) | (blue & 0x3); + return 0; +} +/* +static int smifb_sync(struct fb_info *info) +{ + return 0; +} + +static int smifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg); +*/ +/* + * Initialization helper functions + * + */ +/* kernel interface */ +static struct fb_ops smifb_ops = { + .owner = THIS_MODULE, +/* .fb_open = smifb_open, + .fb_release = smifb_release, + .fb_check_var = smifb_check_var, + .fb_set_par = smifb_set_par, */ + .fb_setcolreg = smifb_setcolreg, +/* .fb_blank = smifb_blank, + .fb_pan_display = smifb_pan_display, */ + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_cursor = soft_cursor, +/* .fb_sync = smifb_sync, + .fb_ioctl = smifb_ioctl, */ +}; + +static struct fb_fix_screeninfo smifb_fix = { + .id = "smifb", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = 1024 * 2, + .accel = FB_ACCEL_NONE, +}; + +static u32 colreg[17]; + +/* NATH: dump registers for debug */ +static ssize_t dump_regs(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pci_dev* fbdev = to_pci_dev(dev); + struct smifb_info* sinfo; + + if (!fbdev) + return -ENODEV; + sinfo = (struct smifb_info*)pci_get_drvdata(fbdev); + if (!sinfo) + return -ENODEV; + + smi_print_moderegs( sinfo ); + + return 0; +} + +static DEVICE_ATTR(dumpregs, 0666, dump_regs, NULL); + +static int smifb_create_dump_file(struct pci_dev *dev) +{ + printk("smifb: creating dump command file in sysfs\n"); + return device_create_file( &dev->dev, &dev_attr_dumpregs ); +} + +static void smifb_remove_reset_file(struct pci_dev *dev) +{ + device_remove_file( &dev->dev, &dev_attr_dumpregs ); +} + +/* + * PCI bus + * + */ +static int __devinit smifb_probe(struct pci_dev *pd, const struct pci_device_id *ent) +{ + int len; + int res; + u16 cmd; + struct smifb_info *sinfo; + struct fb_info *info; + int i = 0; + + pr_debug("smifb: vendor id 0x%04x\n", pd->vendor); + pr_debug("smifb: device id 0x%04x\n", pd->device); + + pr_debug("smifb: base0 start addr 0x%08x\n", (unsigned int)pci_resource_start(pd, 0)); + pr_debug("smifb: base0 end addr 0x%08x\n", (unsigned int)pci_resource_end(pd, 0)); + pr_debug("smifb: base0 region len 0x%08x\n", (unsigned int)pci_resource_len(pd, 0)); + pr_debug("smifb: base0 flags 0x%08x\n", (unsigned int)pci_resource_flags(pd, 0)); + + /* Allocate memory resources */ + sinfo = kmalloc(sizeof(struct smifb_info), GFP_KERNEL); + if (!sinfo) { + goto err_out; + } + memset(sinfo, 0, sizeof(struct smifb_info)); + + /* Driver name */ + sinfo->drvr_name = drvrname; + + /* Set up PCI */ + sinfo->pd = pd; + sinfo->base_phys = pci_resource_start(sinfo->pd, 0); /* PCI device base address */ + len = pci_resource_len(sinfo->pd, 0); + pr_debug("smifb: PCI ressource len = 0x%08lx\n", (long unsigned int)len); + /* Reserve PCI I/O and memory resources */ + if (!request_mem_region(sinfo->base_phys, len, "smifb")) { + printk(KERN_ERR "cannot reserve FrameBuffer and MMIO region\n"); + goto err_out_kfree; + } + + if ((res = pci_enable_device(sinfo->pd)) < 0) { + printk(KERN_ERR "smifb: failed to enable -- err %d\n", res); + goto err_out_free_base; + } + + /* Set MEM and IO */ + pci_read_config_word(pd, PCI_COMMAND, &cmd); + cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO); + pci_write_config_word(pd, PCI_COMMAND, cmd); + + + sinfo->base = ioremap(sinfo->base_phys, len); /* FB+DPD+DPR+VPR+CPR+MMIO */ + if (!sinfo->base) { + goto err_out_free_base; + } + + /* Set up memory pointers */ + sinfo->dpport = (caddr_t) (sinfo->base + LYNX3DM_DPPORT_BASE_OFFSET); + sinfo->dpr = (caddr_t) (sinfo->base + LYNX3DM_DP_BASE_OFFSET); + sinfo->vpr = (caddr_t) (sinfo->base + LYNX3DM_VP_BASE_OFFSET); + sinfo->cpr = (caddr_t) (sinfo->base + LYNX3DM_CP_BASE_OFFSET); + sinfo->mmio = (caddr_t) (sinfo->base + LYNX3DM_IO_BASE_OFFSET); + sinfo->fb_base = (caddr_t) (sinfo->base + LYNX3DM_FB_BASE_OFFSET); + + pr_debug("smifb: sinfo->dpport = 0x%08x\n", (uint32_t) sinfo->dpport); + pr_debug("smifb: sinfo->dpr = 0x%08x, sinfo->vpr = 0x%08x\n", (unsigned int)sinfo->dpr, (unsigned int)sinfo->vpr); + pr_debug("smifb: sinfo->cpr = 0x%08x, sinfo->mmio = 0x%08x\n", (unsigned int)sinfo->cpr, (unsigned int)sinfo->mmio); + + sinfo->fbsize = 8 * 1024 * 1024; + sinfo->fb_base_phys = sinfo->base_phys + LYNX3DM_FB_BASE_OFFSET; + + pr_debug("smifb: sinfo->fb_base_phys = 0x%08x\n", (unsigned int)sinfo->fb_base_phys); + pr_debug("smifb: sinfo->fbsize = 0x%08x\n", (unsigned int)sinfo->fbsize); + pr_debug("smifb: sinfo->base = 0x%08x\n", (unsigned int)sinfo->base); + pr_debug("smifb: sinfo->fb_base = 0x%08x\n", (unsigned int)sinfo->fb_base); + + /* Clear frame buffer */ + for (i=0; ifbsize/4; i++) { + *((uint32_t*)(sinfo->fb_base + i*4)) = 0; + } + + smi_print_moderegs( sinfo ); + + /* Set up driver */ + info = &(sinfo->info); + smifb_get_fix(&smifb_fix, -1, info); + + info->flags = FBINFO_FLAG_DEFAULT; + info->fbops = &smifb_ops; + info->var = smifb_default_var; + info->fix = smifb_fix; + info->pseudo_palette = colreg; + info->screen_base = sinfo->fb_base; + + /* Set up the chip registers */ + smi_set_moderegs(sinfo, &smifb_default_var); + + if (register_framebuffer(&sinfo->info) < 0) { + goto err_out_iounmap; + } + pci_set_drvdata(pd, sinfo); + + smifb_create_dump_file( pd ); + + printk(KERN_INFO "smifb: " "framebuffer (%s)\n", sinfo->drvr_name); + + return 0; + +err_out_iounmap: + iounmap(sinfo->base); +err_out_free_base: + release_mem_region(sinfo->base_phys, len); +err_out_kfree: + kfree(sinfo); +err_out: + return -ENODEV; +} + +static void __devexit smifb_remove(struct pci_dev *pd) +{ + struct smifb_info *sinfo = pci_get_drvdata(pd); + pr_debug("smifb: smifb_remove\n"); + + if (!sinfo) + return; + + smifb_remove_reset_file( pd ); + + unregister_framebuffer(&sinfo->info); + + /* stop the lynx chip */ + release_mem_region(sinfo->base_phys, pci_resource_len(sinfo->pd, 0)); + kfree(sinfo); + pci_set_drvdata(pd, NULL); +} + + +static struct pci_driver smifb_driver = { + .name = "smifb", + .id_table = smifb_pci_tbl, + .probe = smifb_probe, + .remove = __devexit_p(smifb_remove), +}; + + +/* + * Driver initialization + */ +static int __init smifb_setup(char *options) +{ + pr_debug("smifb: setup\n"); + + if (!options || !*options) { + pr_debug("smifb: no options given.\n"); + return 0; + } + + pr_debug("smifb: no options supported yet.\n"); + return 0; +} + +int __init smifb_init(void) +{ + char *option = NULL; + + pr_debug("smifb: smifb_init\n"); + + if (fb_get_options("smifb", &option)) + return -ENODEV; + smifb_setup(option); + + return pci_register_driver(&smifb_driver); +} + + +static void __exit smifb_exit(void) +{ + pci_unregister_driver(&smifb_driver); +} + +module_init(smifb_init); +module_exit(smifb_exit); + + +MODULE_AUTHOR("Sergey Podstavin"); +MODULE_DESCRIPTION("Framebuffer driver for Silicon Motion Lynx 3DM+"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/smi/smi_hw.c b/drivers/video/smi/smi_hw.c new file mode 100644 index 0000000..b71792a --- /dev/null +++ b/drivers/video/smi/smi_hw.c @@ -0,0 +1,629 @@ +/* + * drivers/video/smi/smi_hw.c + * + * LynxEM+/EM4+(Silicon Motion Inc.) fb driver for VR5701-SG2 + * + * Author: Sergey Podstavin + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include "smifb.h" +#include "smi_hw.h" + +#define pr_debug(fmt,arg...) printk(KERN_INFO fmt,arg) + +void smi_print_moderegs(struct smifb_info *sinfo) +{ + unsigned int xres = 0, hStart = 0, right_margin = 0, hTotal = 0, hsync_len = 0; + unsigned int yres = 0, vStart = 0, lower_margin = 0, vTotal = 0, vsync_len = 0; + + unsigned int wchar = 8; + unsigned int val = 0, overflow_07 = 0, overflow_30 = 0; + + unsigned int i = 0; + + printk("\n\n\tBegin dump of regs\n\n"); + + pr_debug("smifb: sinfo->dpport = 0x%08x\n", (uint32_t) sinfo->dpport); + pr_debug("smifb: sinfo->dpr = 0x%08x, sinfo->vpr = 0x%08x\n", (unsigned int)sinfo->dpr, (unsigned int)sinfo->vpr); + pr_debug("smifb: sinfo->cpr = 0x%08x, sinfo->mmio = 0x%08x\n", (unsigned int)sinfo->cpr, (unsigned int)sinfo->mmio); + + /* Drawing Engine Control Registers */ + printk(" DPR_00 Source Y or K2 : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x00))&0x3fff)); + printk(" DPR_02 Source X or K1 : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x00))&0x3fff0000)>>16)); + printk(" DPR_04 Destination Y or Start Y : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x04))&0x3fff)); + printk(" DPR_06 Destination X or Start X : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x04))&0x0fff0000)>>16)); + printk(" DPR_08 Dimension Y or Error Term : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x08))&0x3fff)); + printk(" DPR_0A Dimension X or Vector Length : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x08))&0x0fff0000)>>16)); + printk(" DPR_0C ROP and Miscellaneous Ctrl : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x0C))&0xffff)); + printk(" DPR_0E DE Commands and Ctrl : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x0C))&0xffff0000)>>16)); + printk(" DPR_10 Source Row Pitch : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x10))&0x0fff)); + printk(" DPR_12 Destination Row Picth : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x10))&0x0fff0000)>>16)); + printk(" DPR_14 Foreground Colors : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x14))&0x00ffffff); + printk(" DPR_18 Background Colors : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x18))&0x00ffffff); + printk(" DPR_1C Stretch Source Height Y : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x1C))&0x0fff)); + printk(" DPR_1E DE Data/Loc Format Select : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x1C))&0x7fbf0000)>>16)); + printk(" DPR_20 Color Compare : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x20))&0x00ffffff); + printk(" DPR_24 Color Compare Mask : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x24))&0x00ffffff); + printk(" DPR_28 Bit Mask : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x28))&0xffff)); + printk(" DPR_2A Byte Mask Enable : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x28))&0xffff0000)>>16)); + printk(" DPR_2C Scisors Left and Control : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x2C))&0x3fff)); + printk(" DPR_2E Scisors Top : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x2C))&0x0fff0000)>>16)); + printk(" DPR_30 Scisors Right : 0x%04x\n", (in_le32((unsigned*)(sinfo->dpr+0x30))&0x0fff)); + printk(" DPR_32 Scisors Bottom : 0x%04x\n", ((in_le32((unsigned*)(sinfo->dpr+0x30))&0x0fff0000)>>16)); + printk(" DPR_34 Mono Pattern Low : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x34))); + printk(" DPR_38 Mono Pattern High : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x38))); + printk(" DPR_3C XY Addr Dst & Src ... : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x3C))&0x0fff0fff); + printk(" DPR_40 Source Base Address : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x40))&0x000fffff); + printk(" DPR_44 Destination Base Address : 0x%08x\n", in_le32((unsigned*)(sinfo->dpr+0x44))&0x000fffff); + + /* Video Processor Control Registers */ + printk(" VPR_00 Miscellaneous Graphics and Video Control : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x00))); + printk(" VPR_04 Color Keys : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x04))); + printk(" VPR_08 Color Key Masks : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x08))); + printk(" VPR_0C Data Src Start Addr for Ext Graphics Modes : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x0C))); + printk(" VPR_10 Data Src Width and Off for Ext Graphics Modes : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x10))); + printk(" VPR_14 Video Window I Left and Top Boundaries : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x14))); + printk(" VPR_18 Video Window I Right and Bottom Boundaries : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x18))); + printk(" VPR_1C Video Window I Source Start Address : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x1C))); + printk(" VPR_20 Video Window I Source Width and Offset : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x20))); + printk(" VPR_24 Video Window I Stretch Factor : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x24))); + printk(" VPR_28 Video Window II Left and Top Boundaries : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x28))); + printk(" VPR_2C Video Window II Right and Bottom Boundaries : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x2C))); + printk(" VPR_30 Video Window II Source Start Address : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x30))); + printk(" VPR_34 Video Window II Source Width and Offset : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x34))); + printk(" VPR_38 Video Window II Stretch Factor : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x38))); + printk(" VPR_3C Graphics and Video Controll II : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x3C))); + printk(" VPR_40 Graphic Scale Factor : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x40))); + printk(" VPR_54 FIFO Priority Control : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x54))); + printk(" VPR_58 FIFO Empty Request level Control : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x58))); + printk(" VPR_5C YUV to RGB Conversion Constant : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x5C))); + printk(" VPR_60 Current Scan Line Position : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x60))); + printk(" VPR_64 Signature Analyzer Control and Status : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x64))); + printk(" VPR_68 Video Window I Stretch Factor : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x68))); + printk(" VPR_6C Video Window II Stretch Factor : 0x%08x\n", in_le32((unsigned*)(sinfo->vpr+0x6C))); + + /* Capture Processor Control Registers */ + printk(" CPR_00 Capture Port Control : 0x%08x\n", in_le32((unsigned*)(sinfo->cpr+0x00))); + printk(" CPR_04 Video Source Clipping Control : 0x%08x\n", in_le32((unsigned*)(sinfo->cpr+0x04))); + printk(" CPR_08 Video Source Capture Size Control : 0x%08x\n", in_le32((unsigned*)(sinfo->cpr+0x08))); + printk(" CPR_0C Capture Port Buffer I Source Start Address : 0x%08x\n", in_le32((unsigned*)(sinfo->cpr+0x0C))); + printk(" CPR_10 Capture Port Buffer II Source Start Address : 0x%08x\n", in_le32((unsigned*)(sinfo->cpr+0x10))); + printk(" CPR_14 Capture Port Source Offset Address : 0x%08x\n", in_le32((unsigned*)(sinfo->cpr+0x14))); + printk(" CPR_18 Capture FIFO Empty Request level Control : 0x%08x\n", in_le32((unsigned*)(sinfo->cpr+0x18))); + + printk("\n\n"); + + printk("mmio @ 0x%08x.\n", (unsigned int)sinfo->mmio); + printk("smi_vga_misc_read : %02x\n", smi_vga_misc_read(sinfo->mmio)); + printk("smi_feature_ctrl_read : %02x\n", smi_feature_ctrl_read(sinfo->mmio)); + val = smi_status0_read(sinfo->mmio); + printk("Input status registers : 0x%02x, 0x%02x\n", val, smi_status1_read(sinfo->mmio)); + if (val & 0x10) { + printk(" Color Display detected.\n"); + } + + printk("\nSEQUENCER."); + for (i = 0; i <= 0x04; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_sequencer_read(sinfo->mmio, i)); + } + + printk("\nCRT CONTROLLER."); + for (i = 0; i <= 0x18; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_crtc_read(sinfo->mmio, i)); + } + for (i = 0x30; i <= 0x4D; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_crtc_read(sinfo->mmio, i)); + } + + printk("\nGRAPHICS CONTROLLER."); + for (i = 0; i <= 0x08; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_graphics_read(sinfo->mmio, i)); + } + + printk("\nATTRIBUTE CONTROLLER."); + for (i = 0; i <= 0x14; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_attribute_read(sinfo->mmio, i)); + } + + printk("\nSYSTEM CONTROL."); + printk("\n\t10| -- -- -- -- --"); + for (i = 0x15; i <= 0x1F; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_sysctrl_read(sinfo->mmio, i)); + } + + printk("\nPOWER DOWN CONTROL."); + for (i = 0x20; i <= 0x24; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_powerctrl_read(sinfo->mmio, i)); + } + + printk("\nFLAT PANEL CONTROL."); + for (i = 0x30; i <= 0x34; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_flatpanel_read(sinfo->mmio, i)); + } + printk(" -- -- -- -- -- -- -- -- --"); + for (i = 0x3E; i <= 0x4E; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_flatpanel_read(sinfo->mmio, i)); + } + printk(" --"); + for (i = 0x50; i <= 0x5A; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_flatpanel_read(sinfo->mmio, i)); + } + for (i = 0xA0; i <= 0xAF; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_flatpanel_read(sinfo->mmio, i)); + } + + printk("\nMEMORY CONTROL."); + for (i = 0x60; i <= 0x61; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_memctrl_read(sinfo->mmio, i)); + } + printk("\n\t70| -- -- -- -- -- -- %02x", smi_ext_memctrl_read(sinfo->mmio, 0x76)); + + printk("\nCLOCK CONTROL.\n"); + printk("\t60| -- -- -- -- --"); + for (i = 0x65; i <= 0x6F; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_clkctrl_read(sinfo->mmio, i)); + } + + printk("\nGENERAL PURPOSE REGS."); + for (i = 0x70; i <= 0x75; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_gp_read(sinfo->mmio, i)); + } + + printk("\nPOP-UP ICON and HARDWARE CURSOR."); + for (i = 0x80; i <= 0x93; i++) { + if (!(i % 16)) + printk("\n\t%02x|", i); + if (!(i % 4)) + printk(" "); + printk(" %02x", smi_ext_cursor_read(sinfo->mmio, i)); + } + + printk("\n\n\tEnd dump of regs\n\n"); + + printk("\n\tBegin display values traduction\n\n"); + + xres = ((smi_crtc_read(sinfo->mmio, SMI_CRTx01_H_DISPLAY_END) + 1) * wchar); /* hDisplay */ + hStart = ((smi_crtc_read(sinfo->mmio, SMI_CRTx04_H_SYNC_START) + 0) * wchar); + hTotal = ((smi_crtc_read(sinfo->mmio, SMI_CRTx00_H_TOTAL) + 5) * wchar); + val = ((smi_crtc_read(sinfo->mmio, SMI_CRTx05_H_SYNC_END) & 0x80) >> 2 ); + val |= (smi_crtc_read(sinfo->mmio, SMI_CRTx03_H_BLANK_END) & 0x1f); + right_margin = (val * wchar); + hsync_len = ((smi_crtc_read(sinfo->mmio, SMI_CRTx05_H_SYNC_END) & 0x1f) * wchar); + + overflow_30 = smi_crtc_read(sinfo->mmio, SMI_CRTx30_MODE_EN); + overflow_07 = smi_crtc_read(sinfo->mmio, SMI_CRTx07_OVERFLOW_VERT); + val = ( ((overflow_07 & 0x02) << (8-1)) | ((overflow_07 & 0x40) << (9-6)) ); + val |= ((overflow_30 & 0x04) << (10-2)); + val |= smi_crtc_read(sinfo->mmio, SMI_CRTx12_V_DISPLAY_END); + yres = (val + 1); + val = ( ((overflow_07 & 0x04) << (8-2)) | ((overflow_07 & 0x80) << (9-7)) ); + val |= ((overflow_30 & 0x01) << (10-0)); + vStart = (smi_crtc_read(sinfo->mmio, SMI_CRTx10_V_SYNC_START) | val); + val = ( ((overflow_07 & 0x01) << (8-0)) | ((overflow_07 & 0x20) << (9-5)) ); + val |= ((overflow_30 & 0x08) << (10-3)); + vTotal = (smi_crtc_read(sinfo->mmio, SMI_CRTx06_V_TOTAL) | val); + lower_margin = smi_crtc_read(sinfo->mmio, SMI_CRTx16_V_BLANK_END); + vsync_len = (smi_crtc_read(sinfo->mmio, SMI_CRTx11_V_SYNC_END) & 0x0f); + + printk("Horizontal values, in pixclocks\n"); + printk(" xres = %d\n", xres); + printk(" hTotal = %d\n", hTotal); + printk(" left_margin (hTotal - hStart - hsync_len) = %d\n", (hTotal - hStart - hsync_len)); + printk(" right_margin = %d\n", right_margin); + printk(" computed right_margin (hStart - xres) = %d\n", (hStart - xres)); + printk(" hStart = %d\n", hStart); + printk(" hsync_len = %d\n", hsync_len); + + printk("Vertical values, in pixclocks\n"); + printk(" yres = %d\n", yres); + printk(" vTotal = %d\n", vTotal); + printk(" upper_margin (vTotal - vStart - vsync_len) = %d\n", (vTotal - vStart - vsync_len)); + printk(" lower_margin = %d\n", lower_margin); + printk(" computed lower_margin (vStart - yres) = %d\n", (vStart - yres)); + printk(" vStart = %d\n", vStart); + printk(" vsync_len = %d\n", vsync_len); + + printk("\n\tEnd display values traduction\n\n"); + +} + + +/* + * set mode registers + */ +void smi_set_moderegs(struct smifb_info* sinfo, struct fb_var_screeninfo* fbinfo) +{ + unsigned int bpp = 0, width = 0, height = 0; + unsigned int hDisplay = 0, hStart = 0, hEnd = 0, hTotal = 0; + unsigned int vDisplay = 0, vStart = 0, vEnd = 0, vTotal = 0; + unsigned int wchar = 8, hchar = 16; + unsigned int mode = SMI_USE_GRAPH; + + struct vpr_regs* vpr; + struct dpr_regs* dpr; + + unsigned int tmp = 0; + unsigned int val = 0; + + bpp = fbinfo->bits_per_pixel; + + /* horizontal params all in pixclock */ + width = fbinfo->xres_virtual; + hDisplay = fbinfo->xres; + hStart = (hDisplay + fbinfo->right_margin); /* h-blank start */ + hEnd = (hStart + fbinfo->hsync_len); /* h-sync end */ + hTotal = (hEnd + fbinfo->left_margin); /* hsync to hsync */ + + /* vertical params */ + height = fbinfo->yres_virtual; + vDisplay = fbinfo->yres; /* number of lines */ + vStart = (vDisplay + fbinfo->lower_margin); /* v-sync pulse start */ + vEnd = (vStart + fbinfo->vsync_len); /* v-sync end */ + vTotal = (vEnd + fbinfo->upper_margin); /* number of scanlines (v-blank end) */ + + + printk("smi_set_moderegs, values in pixclocks\n"); + pr_debug("bpp = %d, width = %d, height = %d\n", bpp, width, height); + pr_debug("hDisplay = %d, hStart = %d, hEnd = %d, hTotal = %d\n", hDisplay, hStart, hEnd, hTotal); + pr_debug("vDisplay = %d, vStart = %d, vEnd = %d, vTotal = %d\n", vDisplay, vStart, vEnd, vTotal); + + /**********************************************************************/ + /* Zero chip memory */ + memset(sinfo->vpr, 0, sizeof(struct vpr_regs)); + memset(sinfo->dpr, 0, sizeof(struct dpr_regs)); + memset(sinfo->cpr, 0, sizeof(struct cpr_regs)); + + pr_debug("smi_nath : smi_vga_misc_read : %02x\n", smi_vga_misc_read(sinfo->mmio)); + pr_debug("smi_nath : smi_feature_ctrl_read : %02x\n", smi_feature_ctrl_read(sinfo->mmio)); + + /* Set the chip in color mode and unlock the registers */ + tmp = ( 0x0c | SMI_MISC_ENABLE_WRITE | SMI_MISC_COLOR_MODE ); + if (fbinfo->sync & FB_SYNC_HOR_HIGH_ACT) + tmp |= 0x40; + if (fbinfo->sync & FB_SYNC_VERT_HIGH_ACT) + tmp |= 0x80; + smi_vga_misc_write(sinfo->mmio, tmp); + + /* Enable access to SMI Extended regs */ + smi_unlock_extended_regs(sinfo->mmio); + + printk("smi_set_moderegs, enabling display\n"); + /* Enable display */ + tmp = ((bpp == 8) ? 0x00 : 0x40); + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRx31_VIRT_REFRESH, (0x83 | tmp)); /* No auto-shutdown, CRT and LCD */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRx33_POWER_CURSOR_CTRL, 0x05); /* default, CRT VGA unlocked, LVDS off */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRx34_ON_OFF_SEQ, 0x80); /* default */ + /* At least 0 in bit 7 in order to allow writting to CRT 00-07 regs, the right value will be set up later */ + tmp = smi_crtc_read(sinfo->mmio, SMI_CRTx11_V_SYNC_END); + smi_crtc_write(sinfo->mmio, SMI_CRTx11_V_SYNC_END, (tmp & ~0x80)); + + printk("smi_set_moderegs, setting up mmio regs\n"); + /**********************************************************************/ + /* Sequencer */ + smi_sequencer_write(sinfo->mmio, SMI_SEQx00_RESET, 0x03); /* Normal operating mode */ + tmp = ((wchar == 9) ? 0x00 : 0x01); + smi_sequencer_write(sinfo->mmio, SMI_SEQx01_CLK_MODE, tmp); /* 8 or 9 dots wide char clock */ + smi_sequencer_write(sinfo->mmio, SMI_SEQx02_EN_WR_PLANE, 0x0F); /* Allow write to all map planes */ + smi_sequencer_write(sinfo->mmio, SMI_SEQx03_CHAR_MAP_SEL, 0x00); + smi_sequencer_write(sinfo->mmio, SMI_SEQx04_MEM_MODE, 0x0e); /* Sequential addressing of all 256K */ + + /**********************************************************************/ + /* CRTC Controller */ + /* Horizontal display, the following values are in character clocks */ + smi_crtc_write(sinfo->mmio, SMI_CRTx00_H_TOTAL, (hTotal/wchar - 5)); /* Horizontal Total */ + smi_crtc_write(sinfo->mmio, SMI_CRTx01_H_DISPLAY_END, (hDisplay/wchar - 1)); /* Horizontal Display End */ + smi_crtc_write(sinfo->mmio, SMI_CRTx02_H_BLANK_START, (hDisplay/wchar - 1)); /* Horizontal Blank Start */ + val = (fbinfo->right_margin / wchar); + tmp = (val & 0x1f); + smi_crtc_write(sinfo->mmio, SMI_CRTx03_H_BLANK_END, (0x00 | tmp)); /* Blank Pulse Width*/ + smi_crtc_write(sinfo->mmio, SMI_CRTx04_H_SYNC_START, (hStart/wchar)); /* Horizontal Sync Pulse Start */ + tmp = ( (val & 0x20) << (7-5) ); + val = ((fbinfo->hsync_len / wchar) & 0x1f); + smi_crtc_write(sinfo->mmio, SMI_CRTx05_H_SYNC_END, (tmp | 0x00 | val)); /* Sync Pulse Width */ + + /* Vertical display, the following values are in scan lines */ + smi_crtc_write(sinfo->mmio, SMI_CRTx06_V_TOTAL, (vTotal & 0xff)); /* Vertical Total 8 LSB bits*/ + smi_crtc_write(sinfo->mmio, SMI_CRTx12_V_DISPLAY_END, ((vDisplay - 1) & 0xff)); /* Vertical Display End */ + smi_crtc_write(sinfo->mmio, SMI_CRTx15_V_BLANK_START, ((vDisplay - 1) & 0xff)); /* Vertical Blank Start */ + smi_crtc_write(sinfo->mmio, SMI_CRTx16_V_BLANK_END, (fbinfo->lower_margin & 0xff)); /* Vertical Blank End */ + smi_crtc_write(sinfo->mmio, SMI_CRTx10_V_SYNC_START, (vStart & 0xff)); /* Vertical Sync Pulse Start */ + val = (fbinfo->vsync_len & 0x0f); + smi_crtc_write(sinfo->mmio, SMI_CRTx11_V_SYNC_END, (0x00 | val)); /* Vertical Sync Pulse Width */ + tmp = ( ((vTotal & 0x200) >> (9-5)) | ((vTotal & 0x100) >> (8-0)) ); /* 06_V_TOTAL */ + tmp |= ( (((vDisplay - 1) & 0x200) >> (9-6)) | (((vDisplay - 1) & 0x100) >> (8-1)) ); /* 12_V_DISPLAY_END */ + tmp |= ( ((vDisplay - 1) & 0x100) >> (8-3) ); /* 15_V_BLANK_START */ + tmp |= ( ((vStart & 0x200) >> (9-7)) | ((vStart & 0x100) >> (8-2)) ); /* 10_V_SYNC_START */ + tmp |= ( (0xfff & 0x100) >> (8-4) ); /* 18_LINE_COMPARE */ + smi_crtc_write(sinfo->mmio, SMI_CRTx07_OVERFLOW_VERT, (0x00 | tmp)); /* Overflow Vertical */ + smi_crtc_write(sinfo->mmio, SMI_CRTx08_PRESET_ROW_SCAN, 0x00); /* Preset Row Scan */ + tmp = ( (vDisplay & 0x200) >> (9-5) ); /* 15_V_BLANK_START */ + tmp |= ( (0xfff & 0x200) >> (9-6) ); /* 18_LINE_COMPARE */ + val = ((hchar - 1) & 0x1f); + smi_crtc_write(sinfo->mmio, SMI_CRTx09_MAX_SCAN_LINE, (0x00 | tmp | val)); /* Maximum Scan Line */ + + smi_crtc_write(sinfo->mmio, SMI_CRTx0C_DISP_START_ADDR_H, 0x00); /* Display Start Address (19 bits) = 0x00000 */ + smi_crtc_write(sinfo->mmio, SMI_CRTx0D_DISP_START_ADDR_L, 0x00); + smi_crtc_write(sinfo->mmio, SMI_CRTx0A_CURSOR_START, 0x20); /* No cursor */ + smi_crtc_write(sinfo->mmio, SMI_CRTx0B_CURSOR_END, 0x00); + smi_crtc_write(sinfo->mmio, SMI_CRTx0E_CURSOR_ADDR_H, 0x00); + smi_crtc_write(sinfo->mmio, SMI_CRTx0F_CURSOR_ADDR_L, 0x00); + tmp = ((width * bpp / 64) & 0xff); + smi_crtc_write(sinfo->mmio, SMI_CRTx13_OFFSET, 0xff); /* Offset */ + smi_crtc_write(sinfo->mmio, SMI_CRTx14_UNDERLINE_LOC, (0x40)); /* Underline Location */ + tmp = ((bpp == 8) ? 0x04 : 0x00); + smi_crtc_write(sinfo->mmio, SMI_CRTx17_MODE_CTRL, (0xa3)); /* CRT Mode Control */ + smi_crtc_write(sinfo->mmio, SMI_CRTx18_LINE_COMPARE, 0xff); /* Line Compare */ + + /* Extended SMI CRT */ + tmp = ((vTotal & 0x400) >> (10-3)); /* 06_V_TOTAL */ + tmp |= (((vDisplay - 1) & 0x400) >> (10-2)); /* 12_V_DISPLAY_END */ + tmp |= ((vDisplay & 0x400) >> (10-1)); /* 15_V_BLANK_START */ + tmp |= ((vStart & 0x400) >> (10-0)); /* 10_V_SYNC_START */ + smi_crtc_write(sinfo->mmio, SMI_CRTx30_MODE_EN, (0x00 | tmp)); /* CRTC Overflow and Interlace Mode Enable */ + smi_crtc_write(sinfo->mmio, SMI_CRTx31_INTL_RETRACE, 0x00); + smi_crtc_write(sinfo->mmio, SMI_CRTx35_V_EXP_CONST_L, 0x00); + smi_crtc_write(sinfo->mmio, SMI_CRTx36_V_EXP_CONST_H, 0x00); + + /* Shadow registers */ + smi_crtc_write(sinfo->mmio, SMI_SVRx40_H_TOTAL, (hTotal/wchar - 5)); /* Horizontal Total */ + smi_crtc_write(sinfo->mmio, SMI_SVRx41_H_BLANK_START, (hDisplay/wchar - 1)); /* Horizontal Blank Start */ + val = (fbinfo->right_margin / wchar); + tmp = (val & 0x1f); + smi_crtc_write(sinfo->mmio, SMI_SVRx42_H_BLANK_END, tmp); /* Horizontal Blank End */ + smi_crtc_write(sinfo->mmio, SMI_SVRx43_H_RETRACE_START, (hStart/wchar)); /* Horizontal Retrace Start */ + tmp = ( (val & 0x20) << (7-5) ); + val = ((fbinfo->hsync_len / wchar) & 0x1f); + smi_crtc_write(sinfo->mmio, SMI_SVRx44_H_RETRACE_END, (tmp | 0x00 | val)); /* Horizontal Retrace End */ + smi_crtc_write(sinfo->mmio, SMI_SVRx45_V_TOTAL, (vTotal & 0xff)); /* Vertical Total */ + smi_crtc_write(sinfo->mmio, SMI_SVRx46_V_BLANK_START, ((vDisplay - 1) & 0xff)); /* Vertical Blank Start */ + smi_crtc_write(sinfo->mmio, SMI_SVRx47_V_BLANK_END, (fbinfo->lower_margin & 0xff)); /* Vertical Blank End */ + smi_crtc_write(sinfo->mmio, SMI_SVRx48_V_RETRACE_START, (vStart & 0xff)); /* Vertical Retrace Start */ + smi_crtc_write(sinfo->mmio, SMI_SVRx49_V_RETRACE_END, (fbinfo->vsync_len & 0x0f)); /* Vertical Retrace End */ + tmp = ( ((vStart & 0x200) >> (9-7)) | ((vStart & 0x100) >> (8-2)) ); + tmp |= ( (((vDisplay - 1) & 0x200) >> (9-6)) | (((vDisplay - 1) & 0x100) >> (8-1)) ); + tmp |= ( ((vTotal & 0x200) >> (9-5)) | ((vTotal & 0x100) >> (8-0)) ); + tmp |= ( ((vDisplay - 1) & 0x100) >> (8-3) ); + smi_crtc_write(sinfo->mmio, SMI_SVRx4A_V_OVERFLOW, tmp); /* Vertical Overflow */ + tmp = ( ((vDisplay - 1) & 0x200) >> (9-5) ); + smi_crtc_write(sinfo->mmio, SMI_SVRx4B_MAX_SCAN_LINE, tmp); /* Maximum Scan Line */ + smi_crtc_write(sinfo->mmio, SMI_SVRx4C_H_DISPLAY_END, (hDisplay/wchar - 1)); /* Horizontal Display End */ + smi_crtc_write(sinfo->mmio, SMI_SVRx4D_V_DISPLAY_END, ((vDisplay - 1) & 0xff)); /* Vertical Display End */ + + + /**********************************************************************/ + /* Graphics Controller */ + smi_graphics_write(sinfo->mmio, SMI_GRx00_SET_RESET, 0x00); + smi_graphics_write(sinfo->mmio, SMI_GRx01_EN_SET_RESET, 0x00); + smi_graphics_write(sinfo->mmio, SMI_GRx02_COLOR_COMPARE, 0x00); + smi_graphics_write(sinfo->mmio, SMI_GRx03_DATA_ROTATE, 0x00); + smi_graphics_write(sinfo->mmio, SMI_GRx04_READ_PLANE_SEL, 0x00); + smi_graphics_write(sinfo->mmio, SMI_GRx05_MODE, 0x40); /* Graphics Mode, FIXME: bpp dependant ? */ + smi_graphics_write(sinfo->mmio, SMI_GRx06_MISC, (0x04 | mode)); /* Graphics Misc */ + smi_graphics_write(sinfo->mmio, SMI_GRx07_COLOR_DONT_CARE, 0x0f); /* Color don't care plane */ + smi_graphics_write(sinfo->mmio, SMI_GRx08_BIT_MASK, 0xff); /* Bit Mask */ + + + /**********************************************************************/ + /* Attribute Controller */ + for (tmp = 0; tmp <= 0x0f; tmp++) { + smi_attribute_write(sinfo->mmio, SMI_ATTRx_PAL(tmp), tmp); + } + tmp = ((bpp == 8) ? 0x40 : 0x00); + smi_attribute_write(sinfo->mmio, SMI_ATTRx10_MODE, (0x00 | mode | tmp)); /* Attr Mode Ctrl */ + smi_attribute_write(sinfo->mmio, SMI_ATTRx11_OVERSCAN_COLOR, 0x00); + smi_attribute_write(sinfo->mmio, SMI_ATTRx12_COLOR_PLANE_EN, 0x0f); + smi_attribute_write(sinfo->mmio, SMI_ATTRx13_H_PIX_PANNING, 0x00); + smi_attribute_write(sinfo->mmio, SMI_ATTRx14_COLOR_SELECT, 0x00); + + + /**********************************************************************/ + /* System Control */ + smi_ext_sysctrl_write(sinfo->mmio, SMI_SCRx15_PCI_MISC_CTRL, 0x8a); /* PCI Misc Ctrl */ + smi_ext_sysctrl_write(sinfo->mmio, SMI_SCRx17_GRAPH_COMMAND_1, 0x22); /* General Graphics Command 1 */ + smi_ext_sysctrl_write(sinfo->mmio, SMI_SCRx18_GRAPH_COMMAND_2, 0x11); /* General Graphics Command 2 */ + smi_ext_sysctrl_write(sinfo->mmio, SMI_SCRx19_INTR_EN_MASK_1, 0x00); /* Interrupt Enable and Mask 1 */ + smi_ext_sysctrl_write(sinfo->mmio, SMI_SCRx1B_INTR_EN_MASK_2, 0x00); /* Interrupt Enable and Mask 2 */ + smi_ext_sysctrl_write(sinfo->mmio, SMI_SCRx1F_INTR_MASK_HARD_EN, 0x00); /* Intr Mask and HW Intr Enable */ + + + /**********************************************************************/ + /* Power Down Control */ + smi_ext_powerctrl_write(sinfo->mmio, SMI_PDRx20_CTRL, 0xc4); /* Power Down Control */ + smi_ext_powerctrl_write(sinfo->mmio, SMI_PDRx21_BLOCKS_DISABLE, 0x30); /* Functionnal Blocks Disable Ctrl */ + smi_ext_powerctrl_write(sinfo->mmio, SMI_PDRx22_LCD_PANEL_CTRL, 0x02); /* LCD Panel Control Select */ + smi_ext_powerctrl_write(sinfo->mmio, SMI_PDRx23_ACT_DETECT, 0x01); /* Activity Detection Control */ + smi_ext_powerctrl_write(sinfo->mmio, SMI_PDRx24_REG_SELECT, 0x01); /* Power Down Register Select */ + + + /**********************************************************************/ + /* Flat Pannel */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRx30_FP_TYPE_SEL, 0xa8); /* Flat Panel Type Select : TFT */ + tmp = ((bpp == 8) ? 0x00 : 0x40); + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRx31_VIRT_REFRESH, (0x02 | tmp)); /* Enable CRT */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRx32_DESPE_CTRL, 0x04); + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRx33_POWER_CURSOR_CTRL, 0x05); + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRx34_ON_OFF_SEQ, 0x80); + /* Use CRT, not LCD interface */ + for (tmp = 0x3E; tmp <= 0x5A; tmp++) { + smi_ext_flatpanel_write(sinfo->mmio, tmp, 0x00); + } + /* Panel Video */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA0_HW_CTRL, 0x00); /* Panel HW Video Control */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA1_COLOR_KEY_L, 0x00); /* Color Key */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA2_COLOR_KEY_H, 0x00); + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA3_COLOR_KEY_MASK_L, 0x00); /* Color Key Mask */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA4_COLOR_KEY_MASK_H, 0x00); + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA5_RED_CONST, 0x00); /* Red Constant */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA6_GREEN_CONST, 0x00); /* Green Constant */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA7_BLUE_CONST, 0x00); /* Blue Constant */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA8_TOP_BOUND, 0x00); /* Top Boundary */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxA9_LEFT_BOUND, 0x00); /* Left Boundary */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxAA_BOT_BOUND, 0x00); /* Bottom Boundary */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxAB_RIGHT_BOUND, 0x00); /* Right Boundary */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxAC_TOP_LEFT_OVER, 0x00); /* Top and Left Boundary Overflow */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxAD_BOT_RIGHT_OVER, 0x00); /* Bottom and Right Boundary Overflow */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxAE_V_STRETCH, 0x00); /* Vertical Stretch Factor */ + smi_ext_flatpanel_write(sinfo->mmio, SMI_FPRxAF_H_STRETCH, 0x00); /* horizontal Stretch Factor */ + + + /**********************************************************************/ + /* Memory Control */ + smi_ext_memctrl_write(sinfo->mmio, SMI_MCRx60_CTRL, 0x01); /* Memory Ctrl */ + smi_ext_memctrl_write(sinfo->mmio, SMI_MCRx61_BANK_ADDR_HIGH, 0x00); + smi_ext_memctrl_write(sinfo->mmio, SMI_MCRx76_TYPE_TIME_CTRL, 0x3f); /* Memory Type and Timing Ctrl */ + + + /**********************************************************************/ + /* Clock Control */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx65_TV_ENC, 0x00); /* TV Encoder Control */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx66_RAM_CTRL, 0x03); /* RAM Control and Funcion On/Off */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx68_CLK_CTRL_1, 0x50); /* Clock Control 1 */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx69_CLK_CTRL_2, 0x03); /* Clock Control 2 */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx6A_MCLK_NUM, 0x0c); /* MCLK Numerator */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx6B_MCLK_DEN, 0x02); /* MCLK Denominator */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx6C_VCLK_NUM, 0x97); /* VCLK Numerator */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx6D_VCLK_DEN, 0x22); /* VCLK Denominator */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx6E_VCLK2_NUM, 0x09); /* VCLK2 Numerator */ + smi_ext_clkctrl_write(sinfo->mmio, SMI_CCRx6F_VCLK2_DEN, 0x02); /* VCLK2 Denominator */ + + + /**********************************************************************/ + /* General Purpose Regs */ + for (tmp = 0x70; tmp <= 0x75; tmp++) { + smi_ext_gp_write(sinfo->mmio, tmp, 0x00); + } + + /**********************************************************************/ + /* Pop-up Icon and Hardware Cursor */ + for (tmp = 0x80; tmp <= 0x93; tmp++) { + smi_ext_cursor_write(sinfo->mmio, tmp, 0x00); + } + + + + /**********************************************************************/ + /* 2D and Video Registers */ + + printk("smi_set_moderegs, setting up memmory mapped regs\n"); + + vpr = (struct vpr_regs*)sinfo->vpr; + dpr = (struct dpr_regs*)sinfo->dpr; + + /**********************************************************************/ + /* Drawing engine Control Regs */ + out_le16( &(dpr->dpr10_src_pitch), width); /* Source Row Pitch */ + out_le16( &(dpr->dpr12_dst_pitch), width); /* Destination Row Pitch */ + out_le32( &(dpr->dpr14_fg), 0x00000000); /* FG color */ + out_le32( &(dpr->dpr18_bg), 0x00000000); /* BG color */ + switch (bpp) { + case 8: val = 0x00; break; + case 16: val = 0x01; break; + case 24: val = 0x11; break; + case 32: val = 0x10; break; + default: printk(KERN_ERR "smifb: error, unsupported bit depth"); + } + out_le16( &(dpr->dpr1E_DE_format_sel), (0x0005 | (val << 4))); /* DE Data and Location Format Sel */ + out_le32( &(dpr->dpr20_col_compare), 0x00); /* Color Compare */ + out_le32( &(dpr->dpr24_col_comp_mask), 0xffffffff); /* Color Compare Mask */ + out_le16( &(dpr->dpr28_bit_mask), 0xffff); /* Bit Mask */ + out_le16( &(dpr->dpr2A_byte_mask_en), 0xffff); /* Bit Mask */ + out_le32( &(dpr->dpr34_mono_pat_low), 0x00000000); /* Mono Pattern Low */ + out_le32( &(dpr->dpr38_mono_pat_high), 0x00000000); /* Mono Pattern High */ + out_le16( &(dpr->dpr3C_xy_src), width); /* XY Addressing Source Window Width */ + out_le16( &(dpr->dpr3E_xy_dst), width); /* XY Addressing Destination Window Width */ + out_le32( &(dpr->dpr40_src_base_addr), 0x00); /* Source Base Address */ + out_le32( &(dpr->dpr44_dst_base_addr), 0x00); /* Destination Base Address */ + + + /**********************************************************************/ + /* Video Processor Control Regs */ + switch (bpp) { + case 8: val = VPR00_FMT_8P; break; /* 101 for 8 bit 3-3-2 RGB */ + case 15: val = VPR00_FMT_15P; break; /* 001 for 15 bit 5-5-5 RGB */ + case 16: val = VPR00_FMT_16P; break; /* 010 for 16 bit 5-6-5 RGB */ + case 24: val = VPR00_FMT_24P; break; /* 100 for 24 bit 8-8-8 RGB */ + case 32: val = VPR00_FMT_32P; break; /* 011 for 32 bit x-8-8-8 RGB */ + /*FIXME: Needs to support 8bit index and YUV 4:2:2 */ + default: printk(KERN_ERR "smifb: error, unsupported bit depth"); + } + tmp = ((val << 16) | (val << 8) | (val << 0)); + out_le32( &(vpr->vpr00_misc), (0x0008 | tmp)); /* Misc Graphics and Video Control : Use Window I */ + tmp = (width * bpp / 64); + out_le32( &(vpr->vpr10_data_width_extgm), (((tmp + 2) << 16) | tmp )); /* Data Src Width and Offset */ + /* Set up Window I */ + out_le32( &(vpr->win1.top_left_bound), 0x00); /* Video Win Top Left Bound */ + out_le32( &(vpr->win1.bot_right_bound), (((height & 0x07ff)<<16)|(width & 0x07ff))); /* Video Win BotRight Bound */ + out_le32( &(vpr->win1.src_addr), 0x00); /* Video Window Source Start Address */ + out_le16( &(vpr->win1.src_offset), (width * bpp / 64)); /* Video Window Source Offset */ + out_le16( &(vpr->win1.src_line_width), (width * bpp / 64)); /* Video Window Source Width */ + out_le32( &(vpr->win1.stretch), 0x00); /* Video Window Stretch Factor */ + + out_le32( &(vpr->vpr54_fifo_prio), 0x07216543); /* FIFO Priority Control */ + out_le32( &(vpr->vpr58_fifo_req_level), 0x00000444); /* FIFO Empty Request level Control */ + out_le32( &(vpr->vpr5C_yuv_to_rgb), 0x000000); /* YUV to RGB Conversion Constant */ + +} diff --git a/drivers/video/smi/smi_hw.h b/drivers/video/smi/smi_hw.h new file mode 100644 index 0000000..93599a5 --- /dev/null +++ b/drivers/video/smi/smi_hw.h @@ -0,0 +1,672 @@ +/* + * drivers/video/smi/smi_hw.h + * + * LynxEM+/EM4+(Silicon Motion Inc.) fb driver for VR5701-SG2 + * + * Author: Sergey Podstavin + * + * Modifications: Nathael Pajani + * Port to linux 2.6.22-rc5 for powerpc based board xcom9347 + * with MPC8347E processor and LYNX_3DM+ graphic chip. + * All pages are numbere according to the + * Lynx3DM+ Databook - Version 0.8 - Last updated 05/21/02 + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#ifndef __SMI_HW_H__ +#define __SMI_HW_H__ + +#include "smifb.h" + +#define PCI_VENDOR_ID_SMI 0x126f +#define PCI_DEVICE_ID_SMI_LYNX_3DM 0x0720 + + +#define LYNX3DM_DP_BASE_OFFSET 0x000000 /* 2D/3D Port Regs */ +#define LYNX3DM_DPREG_REGION_SIZE (2*1024) +#define LYNX3DM_VP_BASE_OFFSET 0x000800 /* Video Port Regs */ +#define LYNX3DM_VPREG_REGION_SIZE (2*1024) +#define LYNX3DM_CP_BASE_OFFSET 0x001000 /* Vidcap port Regs */ +#define LYNX3DM_CPREG_REGION_SIZE (2*1024) +/* ... There are many others, not supported yet. */ + +#define LYNX3DM_IO_BASE_OFFSET 0x0c0000 /* Acces to STD VGA Regs and Extended SMI Regs */ +#define LYNX3DM_MMIO_REGION_SIZE (256*1024) + +#define LYNX3DM_DPPORT_BASE_OFFSET 0x100000 /* Acces to Additionnal DE Data Port */ +#define LYNX3DM_DPPORT_REGION_SIZE (1024*1024) + +#define LYNX3DM_FB_BASE_OFFSET 0x200000 /* Frame Buffer Base offset */ +#define LYNX3DM_FB_SIZE (30*1024*1024) + + + +/* Display all the register values */ +extern void smi_print_moderegs(struct smifb_info *sinfo); + +/* Try to set up the chip's registers according to the given video mode */ +extern void smi_set_moderegs(struct smifb_info *sinfo, struct fb_var_screeninfo *video_mode); + + +struct dpr_regs { + uint16_t dpr00_src_y; /* 0x00 Source Y or K2 */ + uint16_t dpr02_src_x; /* 0x02 Source X or K1 */ + uint16_t dpr04_dst_y; /* 0x04 Destination Y or Start Y */ + uint16_t dpr06_dst_x; /* 0x06 Destination X or Start X */ + uint16_t dpr08_dim_y; /* 0x08 Dimension Y or Error Term */ + uint16_t dpr0A_dim_x; /* 0x0A Dimension X or Vector Length */ + uint16_t dpr0C_ROP_misc_ctrl; /* 0x0C ROP and Misc Control */ + uint16_t dpr0E_DE_cmd_ctrl; /* 0x0E Drawing Engine Commands and Control */ + uint16_t dpr10_src_pitch; /* 0x10 Source Row Pitch */ + uint16_t dpr12_dst_pitch; /* 0x12 Destination Row Pitch */ + + uint32_t dpr14_fg; /* 0x14 FG color */ + uint32_t dpr18_bg; /* 0x18 BG color */ + + uint16_t dpr1C_stretch_y; /* 0x1C Stretch Source Height Y */ + uint16_t dpr1E_DE_format_sel; /* 0x1E Drawing Engine DataFormat and Location Format Select */ + + uint32_t dpr20_col_compare; /* 0x20 Color Compare */ + uint32_t dpr24_col_comp_mask; /* 0x24 Color Compare Mask */ + + uint16_t dpr28_bit_mask; /* 0x28 Bit Mask */ + uint16_t dpr2A_byte_mask_en; /* 0x2A Byte Mask Enable */ + uint16_t dpr2C_scisors_left; /* 0x2C Scisors Left and Control */ + uint16_t dpr2E_scisors_top; /* 0x2E Scisors Top */ + uint16_t dpr30_scisors_right; /* 0x30 Scisors Right */ + uint16_t dpr32_scisors_bot; /* 0x32 Scisors Bottom */ + + uint32_t dpr34_mono_pat_low; /* 0x34 Mono Pattern Low */ + uint32_t dpr38_mono_pat_high; /* 0x38 Mono Pattern High */ + uint16_t dpr3C_xy_src; /* 0x3C XY Addressing Source Window Width */ + uint16_t dpr3E_xy_dst; /* 0x3E XY Addressing Destination Window Width */ + uint32_t dpr40_src_base_addr; /* 0x40 Source Base Address */ + uint32_t dpr44_dst_base_addr; /* 0x44 Destination Base Address */ +} __attribute__ ((packed)); + +/* video window formats - I=indexed, P=packed */ +#define VPR00_FMT_8I 0x00 +#define VPR00_FMT_15P 0x01 +#define VPR00_FMT_16P 0x02 +#define VPR00_FMT_32P 0x03 +#define VPR00_FMT_24P 0x04 +#define VPR00_FMT_8P 0x05 +#define VPR00_FMT_YUV422 0x06 +#define VPR00_FMT_YUV420 0x07 + +struct vpr_window { + uint32_t top_left_bound; /* Video Window Top Left Boundary */ + uint32_t bot_right_bound; /* Video Window Bottom Right Boundary */ + uint32_t src_addr; /* Video Window Source Start Address */ + uint16_t src_offset; /* Video Window Source Offset */ + uint16_t src_line_width; /* Video Window Source Line Width */ + uint32_t stretch; /* Video Window Stretch Factor */ +} __attribute__ ((packed)); + +struct vpr_regs { + uint32_t vpr00_misc; /* 0x00 Miscellaneous Graphics and Video Control */ + + uint32_t vpr04_col_key; /* 0x04 Color Keys */ + uint32_t vpr08_col_masks; /* 0x08 Color Key Masks */ + + uint32_t vpr0C_data_addr_extgm; /* 0x0C Data Source Start Address for Extended Graphics Modes */ + uint32_t vpr10_data_width_extgm; /* 0x10 Data Source Width and Offset for Extended Graphics Modes */ + + struct vpr_window win1; /* 0x14 - 0x24 */ + struct vpr_window win2; /* 0x28 - 0x38 */ + + uint32_t vpr3C_gv_ctrl2; /* 0x3C Graphics and Video Controll II */ + uint32_t vpr40_scale; /* 0x40 Graphic Scale Factor */ + uint32_t vpr44_data_src_addr; /* 0x44 */ + uint32_t vpr48_win1_chroma_addr; /* 0x48 */ + uint32_t vpr4C_win2_chroma_addr; /* 0x4C */ + uint32_t vpr50_sub_pic_src_addr; /* 0x50 */ + uint32_t vpr54_fifo_prio; /* 0x54 FIFO Priority Control */ + uint32_t vpr58_fifo_req_level; /* 0x58 FIFO Empty Request level Control */ + uint32_t vpr5C_yuv_to_rgb; /* 0x5C YUV to RGB Conversion Constant */ + uint32_t vpr60_read_scan_line; /* 0x60 Current Scan Line Position */ + uint32_t vpr64_signature_cs; /* 0x64 Signature Analyzer Control and Status */ + uint32_t empty1[2]; + uint32_t vpr_subpic_color[16]; /* 0x70 - 0xAC Sub Picture Color Look Up Register 0 to F */ + uint32_t vprB0_subpic_topleft; /* 0xB0 Sub Picture Top/Left Boundary */ + uint32_t vprB4_subpic_botright; /* 0xB4 Sub Picture Bottom/Right Boundary */ + uint32_t vprB8_subpic_src_addr; /* 0xB8 Sub Picture Source Data Address Offset and Line Width */ + uint32_t empty2[1]; + uint32_t vprC0_win1_uv_scale; /* 0xC0 Video Window 1 U/V Scale Factor */ + uint32_t vprC4_win2_scale; /* 0xC4 Video Window 2 Scale Factor */ +} __attribute__ ((packed)); + +struct cpr_regs { + uint32_t cpr00_cp_ctrl; /* 0x00 Capture Port Control */ + uint16_t cpr04_src_topclip; /* 0x04 Video Source Clipping Control */ + uint16_t cpr06_src_leftclip; /* 0x06 Video Source Clipping Control */ + uint16_t cpr08_cap_height; /* 0x08 Video Source Capture Size Control */ + uint16_t cpr0A_cap_width; /* 0x0A Video Source Capture Size Control */ + uint32_t cpr0C_buff1_start; /* 0x0C Capture Port Buffer 1 Source Start Address */ + uint32_t cpr10_buff2_start; /* 0x10 Capture Port Buffer 2 Source Start Address */ + uint32_t cpr14_src_off_addr; /* 0x14 Capture Port Source Offset Address */ + uint32_t cpr18_fifo_req_lvl; /* 0x18 Capture FIFO Empty Request Level Control */ +} __attribute__ ((packed)); + + + +#define MMIO_OUT8(p, r, d) (((volatile uint8_t *)(p))[r] = (d)) +#define MMIO_IN8(p, r) (((volatile uint8_t *)(p))[(r)]) + +static inline uint8_t VGA_READ8(uint8_t* base, unsigned int reg) +{ + return MMIO_IN8(base, reg); +} + +static inline void VGA_WRITE8(uint8_t* base, unsigned int reg, uint8_t data) +{ + MMIO_OUT8(base, reg, data); +} + + +#define SMI_USE_TEXT 0x00 +#define SMI_USE_GRAPH 0x01 + + +/**********************************************************/ +/* PCI IO mapped registers offsets */ +/* NOTE : */ +/* monochrome emulation = 3Bx, color emulation = 3Dx */ +/* */ +/**********************************************************/ + +/* Misc register ******************************************/ +#define SMI_MISC_RD 0x3cc /* Misc (read address) */ +#define SMI_MISC_WR 0x3c2 /* misc (write address) */ +#define SMI_MISC_COLOR_MODE 0x01 /* 0 = monochrome and acces of 3?x regs at 3Bx (hex) */ + /* 1 = color and acces of 3?x regs at 3Dx (hex) */ +#define SMI_MISC_ENABLE_WRITE 0x02 /* Enable Video RAM access from CPU */ + +static inline uint8_t smi_vga_misc_read(uint8_t* base) +{ + return VGA_READ8(base, SMI_MISC_RD); +} +static inline void smi_vga_misc_write(uint8_t* base, uint8_t val) +{ + BUG_ON( !(val & SMI_MISC_COLOR_MODE) ); /* See NOTE, offsets defined using color mode */ + VGA_WRITE8(base, SMI_MISC_WR, val); +} + +/* Input status register ******************************************/ +#define SMI_ISR0_RD 0x3c2 /* Input status reg 0 (rd only) */ +#define SMI_ISR1_RD 0x3da /* Input status reg 1 (rd only) */ +static inline uint8_t smi_status0_read(uint8_t* base) +{ + return VGA_READ8(base, SMI_ISR0_RD); +} +static inline uint8_t smi_status1_read(uint8_t* base) +{ + return VGA_READ8(base, SMI_ISR1_RD); +} + +/* Extended regs write protect register ******************************************/ +#define SMI_LOCK_REG 0x3c3 /* unlock/lock ext crt reg */ +#define SMI_LOCK_REG_PROTECT 0xA0 +#define SMI_LOCK_REG_WRITE_EN 0x40 +static inline void smi_unlock_extended_regs(uint8_t* base) +{ + VGA_WRITE8(base, SMI_LOCK_REG, SMI_LOCK_REG_WRITE_EN); +} +static inline void smi_lock_extended_regs(uint8_t* base) +{ + VGA_WRITE8(base, SMI_LOCK_REG, SMI_LOCK_REG_PROTECT); +} + +/* Feature Control register ******************************************/ +#define SMI_FCR_RD 0x3ca /* Feature control register (read) */ +#define SMI_FCR_WR 0x3da /* Feature control register (write) */ +static inline uint8_t smi_feature_ctrl_read(uint8_t* base) +{ + return VGA_READ8(base, SMI_FCR_RD); +} +static inline void smi_feature_ctrl_write(uint8_t* base, uint8_t val) +{ + VGA_WRITE8(base, SMI_FCR_WR, val); +} + + +/* RAMDAC Registers *****************************************/ +#define SMI_DAC_MASK 0x3c6 /* DAC mask register */ +#define SMI_DAC_RD_ADDR 0x3c7 /* DAC address read register (write only)*/ +#define SMI_DAC_STATUS 0x3c7 /* DAC status register (read only)*/ +#define SMI_DAC_WR_ADDR 0x3c8 /* DAC address write register */ +#define SMI_DAC_DATA 0x3c9 /* DAC data register.*/ +/* FIXME add support for RAMDAC */ + + + + +/**********************************************************************/ +/* Standard VGA registers */ +/**********************************************************************/ + +/**********************************************************************/ +/* Sequencer */ +#define SMI_SEQ_INDEX 0x3c4 /* Sequencer index reg */ +#define SMI_SEQ_DATA 0x3c5 /* Sequencer data reg */ + +#define SMI_SEQx00_RESET 0x00 /* Reset */ +#define SMI_SEQx01_CLK_MODE 0x01 /* Clocking Mode */ +#define SMI_SEQx02_EN_WR_PLANE 0x02 /* Enable Write Plane */ +#define SMI_SEQx03_CHAR_MAP_SEL 0x03 /* Character Map Select */ +#define SMI_SEQx04_MEM_MODE 0x04 /* Memory Mode */ +#define SMI_SEQX_MAX 0x04 + +static inline uint8_t smi_sequencer_read(uint8_t * base, uint8_t index) +{ + BUG_ON( index > SMI_SEQX_MAX ); + VGA_WRITE8(base, SMI_SEQ_INDEX, index); + return VGA_READ8(base, SMI_SEQ_DATA); +} +static inline void smi_sequencer_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( index > SMI_SEQX_MAX ); + VGA_WRITE8(base, SMI_SEQ_INDEX, index); + VGA_WRITE8(base, SMI_SEQ_DATA, data); +} + + +/**********************************************************************/ +/* CRTC Controller */ +#define SMI_CRT_INDEX 0x3d4 /* CRTC controller index reg */ +#define SMI_CRT_DATA 0x3d5 /* CRTC controller data reg */ + +#define SMI_CRTx00_H_TOTAL 0x00 /* Horizontal Total */ +#define SMI_CRTx01_H_DISPLAY_END 0x01 /* Horizontal Display End */ +#define SMI_CRTx02_H_BLANK_START 0x02 /* Horizontal Blank Start */ +#define SMI_CRTx03_H_BLANK_END 0x03 /* Horizontal Blank End */ +#define SMI_CRTx04_H_SYNC_START 0x04 /* Horizontal Sync Pulse Start */ +#define SMI_CRTx05_H_SYNC_END 0x05 /* Horizontal Sync Pulse End */ + +#define SMI_CRTx06_V_TOTAL 0x06 /* Vertical Total */ +#define SMI_CRTx12_V_DISPLAY_END 0x12 /* Vertical Display End */ +#define SMI_CRTx15_V_BLANK_START 0x15 /* Vertical Blank Start */ +#define SMI_CRTx16_V_BLANK_END 0x16 /* Vertical Blank End */ +#define SMI_CRTx10_V_SYNC_START 0x10 /* Vertical Sync Pulse Start */ +#define SMI_CRTx11_V_SYNC_END 0x11 /* Vertical Sync Pulse End */ + +#define SMI_CRTx07_OVERFLOW_VERT 0x07 /* Overflow Vertical */ +#define SMI_CRTx08_PRESET_ROW_SCAN 0x08 /* Preset Row Scan */ +#define SMI_CRTx09_MAX_SCAN_LINE 0x09 /* Maximum Scan Line */ +#define SMI_CRTx0C_DISP_START_ADDR_H 0x0C /* Display Start Address High */ +#define SMI_CRTx0D_DISP_START_ADDR_L 0x0D /* Display Start Address Low */ +#define SMI_CRTx0A_CURSOR_START 0x0A /* Cursor Start Scan Line */ +#define SMI_CRTx0B_CURSOR_END 0x0B /* Cursor End Scan Line */ +#define SMI_CRTx0E_CURSOR_ADDR_H 0x0E /* Cursor Start Address High */ +#define SMI_CRTx0F_CURSOR_ADDR_L 0x0F /* Cursor Start Address Low */ +#define SMI_CRTx13_OFFSET 0x13 /* Offset */ +#define SMI_CRTx14_UNDERLINE_LOC 0x14 /* Underline Location */ +#define SMI_CRTx17_MODE_CTRL 0x17 /* CRT Mode Control */ +#define SMI_CRTx18_LINE_COMPARE 0x18 /* Line Compare */ + +#define SMI_CRTx22_GRAPH_DATA_READBACK 0x22 /* Graphics Controller Data Latches Readback */ +#define SMI_CRTx24_ATTR_TOGGLE_READBACK 0x24 /* Attribute Controller Toggle Readback */ +#define SMI_CRTx26_ATTR_INDEX_READBACK 0x26 /* Attribute Controller Index Readback */ + +/* Extended SMI CRT */ +#define SMI_CRTx30_MODE_EN 0x30 /* CRTC Overflow and Interlace Mode Enable */ +#define SMI_CRTx31_INTL_RETRACE 0x31 /* Interlace Retrace */ +#define SMI_CRTx32_TV_V_START 0x32 /* TV Vertical Display Enable Start */ +#define SMI_CRTx33_TV_V_END_H 0x33 /* TV Vertical Display Enable End High */ +#define SMI_CRTx34_TV_V_END_L 0x34 /* TV Vertical Display Enable End Low */ +#define SMI_CRTx35_V_EXP_CONST_L 0x35 /* Vertical Screen Expansion DDA Control Constant Low */ +#define SMI_CRTx36_V_EXP_CONST_H 0x36 /* Vertical Screen Expansion DDA Control Constant High */ +#define SMI_CRTx37_TEST_SEL 0x37 /* Hardware/VGA Test Selection */ +#define SMI_CRTx38_TV_EQ_PULSE 0x38 /* TV Equalization Pulse Control */ +#define SMI_CRTx39_TV_SER_PULSE 0x39 /* TV Serration Pulse Control */ +#define SMI_CRTx3A_TV_TIMING 0x3A /* TV Total Timing Control for the Internal TV Encoder */ +#define SMI_CRTx3B_MISC_LOCK_1 0x3B /* Miscellaneous Lock 1 */ +#define SMI_CRTx3C_MISC_LOCK_2 0x3C /* Miscellaneous Lock 2 */ +#define SMI_CRTx3D_SCRATCH_BITS 0x3D /* Scratch Register Bits */ +#define SMI_CRTx3E_SCRATCH_BITS 0x3E /* Scratch Register Bits FIXME, said to be 3?4 in doc */ +#define SMI_CRTx3F_SCRATCH_BITS 0x3F /* Scratch Register Bits FIXME, said to be 3?4 in doc */ +/* CRTx9E - CRTxAD : Screen Centering - Not supported Yet */ + +/* Extended SMI Shadow -- Use with caution... read Documentation for this when using both CRT and TV */ +#define SMI_SVRx40_H_TOTAL 0x40 /* Shadow VGA Horizontal Total */ +#define SMI_SVRx41_H_BLANK_START 0x41 /* Shadow VGA Horizontal Blank Start */ +#define SMI_SVRx42_H_BLANK_END 0x42 /* Shadow VGA Horizontal Blank End */ +#define SMI_SVRx43_H_RETRACE_START 0x43 /* Shadow VGA Horizontal Retrace Start */ +#define SMI_SVRx44_H_RETRACE_END 0x44 /* Shadow VGA Horizontal Retrace End */ +#define SMI_SVRx45_V_TOTAL 0x45 /* Shadow VGA Vertical Total */ +#define SMI_SVRx46_V_BLANK_START 0x46 /* Shadow VGA Vertical Blank End */ +#define SMI_SVRx47_V_BLANK_END 0x47 /* Shadow VGA Vertical Blank End */ +#define SMI_SVRx48_V_RETRACE_START 0x48 /* Shadow VGA Vertical Retrace Start */ +#define SMI_SVRx49_V_RETRACE_END 0x49 /* Shadow VGA Vertical Retrace End */ +#define SMI_SVRx4A_V_OVERFLOW 0x4A /* Shadow VGA Vertical Overflow */ +#define SMI_SVRx4B_MAX_SCAN_LINE 0x4B /* Shadow VGA Maximum Scan Line */ +#define SMI_SVRx4C_H_DISPLAY_END 0x4C /* Shadow VGA Horizontal Display End */ +#define SMI_SVRx4D_V_DISPLAY_END 0x4D /* Shadow VGA Vertical Display End */ +#define SMI_CRTX_MAX 0x4D + +static inline uint8_t smi_crtc_read(uint8_t * base, uint8_t index) +{ + BUG_ON( index > SMI_CRTX_MAX ); + VGA_WRITE8(base, SMI_CRT_INDEX, index); + return VGA_READ8(base, SMI_CRT_DATA); +} +static inline void smi_crtc_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( index > SMI_CRTX_MAX ); + VGA_WRITE8(base, SMI_CRT_INDEX, index); + VGA_WRITE8(base, SMI_CRT_DATA, data); +} + + +/**********************************************************************/ +/* Graphics Controller */ +#define SMI_GR_INDEX 0x3ce /* Graphic controller index reg */ +#define SMI_GR_DATA 0x3cf /* Graphic controller data reg */ + +#define SMI_GRx00_SET_RESET 0x00 /* Set/Reset */ +#define SMI_GRx01_EN_SET_RESET 0x01 /* Enable Set/Reset */ +#define SMI_GRx02_COLOR_COMPARE 0x02 /* Color Compare */ +#define SMI_GRx03_DATA_ROTATE 0x03 /* Data Rotate */ +#define SMI_GRx04_READ_PLANE_SEL 0x04 /* Read Plane Select */ +#define SMI_GRx05_MODE 0x05 /* Graphics Mode */ +#define SMI_GRx06_MISC 0x06 /* Graphics Misc */ +#define SMI_GRx07_COLOR_DONT_CARE 0x07 /* Color don't care plane */ +#define SMI_GRx08_BIT_MASK 0x08 /* Bit Mask */ +#define SMI_GRX_MAX 0x08 + +static inline uint8_t smi_graphics_read(uint8_t * base, uint8_t index) +{ + BUG_ON( index > SMI_GRX_MAX ); + VGA_WRITE8(base, SMI_GR_INDEX, index); + return VGA_READ8(base, SMI_GR_DATA); +} + +static inline void smi_graphics_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( index > SMI_GRX_MAX ); + VGA_WRITE8(base, SMI_GR_INDEX, index); + VGA_WRITE8(base, SMI_GR_DATA, data); +} + + + +/**********************************************************************/ +/* Attribute Controller */ +#define SMI_ATTR_INDEX 0x3c0 /* attributes index reg */ +#define SMI_ATTR_DATA 0x3c1 /* attributes read data reg */ +#define SMI_ATTR_FLIP_FLOP 0x3da /* flip-flop */ + +#define SMI_ATTRx_PAL(x) (0x00 + (x)) /* Palette */ +#define SMI_ATTRx10_MODE 0x10 /* Attribute Mode Control */ +#define SMI_ATTRx11_OVERSCAN_COLOR 0x11 /* Overscan Color */ +#define SMI_ATTRx12_COLOR_PLANE_EN 0x12 /* Color Plane Enable */ +#define SMI_ATTRx13_H_PIX_PANNING 0x13 /* Horizontal Pixel Panning */ +#define SMI_ATTRx14_COLOR_SELECT 0x14 /* Color Select */ +#define SMI_ATTRX_MAX 0x14 + +static inline uint8_t smi_attribute_read(uint8_t * base, uint8_t index) +{ + BUG_ON( index > SMI_ATTRX_MAX ); + (void)VGA_READ8(base, SMI_ATTR_FLIP_FLOP); /* reset flip-flop */ + VGA_WRITE8(base, SMI_ATTR_INDEX, index); + return VGA_READ8(base, SMI_ATTR_DATA); +} + +static inline void smi_attribute_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( index > SMI_ATTRX_MAX ); + (void)VGA_READ8(base, SMI_ATTR_FLIP_FLOP); /* reset flip-flop */ + VGA_WRITE8(base, SMI_ATTR_INDEX, index); + VGA_WRITE8(base, SMI_ATTR_DATA, data); +} + + + + +/**********************************************************************/ +/* Extended SMI registers */ +/**********************************************************************/ + +#define SMI_EXT_INDEX 0x3c4 /* SMI Extended registers index reg */ +#define SMI_EXT_DATA 0x3c5 /* SMI Extended registers data reg */ + +/**********************************************************************/ +/* System Control */ +#define SMI_SCRX_MIN 0x15 +#define SMI_SCRx15_PCI_MISC_CTRL 0x15 /* PCI Miscellaneous Control */ +#define SMI_SCRx16_DE_VP_STATUS 0x16 /* Status for Drawing Engine and Video Processor */ +#define SMI_SCRx17_GRAPH_COMMAND_1 0x17 /* General Graphics Command Register 1 */ +#define SMI_SCRx18_GRAPH_COMMAND_2 0x18 /* General Graphics Command Register 2 */ +#define SMI_SCRx19_INTR_EN_MASK_1 0x19 /* Interrupt Enable and Mask 1 */ +#define SMI_SCRx1A_INTR_STATUS_1 0x1A /* Interrupt Status */ +#define SMI_SCRx1B_INTR_EN_MASK_2 0x1B /* Interrupt Enable and Mask 2 */ +#define SMI_SCRx1C_INTR_STATUS_2 0x1C /* Interrupt Status */ +#define SMI_SCRx1F_INTR_MASK_HARD_EN 0x1F /* Interrupt Mask and Hardware Interrupt Enable */ +#define SMI_SCRX_MAX 0x1F + +static inline uint8_t smi_ext_sysctrl_read(uint8_t * base, uint8_t index) +{ + BUG_ON( (index < SMI_SCRX_MIN) || (index > SMI_SCRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + return VGA_READ8(base, SMI_EXT_DATA); +} +static inline void smi_ext_sysctrl_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( (index < SMI_SCRX_MIN) || (index > SMI_SCRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + VGA_WRITE8(base, SMI_EXT_DATA, data); +} + +/**********************************************************************/ +/* Power Down Control */ +#define SMI_PDRX_MIN 0x20 +#define SMI_PDRx20_CTRL 0x20 /* Power Down Control for Memory, Flat Panel, PLL, and Video Port */ +#define SMI_PDRx21_BLOCKS_DISABLE 0x21 /* Functionnal Blocks Disable Control */ +#define SMI_PDRx22_LCD_PANEL_CTRL 0x22 /* LCD Panel Control Select */ +#define SMI_PDRx23_ACT_DETECT 0x23 /* Activity Detection Control */ +#define SMI_PDRx24_REG_SELECT 0x24 /* Power Down Register Select */ +#define SMI_PDRX_MAX 0x24 + +static inline uint8_t smi_ext_powerctrl_read(uint8_t * base, uint8_t index) +{ + BUG_ON( (index < SMI_PDRX_MIN) || (index > SMI_PDRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + return VGA_READ8(base, SMI_EXT_DATA); +} +static inline void smi_ext_powerctrl_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( (index < SMI_PDRX_MIN) || (index > SMI_PDRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + VGA_WRITE8(base, SMI_EXT_DATA, data); +} + +/**********************************************************************/ +/* Flat Pannel */ +#define SMI_FPRX_MIN 0x30 +#define SMI_FPRx30_FP_TYPE_SEL 0x30 /* Flat Panel Type Select */ +#define SMI_FPRx31_VIRT_REFRESH 0x31 /* Virtual Refresh and Auto Shut Down Control */ +#define SMI_FPRx32_DESPE_CTRL 0x32 /* Dithering Engine Select, Polarity, and Expansion Control */ +#define SMI_FPRx33_POWER_CURSOR_CTRL 0x33 /* Panel Power Sequence and LCD Character/Cursor Blink Control */ +#define SMI_FPRx34_ON_OFF_SEQ 0x34 /* LCD Panel ON/OFF Sequence Select and DSTN LCD Control */ + +#define SMI_FPRx3E_PANEL_HEIGHT_H 0x3E /* DSTN LCD Panel Height - High */ +#define SMI_FPRx3F_PANEL_HEIGHT_L 0x3F /* DSTN LCD Panel Height - Low */ + +#define SMI_FPRx40_RFIFO1_ADDR_L 0x40 /* Read FIFO1 Start Address Low for LCD Frame Buffer */ +#define SMI_FPRx41_RFIFO1_ADDR_H 0x41 /* Read FIFO1 Start Address High for LCD Frame Buffer */ +#define SMI_FPRx42_RFIFO2_ADDR_L 0x42 /* Read FIFO2 Start Address Low for LCD Frame Buffer */ +#define SMI_FPRx43_RFIFO2_ADDR_H 0x43 /* Read FIFO2 Start Address High for LCD Frame Buffer */ +#define SMI_FPRx44_RFIFO1_OFFSET 0x44 /* Read FIFO1 Offset Value of LCD Frame Buffer */ +#define SMI_FPRx45_RFIFO1_OVER_ADDR 0x45 /* Read FIFO1 Address Offset for LCD Frame Buffer Overflow */ +#define SMI_FPRx46_W_ADDR_L 0x46 /* Write Start Address Low of LCD Frame Buffer */ +#define SMI_FPRx47_W_ADDR_H 0x47 /* Write Start Address High of LCD Frame Buffer */ +#define SMI_FPRx48_W_OFFSET 0x48 /* Write Offset Value of LCD Frame Buffer */ +#define SMI_FPRx49_W_OVERFLOW 0x49 /* LCD Frame Buffer Write Overflow */ +#define SMI_FPRx4A_RW_REQ_LEVEL 0x4A /* LCD Read and Write FIFOs Request Level Control */ +#define SMI_FPRx4B_RFIFO2_OFFSET 0x4B /* Read FIFO2 Offset Value of LCD Frame Buffer */ +#define SMI_FPRx4C_RFIFO2_OVER_ADDR 0x4C /* Read FIFO Offset Value of LCD Frame Buffer Overflow */ +#define SMI_FPRx4D_FIFO_MSB 0x4D /* MSB Read FIFO Address */ +#define SMI_FPRx4E_LCD2_CTRL 0x4E /* LCD2 Control Register */ + +#define SMI_FPRx50_VR_OVERFLOW_1 0x50 /* LCD Overflow Register 1 for Virtual Refresh */ +#define SMI_FPRx51_VR_OVERFLOW_2 0x51 /* LCD Overflow Register 2 for Virtual Refresh */ +#define SMI_FPRx52_VR_H_TOTAL 0x52 /* LCD horizontal Total for Virtual Refresh */ +#define SMI_FPRx53_VR_H_DISP_EN 0x53 /* LCD horizontal Display Enable for Virtual Refresh */ +#define SMI_FPRx54_VR_H_SYNC_START 0x54 /* LCD horizontal Sync Start for Virtual Refresh */ +#define SMI_FPRx55_VR_V_TOTAL 0x55 /* LCD Vertical Total for Virtual Refresh */ +#define SMI_FPRx56_VR_V_DISP_EN 0x56 /* LCD Vertical Display Enable for Virtual Refresh */ +#define SMI_FPRx57_VR_V_SYNC_START 0x57 /* LCD Vertical Sync Start for Virtual Refresh */ +#define SMI_FPRx58_EMI_CTRL 0x58 /* EMI Control Register */ +#define SMI_FPRx59_M_SIGNAL 0x59 /* Panel M-Signal Control Register */ +#define SMI_FPRx5A_SYNC_PULSE_WIDTH 0x5A /* SYNC Pulse-widths Adjustment */ + +#define SMI_FPRxA0_HW_CTRL 0xA0 /* Panel HW Video Control */ +#define SMI_FPRxA1_COLOR_KEY_L 0xA1 /* Panel Video Color Key Low */ +#define SMI_FPRxA2_COLOR_KEY_H 0xA2 /* Panel Video Color Key High */ +#define SMI_FPRxA3_COLOR_KEY_MASK_L 0xA3 /* Panel Video Color Key Mask Low */ +#define SMI_FPRxA4_COLOR_KEY_MASK_H 0xA4 /* Panel Video Color Key Mask High */ +#define SMI_FPRxA5_RED_CONST 0xA5 /* Panel Video Red Constant */ +#define SMI_FPRxA6_GREEN_CONST 0xA6 /* Panel Video Green Constant */ +#define SMI_FPRxA7_BLUE_CONST 0xA7 /* Panel Video Blue Constant */ +#define SMI_FPRxA8_TOP_BOUND 0xA8 /* Panel Video Top Boundary */ +#define SMI_FPRxA9_LEFT_BOUND 0xA9 /* Panel Video Left Boundary */ +#define SMI_FPRxAA_BOT_BOUND 0xAA /* Panel Video Bottom Boundary */ +#define SMI_FPRxAB_RIGHT_BOUND 0xAB /* Panel Video Right Boundary */ +#define SMI_FPRxAC_TOP_LEFT_OVER 0xAC /* Panel Video Top and Left Boundary Overflow */ +#define SMI_FPRxAD_BOT_RIGHT_OVER 0xAD /* Panel Video Bottom and Right Boundary Overflow */ +#define SMI_FPRxAE_V_STRETCH 0xAE /* Panel Video Vertical Stretch Factor */ +#define SMI_FPRxAF_H_STRETCH 0xAF /* Panel Video horizontal Stretch Factor */ +#define SMI_FPRX_MAX 0xAF + +static inline uint8_t smi_ext_flatpanel_read(uint8_t * base, uint8_t index) +{ + BUG_ON( (index < SMI_FPRX_MIN) || (index > SMI_FPRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + return VGA_READ8(base, SMI_EXT_DATA); +} +static inline void smi_ext_flatpanel_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( (index < SMI_FPRX_MIN) || (index > SMI_FPRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + VGA_WRITE8(base, SMI_EXT_DATA, data); +} + +/**********************************************************************/ +/* Memory Control */ +#define SMI_MCRX_MIN 0x60 +#define SMI_MCRx60_CTRL 0x60 /* Memory Control */ +#define SMI_MCRx61_BANK_ADDR_HIGH 0x61 /* Memory Bank Address High */ +#define SMI_MCRx76_TYPE_TIME_CTRL 0x76 /* Memory Type and Timing Control */ +#define SMI_MCRX_MAX 0x76 + +static inline uint8_t smi_ext_memctrl_read(uint8_t * base, uint8_t index) +{ + BUG_ON( (index < SMI_MCRX_MIN) || (index > SMI_MCRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + return VGA_READ8(base, SMI_EXT_DATA); +} +static inline void smi_ext_memctrl_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( (index < SMI_MCRX_MIN) || (index > SMI_MCRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + VGA_WRITE8(base, SMI_EXT_DATA, data); +} + +/**********************************************************************/ +/* Clock Control */ +#define SMI_CCRX_MIN 0x65 +#define SMI_CCRx65_TV_ENC 0x65 /* TV Encoder Control */ +#define SMI_CCRx66_RAM_CTRL 0x66 /* RAM Control and Funcion On/Off */ +/* SMI_CCRx67 is for test purpose only */ +#define SMI_CCRx68_CLK_CTRL_1 0x68 /* Clock Control 1 */ +#define SMI_CCRx69_CLK_CTRL_2 0x69 /* Clock Control 2 */ +#define SMI_CCRx6A_MCLK_NUM 0x6A /* MCLK Numerator */ +#define SMI_CCRx6B_MCLK_DEN 0x6B /* MCLK Denominator */ +#define SMI_CCRx6C_VCLK_NUM 0x6C /* VCLK Numerator */ +#define SMI_CCRx6D_VCLK_DEN 0x6D /* VCLK Denominator */ +#define SMI_CCRx6E_VCLK2_NUM 0x6E /* VCLK2 Numerator */ +#define SMI_CCRx6F_VCLK2_DEN 0x6F /* VCLK2 Denominator */ +/* SMI_CCRx7A - SMI_CCRx7C are for TV and RAMDAC Testing Power */ +/* SMI_CCRx7D is for TV and RAMDAC Testing */ +#define SMI_CCRX_MAX 0x6F + +static inline uint8_t smi_ext_clkctrl_read(uint8_t * base, uint8_t index) +{ + BUG_ON( (index < SMI_CCRX_MIN) || (index > SMI_CCRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + return VGA_READ8(base, SMI_EXT_DATA); +} +static inline void smi_ext_clkctrl_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( (index < SMI_CCRX_MIN) || (index > SMI_CCRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + VGA_WRITE8(base, SMI_EXT_DATA, data); +} + +/**********************************************************************/ +/* General Purpose Regs */ +#define SMI_GPRX_MIN 0x70 +#define SMI_GPRx70_SCRATCH_1 0x70 /* Scratch Pad Register 1 */ +#define SMI_GPRx71_SCRATCH_2 0x71 /* Scratch Pad Register 2 */ +#define SMI_GPRx72_USER_1 0x72 /* User Defined Register 1 for DDC2/I2C */ +#define SMI_GPRx73_USER_2 0x73 /* User Defined Register 2 */ +#define SMI_GPRx74_SCRATCH_3 0x74 /* Scratch Pad Register 3 */ +#define SMI_GPRx75_SCRATCH_4 0x75 /* Scratch Pad Register 4 */ +#define SMI_GPRX_MAX 0x75 + +static inline uint8_t smi_ext_gp_read(uint8_t * base, uint8_t index) +{ + BUG_ON( (index < SMI_GPRX_MIN) || (index > SMI_GPRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + return VGA_READ8(base, SMI_EXT_DATA); +} +static inline void smi_ext_gp_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( (index < SMI_GPRX_MIN) || (index > SMI_GPRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + VGA_WRITE8(base, SMI_EXT_DATA, data); +} + +/**********************************************************************/ +/* Pop-up Icon and Hardware Cursor */ +#define SMI_PHRX_MIN 0x80 +#define SMI_PHRx80_PATERN_L 0x80 /* Pop-up Icon and Hardware Cursor Pattern Location Low */ +#define SMI_PHRx81_EN_PATERN_H 0x81 /* Hardware Cursor Enable & PI/HWC Pattern Location High */ + +#define SMI_POPx82_POP_CTRL 0x82 /* Pop-up Icon Control */ +/* SMI_POPx83 is reserved */ +#define SMI_POPx84_POP_COLOR_1 0x84 /* Pop-up Icon Color 1 */ +#define SMI_POPx85_POP_COLOR_2 0x85 /* Pop-up Icon Color 2 */ +#define SMI_POPx86_POP_COLOR_3 0x86 /* Pop-up Icon Color 3 */ +#define SMI_POPx90_POP_X_L 0x90 /* Pop-up Icon Start X Low */ +#define SMI_POPx91_POP_X_H 0x91 /* Pop-up Icon Start X High */ +#define SMI_POPx92_POP_Y_L 0x92 /* Pop-up Icon Start Y Low */ +#define SMI_POPx93_POP_Y_H 0x93 /* Pop-up Icon Start Y High */ + +#define SMI_HCRx88_HC_X_L 0x88 /* Hardware Cursor Upper Left X Position Low */ +#define SMI_HCRx89_HC_X_H 0x89 /* Hardware Cursor Upper Left X Position High */ +#define SMI_HCRx8A_HC_Y_L 0x8A /* Hardware Cursor Upper Left Y Position Low */ +#define SMI_HCRx8B_HC_Y_H 0x8B /* Hardware Cursor Upper Left Y Position High */ +#define SMI_HCRx8C_HC_FOREGROUND 0x8C /* Hardware Cursor Foreground Color */ +#define SMI_HCRx8D_HC_BACKGROUND 0x8D /* Hardware Cursor Background Color */ +#define SMI_PHRX_MAX 0x93 + +static inline uint8_t smi_ext_cursor_read(uint8_t * base, uint8_t index) +{ + BUG_ON( (index < SMI_PHRX_MIN) || (index > SMI_PHRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + return VGA_READ8(base, SMI_EXT_DATA); +} +static inline void smi_ext_cursor_write(uint8_t * base, uint8_t index, uint8_t data) +{ + BUG_ON( (index < SMI_PHRX_MIN) || (index > SMI_PHRX_MAX) ); + VGA_WRITE8(base, SMI_EXT_INDEX, index); + VGA_WRITE8(base, SMI_EXT_DATA, data); +} + + +#endif /* __SMI_HW_H__ */ + diff --git a/drivers/video/smi/smifb.h b/drivers/video/smi/smifb.h new file mode 100644 index 0000000..7b761cc --- /dev/null +++ b/drivers/video/smi/smifb.h @@ -0,0 +1,64 @@ +/* + * drivers/video/smi/smifb.h + * + * LynxEM+/EM4+(Silicon Motion Inc.) fb driver for VR5701-SG2 + * + * Author: Sergey Podstavin + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#ifndef __SMIFB_H__ +#define __SMIFB_H__ + +typedef struct { + unsigned char red, green, blue, transp; +} smi_cfb8_cmap_t; + +struct smifb_info { + struct fb_info info; /* kernel framebuffer info */ + const char *drvr_name; /* Silicon Motion hardware board type */ + struct pci_dev *pd; /* descripbe the PCI device */ + unsigned long base_phys; /* physical base address */ + + /* PCI base physical addresses */ + unsigned long fb_base_phys; /* physical Frame Buffer base address */ + unsigned long dpr_base_phys; /* physical Drawing Processor base address */ + unsigned long vpr_base_phys; /* physical Video Processor base address */ + unsigned long cpr_base_phys; /* physical Capture Processor base address */ + unsigned long mmio_base_phys; /* physical MMIO space (VGA + SMI regs ?) base address */ + unsigned long dpport_base_phys; /* physical Drawing Processor Data Port base address */ + int dpport_size; /* size of Drawin Processor Data Port memory space */ + + /* PCI base virtual addresses */ + caddr_t base; /* address of base */ + caddr_t fb_base; /* address of frame buffer base */ + caddr_t dpr; /* Drawing Processor Registers */ + caddr_t vpr; /* Video Processor Registers */ + caddr_t cpr; /* Capture Processor Registers */ + caddr_t mmio; /* Memory Mapped I/O Port */ + caddr_t dpport; /* Drawing Processor Data */ + + int fbsize; /* Frame-Buffer memory size */ + + /* some flags */ + int flag; + + /* current mode */ + int bpp, depth; + u32 visual; + int xres, yres, pitch; + int pixclock; + + /* current pipe */ + int pipe; + + /* initial parameters */ + struct fb_var_screeninfo* initial_fb_var; + +}; + +#endif /* __SMIFB_H__ */