diff options
author | Paul Mundt | 2011-05-24 15:32:20 +0900 |
---|---|---|
committer | Paul Mundt | 2011-05-24 15:32:20 +0900 |
commit | 9fb4c7fbbcb1e947567d13b82e429ae47a46e337 (patch) | |
tree | 6c5f11f347d0f58565381f92680a7a9cc63c0bd8 /drivers/video | |
parent | dc3e5b6a6e842116ec2436161adf31877f09b6b9 (diff) | |
parent | d762f4383100c2a87b1a3f2d678cd3b5425655b4 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/video')
29 files changed, 892 insertions, 828 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index e2126b5af1de..1d0aa5eb10b9 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -8,9 +8,6 @@ menu "Graphics support" config HAVE_FB_ATMEL bool -config HAVE_FB_IMX - bool - config SH_MIPI_DSI tristate depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK @@ -359,7 +356,7 @@ config FB_SA1100 config FB_IMX tristate "Freescale i.MX LCD support" - depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2) + depends on FB && IMX_HAVE_PLATFORM_IMX_FB select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -1570,6 +1567,17 @@ config FB_VIA_DIRECT_PROCFS correct output device configuration. Its use is strongly discouraged. +config FB_VIA_X_COMPATIBILITY + bool "X server compatibility" + depends on FB_VIA + default n + help + This option reduces the functionality (power saving, ...) of the + framebuffer to avoid negative impact on the OpenChrome X server. + If you use any X server other than fbdev you should enable this + otherwise it should be safe to disable it and allow using all + features. + endif config FB_NEOMAGIC diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 82acb8dc4aa1..6183a57eb69d 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -66,7 +66,7 @@ * have. Allow 1% either way on the nominal for TVs. */ #define NR_MONTYPES 6 -static struct fb_monspecs monspecs[NR_MONTYPES] __initdata = { +static struct fb_monspecs monspecs[NR_MONTYPES] __devinitdata = { { /* TV */ .hfmin = 15469, .hfmax = 15781, @@ -873,7 +873,7 @@ static struct fb_ops acornfb_ops = { /* * Everything after here is initialisation!!! */ -static struct fb_videomode modedb[] __initdata = { +static struct fb_videomode modedb[] __devinitdata = { { /* 320x256 @ 50Hz */ NULL, 50, 320, 256, 125000, 92, 62, 35, 19, 38, 2, FB_SYNC_COMP_HIGH_ACT, @@ -925,8 +925,7 @@ static struct fb_videomode modedb[] __initdata = { } }; -static struct fb_videomode __initdata -acornfb_default_mode = { +static struct fb_videomode acornfb_default_mode __devinitdata = { .name = NULL, .refresh = 60, .xres = 640, @@ -942,7 +941,7 @@ acornfb_default_mode = { .vmode = FB_VMODE_NONINTERLACED }; -static void __init acornfb_init_fbinfo(void) +static void __devinit acornfb_init_fbinfo(void) { static int first = 1; @@ -1018,8 +1017,7 @@ static void __init acornfb_init_fbinfo(void) * size can optionally be followed by 'M' or 'K' for * MB or KB respectively. */ -static void __init -acornfb_parse_mon(char *opt) +static void __devinit acornfb_parse_mon(char *opt) { char *p = opt; @@ -1066,8 +1064,7 @@ bad: current_par.montype = -1; } -static void __init -acornfb_parse_montype(char *opt) +static void __devinit acornfb_parse_montype(char *opt) { current_par.montype = -2; @@ -1108,8 +1105,7 @@ acornfb_parse_montype(char *opt) } } -static void __init -acornfb_parse_dram(char *opt) +static void __devinit acornfb_parse_dram(char *opt) { unsigned int size; @@ -1134,15 +1130,14 @@ acornfb_parse_dram(char *opt) static struct options { char *name; void (*parse)(char *opt); -} opt_table[] __initdata = { +} opt_table[] __devinitdata = { { "mon", acornfb_parse_mon }, { "montype", acornfb_parse_montype }, { "dram", acornfb_parse_dram }, { NULL, NULL } }; -int __init -acornfb_setup(char *options) +static int __devinit acornfb_setup(char *options) { struct options *optp; char *opt; @@ -1179,8 +1174,7 @@ acornfb_setup(char *options) * Detect type of monitor connected * For now, we just assume SVGA */ -static int __init -acornfb_detect_monitortype(void) +static int __devinit acornfb_detect_monitortype(void) { return 4; } diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c index 5b2b5ef4edba..64e41f5448c4 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/atafb.c @@ -3117,7 +3117,7 @@ int __init atafb_init(void) atafb_ops.fb_setcolreg = &falcon_setcolreg; error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher, IRQ_TYPE_PRIO, - "framebuffer/modeswitch", + "framebuffer:modeswitch", falcon_vbl_switcher); if (error) return error; diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index dd0e84a9bd2f..cca43c06d3c8 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -333,7 +333,7 @@ static void __exit ltv350qv_exit(void) module_init(ltv350qv_init); module_exit(ltv350qv_exit); -MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); +MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("spi:ltv350qv"); diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 3772433c49d1..93317b5b8740 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -6,7 +6,7 @@ * * This driver is based on sgicons.c and cons_newport. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) */ #include <linux/init.h> diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index e0c2284924b6..5aac00eb1830 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -42,9 +42,34 @@ #define FBPIXMAPSIZE (1024 * 8) +static DEFINE_MUTEX(registration_lock); struct fb_info *registered_fb[FB_MAX] __read_mostly; int num_registered_fb __read_mostly; +static struct fb_info *get_fb_info(unsigned int idx) +{ + struct fb_info *fb_info; + + if (idx >= FB_MAX) + return ERR_PTR(-ENODEV); + + mutex_lock(®istration_lock); + fb_info = registered_fb[idx]; + if (fb_info) + atomic_inc(&fb_info->count); + mutex_unlock(®istration_lock); + + return fb_info; +} + +static void put_fb_info(struct fb_info *fb_info) +{ + if (!atomic_dec_and_test(&fb_info->count)) + return; + if (fb_info->fbops->fb_destroy) + fb_info->fbops->fb_destroy(fb_info); +} + int lock_fb_info(struct fb_info *info) { mutex_lock(&info->lock); @@ -647,6 +672,7 @@ int fb_show_logo(struct fb_info *info, int rotate) { return 0; } static void *fb_seq_start(struct seq_file *m, loff_t *pos) { + mutex_lock(®istration_lock); return (*pos < FB_MAX) ? pos : NULL; } @@ -658,6 +684,7 @@ static void *fb_seq_next(struct seq_file *m, void *v, loff_t *pos) static void fb_seq_stop(struct seq_file *m, void *v) { + mutex_unlock(®istration_lock); } static int fb_seq_show(struct seq_file *m, void *v) @@ -690,13 +717,30 @@ static const struct file_operations fb_proc_fops = { .release = seq_release, }; -static ssize_t -fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +/* + * We hold a reference to the fb_info in file->private_data, + * but if the current registered fb has changed, we don't + * actually want to use it. + * + * So look up the fb_info using the inode minor number, + * and just verify it against the reference we have. + */ +static struct fb_info *file_fb_info(struct file *file) { - unsigned long p = *ppos; struct inode *inode = file->f_path.dentry->d_inode; int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; + + if (info != file->private_data) + info = NULL; + return info; +} + +static ssize_t +fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; + struct fb_info *info = file_fb_info(file); u8 *buffer, *dst; u8 __iomem *src; int c, cnt = 0, err = 0; @@ -761,9 +805,7 @@ static ssize_t fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; - struct inode *inode = file->f_path.dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info *info = file_fb_info(file); u8 *buffer, *src; u8 __iomem *dst; int c, cnt = 0, err = 0; @@ -1141,10 +1183,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info *info = file_fb_info(file); + if (!info) + return -ENODEV; return do_fb_ioctl(info, cmd, arg); } @@ -1265,12 +1307,13 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, static long fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; - struct fb_ops *fb = info->fbops; + struct fb_info *info = file_fb_info(file); + struct fb_ops *fb; long ret = -ENOIOCTLCMD; + if (!info) + return -ENODEV; + fb = info->fbops; switch(cmd) { case FBIOGET_VSCREENINFO: case FBIOPUT_VSCREENINFO: @@ -1303,16 +1346,18 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, static int fb_mmap(struct file *file, struct vm_area_struct * vma) { - int fbidx = iminor(file->f_path.dentry->d_inode); - struct fb_info *info = registered_fb[fbidx]; - struct fb_ops *fb = info->fbops; + struct fb_info *info = file_fb_info(file); + struct fb_ops *fb; unsigned long off; unsigned long start; u32 len; + if (!info) + return -ENODEV; if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; off = vma->vm_pgoff << PAGE_SHIFT; + fb = info->fbops; if (!fb) return -ENODEV; mutex_lock(&info->mm_lock); @@ -1361,14 +1406,16 @@ __releases(&info->lock) struct fb_info *info; int res = 0; - if (fbidx >= FB_MAX) - return -ENODEV; - info = registered_fb[fbidx]; - if (!info) + info = get_fb_info(fbidx); + if (!info) { request_module("fb%d", fbidx); - info = registered_fb[fbidx]; - if (!info) - return -ENODEV; + info = get_fb_info(fbidx); + if (!info) + return -ENODEV; + } + if (IS_ERR(info)) + return PTR_ERR(info); + mutex_lock(&info->lock); if (!try_module_get(info->fbops->owner)) { res = -ENODEV; @@ -1386,6 +1433,8 @@ __releases(&info->lock) #endif out: mutex_unlock(&info->lock); + if (res) + put_fb_info(info); return res; } @@ -1401,6 +1450,7 @@ __releases(&info->lock) info->fbops->fb_release(info,1); module_put(info->fbops->owner); mutex_unlock(&info->lock); + put_fb_info(info); return 0; } @@ -1487,8 +1537,10 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena, return false; } +static int do_unregister_framebuffer(struct fb_info *fb_info); + #define VGA_FB_PHYS 0xA0000 -void remove_conflicting_framebuffers(struct apertures_struct *a, +static void do_remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary) { int i; @@ -1510,43 +1562,32 @@ void remove_conflicting_framebuffers(struct apertures_struct *a, printk(KERN_INFO "fb: conflicting fb hw usage " "%s vs %s - removing generic driver\n", name, registered_fb[i]->fix.id); - unregister_framebuffer(registered_fb[i]); + do_unregister_framebuffer(registered_fb[i]); } } } -EXPORT_SYMBOL(remove_conflicting_framebuffers); -/** - * register_framebuffer - registers a frame buffer device - * @fb_info: frame buffer info structure - * - * Registers a frame buffer device @fb_info. - * - * Returns negative errno on error, or zero for success. - * - */ - -int -register_framebuffer(struct fb_info *fb_info) +static int do_register_framebuffer(struct fb_info *fb_info) { int i; struct fb_event event; struct fb_videomode mode; - if (num_registered_fb == FB_MAX) - return -ENXIO; - if (fb_check_foreignness(fb_info)) return -ENOSYS; - remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, + do_remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, fb_is_primary_device(fb_info)); + if (num_registered_fb == FB_MAX) + return -ENXIO; + num_registered_fb++; for (i = 0 ; i < FB_MAX; i++) if (!registered_fb[i]) break; fb_info->node = i; + atomic_set(&fb_info->count, 1); mutex_init(&fb_info->lock); mutex_init(&fb_info->mm_lock); @@ -1592,36 +1633,14 @@ register_framebuffer(struct fb_info *fb_info) return 0; } - -/** - * unregister_framebuffer - releases a frame buffer device - * @fb_info: frame buffer info structure - * - * Unregisters a frame buffer device @fb_info. - * - * Returns negative errno on error, or zero for success. - * - * This function will also notify the framebuffer console - * to release the driver. - * - * This is meant to be called within a driver's module_exit() - * function. If this is called outside module_exit(), ensure - * that the driver implements fb_open() and fb_release() to - * check that no processes are using the device. - */ - -int -unregister_framebuffer(struct fb_info *fb_info) +static int do_unregister_framebuffer(struct fb_info *fb_info) { struct fb_event event; int i, ret = 0; i = fb_info->node; - if (!registered_fb[i]) { - ret = -EINVAL; - goto done; - } - + if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) + return -EINVAL; if (!lock_fb_info(fb_info)) return -ENODEV; @@ -1629,16 +1648,14 @@ unregister_framebuffer(struct fb_info *fb_info) ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); unlock_fb_info(fb_info); - if (ret) { - ret = -EINVAL; - goto done; - } + if (ret) + return -EINVAL; if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); fb_destroy_modelist(&fb_info->modelist); - registered_fb[i]=NULL; + registered_fb[i] = NULL; num_registered_fb--; fb_cleanup_device(fb_info); device_destroy(fb_class, MKDEV(FB_MAJOR, i)); @@ -1646,9 +1663,65 @@ unregister_framebuffer(struct fb_info *fb_info) fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); /* this may free fb info */ - if (fb_info->fbops->fb_destroy) - fb_info->fbops->fb_destroy(fb_info); -done: + put_fb_info(fb_info); + return 0; +} + +void remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) +{ + mutex_lock(®istration_lock); + do_remove_conflicting_framebuffers(a, name, primary); + mutex_unlock(®istration_lock); +} +EXPORT_SYMBOL(remove_conflicting_framebuffers); + +/** + * register_framebuffer - registers a frame buffer device + * @fb_info: frame buffer info structure + * + * Registers a frame buffer device @fb_info. + * + * Returns negative errno on error, or zero for success. + * + */ +int +register_framebuffer(struct fb_info *fb_info) +{ + int ret; + + mutex_lock(®istration_lock); + ret = do_register_framebuffer(fb_info); + mutex_unlock(®istration_lock); + + return ret; +} + +/** + * unregister_framebuffer - releases a frame buffer device + * @fb_info: frame buffer info structure + * + * Unregisters a frame buffer device @fb_info. + * + * Returns negative errno on error, or zero for success. + * + * This function will also notify the framebuffer console + * to release the driver. + * + * This is meant to be called within a driver's module_exit() + * function. If this is called outside module_exit(), ensure + * that the driver implements fb_open() and fb_release() to + * check that no processes are using the device. + */ +int +unregister_framebuffer(struct fb_info *fb_info) +{ + int ret; + + mutex_lock(®istration_lock); + ret = do_unregister_framebuffer(fb_info); + mutex_unlock(®istration_lock); + return ret; } diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index ef72cb483834..d2ccfd6e662c 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -65,12 +65,6 @@ #define CPOS_OP (1<<28) #define CPOS_CXP(x) (((x) & 3ff) << 16) -#ifdef CONFIG_ARCH_MX1 -#define CPOS_CYP(y) ((y) & 0x1ff) -#else -#define CPOS_CYP(y) ((y) & 0x3ff) -#endif - #define LCDC_LCWHB 0x10 #define LCWHB_BK_EN (1<<31) #define LCWHB_CW(w) (((w) & 0x1f) << 24) @@ -79,16 +73,6 @@ #define LCDC_LCHCC 0x14 -#ifdef CONFIG_ARCH_MX1 -#define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11) -#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5) -#define LCHCC_CUR_COL_B(b) ((b) & 0x1f) -#else -#define LCHCC_CUR_COL_R(r) (((r) & 0x3f) << 12) -#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 6) -#define LCHCC_CUR_COL_B(b) ((b) & 0x3f) -#endif - #define LCDC_PCR 0x18 #define LCDC_HCR 0x1C @@ -115,11 +99,7 @@ #define LCDC_RMCR 0x34 -#ifdef CONFIG_ARCH_MX1 -#define RMCR_LCDC_EN (1<<1) -#else -#define RMCR_LCDC_EN 0 -#endif +#define RMCR_LCDC_EN_MX1 (1<<1) #define RMCR_SELF_REF (1<<0) @@ -536,7 +516,11 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1), fbi->regs + LCDC_CPOS); - writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR); + /* + * RMCR_LCDC_EN_MX1 is present on i.MX1 only, but doesn't hurt + * on other SoCs + */ + writel(RMCR_LCDC_EN_MX1, fbi->regs + LCDC_RMCR); clk_enable(fbi->clk); diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index b66d86ac7cea..178b0720bd79 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c @@ -679,7 +679,7 @@ static int __devinit mddi_probe(struct platform_device *pdev) printk(KERN_ERR "mddi: no associated mem resource!\n"); return -ENOMEM; } - mddi->base = ioremap(resource->start, resource->end - resource->start); + mddi->base = ioremap(resource->start, resource_size(resource)); if (!mddi->base) { printk(KERN_ERR "mddi: failed to remap base!\n"); ret = -EINVAL; diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 7d0284882984..0b2f2dd41416 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -401,7 +401,7 @@ static int mxsfb_set_par(struct fb_info *fb_info) writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET); ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER | - CTRL_SET_BUS_WIDTH(host->ld_intf_width);; + CTRL_SET_BUS_WIDTH(host->ld_intf_width); switch (fb_info->var.bits_per_pixel) { case 16: diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index a2e5b5100ab4..0f4e8c942f9e 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1648,7 +1648,9 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) switch (val) { case CPUFREQ_PRECHANGE: - if (!fbi->overlay[0].usage && !fbi->overlay[1].usage) +#ifdef CONFIG_FB_PXA_OVERLAY + if (!(fbi->overlay[0].usage || fbi->overlay[1].usage)) +#endif set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); break; diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c index 68041d9dc260..695066b5b2e6 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/udlfb.c @@ -27,6 +27,7 @@ #include <linux/fb.h> #include <linux/vmalloc.h> #include <linux/slab.h> +#include <linux/prefetch.h> #include <linux/delay.h> #include <video/udlfb.h> #include "edid.h" diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile index 96f01ee2a412..5108136e8776 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/via/Makefile @@ -6,4 +6,4 @@ obj-$(CONFIG_FB_VIA) += viafb.o viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ - via-core.o via-gpio.o via_modesetting.o + via-core.o via-gpio.o via_modesetting.o via_clock.o diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index 29d70244a21f..3ebf20c06eef 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h @@ -137,17 +137,11 @@ struct chip_information { struct lvds_chip_information lvds_chip_info2; }; -struct crt_setting_information { - int iga_path; -}; - struct tmds_setting_information { int iga_path; int h_active; int v_active; int max_pixel_clock; - int max_hres; - int max_vres; }; struct lvds_setting_information { diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 41ca198b5098..b1f364745ca0 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -28,17 +28,11 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); static void __devinit dvi_get_panel_size_from_DDCv1( struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting); -static void __devinit dvi_get_panel_size_from_DDCv2( - struct tmds_chip_information *tmds_chip, - struct tmds_setting_information *tmds_setting); static int viafb_dvi_query_EDID(void); -static int check_tmds_chip(int device_id_subaddr, int device_id) +static inline bool check_tmds_chip(int device_id_subaddr, int device_id) { - if (tmds_register_read(device_id_subaddr) == device_id) - return OK; - else - return FAIL; + return tmds_register_read(device_id_subaddr) == device_id; } void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, @@ -47,22 +41,13 @@ void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); viafb_dvi_sense(); - switch (viafb_dvi_query_EDID()) { - case 1: + if (viafb_dvi_query_EDID() == 1) dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting); - break; - case 2: - dvi_get_panel_size_from_DDCv2(tmds_chip, tmds_setting); - break; - default: - printk(KERN_WARNING "viafb_init_dvi_size: DVI panel size undetected!\n"); - break; - } return; } -int __devinit viafb_tmds_trasmitter_identify(void) +bool __devinit viafb_tmds_trasmitter_identify(void) { unsigned char sr2a = 0, sr1e = 0, sr3e = 0; @@ -101,7 +86,7 @@ int __devinit viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info-> tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31; - if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { + if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) { /* * Currently only support 12bits,dual edge,add 24bits mode later */ @@ -112,11 +97,10 @@ int __devinit viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info->tmds_chip_info.i2c_port); - return OK; + return true; } else { viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C; - if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) - != FAIL) { + if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) { tmds_register_write(0x08, 0x3b); DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n"); DEBUG_MSG(KERN_INFO "\n %2d", @@ -125,7 +109,7 @@ int __devinit viafb_tmds_trasmitter_identify(void) DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info-> tmds_chip_info.i2c_port); - return OK; + return true; } } @@ -135,7 +119,7 @@ int __devinit viafb_tmds_trasmitter_identify(void) ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) || (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) { DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n"); - return OK; + return true; } switch (viaparinfo->chip_info->gfx_chip_name) { @@ -159,7 +143,7 @@ int __devinit viafb_tmds_trasmitter_identify(void) tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER; viaparinfo->chip_info->tmds_chip_info. tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; - return FAIL; + return false; } static void tmds_register_write(int index, u8 data) @@ -306,12 +290,7 @@ static int viafb_dvi_query_EDID(void) return EDID_VERSION_1; /* Found EDID1 Table */ } - data0 = (u8) tmds_register_read(0x00); - viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; - if (data0 == 0x20) - return EDID_VERSION_2; /* Found EDID2 Table */ - else - return false; + return false; } /* Get Panel Size Using EDID1 Table */ @@ -319,50 +298,15 @@ static void __devinit dvi_get_panel_size_from_DDCv1( struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting) { - int i, max_h = 0, tmp, restore; - unsigned char rData; + int i, restore; unsigned char EDID_DATA[18]; DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n"); restore = tmds_chip->tmds_chip_slave_addr; tmds_chip->tmds_chip_slave_addr = 0xA0; - - rData = tmds_register_read(0x23); - if (rData & 0x3C) - max_h = 640; - if (rData & 0xC0) - max_h = 720; - if (rData & 0x03) - max_h = 800; - - rData = tmds_register_read(0x24); - if (rData & 0xC0) - max_h = 800; - if (rData & 0x1E) - max_h = 1024; - if (rData & 0x01) - max_h = 1280; - for (i = 0x25; i < 0x6D; i++) { switch (i) { - case 0x26: - case 0x28: - case 0x2A: - case 0x2C: - case 0x2E: - case 0x30: - case 0x32: - case 0x34: - rData = tmds_register_read(i); - if (rData == 1) - break; - /* data = (data + 31) * 8 */ - tmp = (rData + 31) << 3; - if (tmp > max_h) - max_h = tmp; - break; - case 0x36: case 0x48: case 0x5A: @@ -383,91 +327,11 @@ static void __devinit dvi_get_panel_size_from_DDCv1( } } - tmds_setting->max_hres = max_h; - switch (max_h) { - case 640: - tmds_setting->max_vres = 480; - break; - case 800: - tmds_setting->max_vres = 600; - break; - case 1024: - tmds_setting->max_vres = 768; - break; - case 1280: - tmds_setting->max_vres = 1024; - break; - case 1400: - tmds_setting->max_vres = 1050; - break; - case 1440: - tmds_setting->max_vres = 1050; - break; - case 1600: - tmds_setting->max_vres = 1200; - break; - case 1920: - tmds_setting->max_vres = 1080; - break; - default: - DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d ! " - "set default panel size.\n", max_h); - break; - } - DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n", tmds_setting->max_pixel_clock); tmds_chip->tmds_chip_slave_addr = restore; } -/* Get Panel Size Using EDID2 Table */ -static void __devinit dvi_get_panel_size_from_DDCv2( - struct tmds_chip_information *tmds_chip, - struct tmds_setting_information *tmds_setting) -{ - int restore; - unsigned char R_Buffer[2]; - - DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n"); - - restore = tmds_chip->tmds_chip_slave_addr; - tmds_chip->tmds_chip_slave_addr = 0xA2; - - /* Horizontal: 0x76, 0x77 */ - tmds_register_read_bytes(0x76, R_Buffer, 2); - tmds_setting->max_hres = R_Buffer[0] + (R_Buffer[1] << 8); - - switch (tmds_setting->max_hres) { - case 640: - tmds_setting->max_vres = 480; - break; - case 800: - tmds_setting->max_vres = 600; - break; - case 1024: - tmds_setting->max_vres = 768; - break; - case 1280: - tmds_setting->max_vres = 1024; - break; - case 1400: - tmds_setting->max_vres = 1050; - break; - case 1440: - tmds_setting->max_vres = 1050; - break; - case 1600: - tmds_setting->max_vres = 1200; - break; - default: - DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d! " - "set default panel size.\n", tmds_setting->max_hres); - break; - } - - tmds_chip->tmds_chip_slave_addr = restore; -} - /* If Disable DVI, turn off pad */ void viafb_dvi_disable(void) { diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h index 2c525c0c1adb..f473dd010977 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/via/dvi.h @@ -56,7 +56,7 @@ int viafb_dvi_sense(void); void viafb_dvi_disable(void); void viafb_dvi_enable(void); -int __devinit viafb_tmds_trasmitter_identify(void); +bool __devinit viafb_tmds_trasmitter_identify(void); void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting); void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c index 1ee511b73307..e10d8249534c 100644 --- a/drivers/video/via/global.c +++ b/drivers/video/via/global.c @@ -40,10 +40,6 @@ int viafb_hotplug_Yres = 480; int viafb_hotplug_bpp = 32; int viafb_hotplug_refresh = 60; int viafb_primary_dev = None_Device; -unsigned int viafb_second_xres = 640; -unsigned int viafb_second_yres = 480; -unsigned int viafb_second_virtual_xres; -unsigned int viafb_second_virtual_yres; int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1; struct fb_info *viafbinfo; struct fb_info *viafbinfo1; diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index 38ef5ac66953..ff969dc34593 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h @@ -73,8 +73,6 @@ extern int viafb_hotplug_bpp; extern int viafb_hotplug_refresh; extern int viafb_primary_dev; -extern unsigned int viafb_second_xres; -extern unsigned int viafb_second_yres; extern int viafb_lcd_panel_id; #endif /* __GLOBAL_H__ */ diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 980e263f1875..47b13535ed2b 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -20,274 +20,84 @@ */ #include <linux/via-core.h> +#include <asm/olpc.h> #include "global.h" - -static struct pll_config cle266_pll_config[] = { - {19, 4, 0}, - {26, 5, 0}, - {28, 5, 0}, - {31, 5, 0}, - {33, 5, 0}, - {55, 5, 0}, - {102, 5, 0}, - {53, 6, 0}, - {92, 6, 0}, - {98, 6, 0}, - {112, 6, 0}, - {41, 7, 0}, - {60, 7, 0}, - {99, 7, 0}, - {100, 7, 0}, - {83, 8, 0}, - {86, 8, 0}, - {108, 8, 0}, - {87, 9, 0}, - {118, 9, 0}, - {95, 12, 0}, - {115, 12, 0}, - {108, 13, 0}, - {83, 17, 0}, - {67, 20, 0}, - {86, 20, 0}, - {98, 20, 0}, - {121, 24, 0}, - {99, 29, 0}, - {33, 3, 1}, - {15, 4, 1}, - {23, 4, 1}, - {37, 5, 1}, - {83, 5, 1}, - {85, 5, 1}, - {94, 5, 1}, - {103, 5, 1}, - {109, 5, 1}, - {113, 5, 1}, - {121, 5, 1}, - {82, 6, 1}, - {31, 7, 1}, - {55, 7, 1}, - {84, 7, 1}, - {83, 8, 1}, - {76, 9, 1}, - {127, 9, 1}, - {33, 4, 2}, - {75, 4, 2}, - {119, 4, 2}, - {121, 4, 2}, - {91, 5, 2}, - {118, 5, 2}, - {83, 6, 2}, - {109, 6, 2}, - {90, 7, 2}, - {93, 2, 3}, - {53, 3, 3}, - {73, 4, 3}, - {89, 4, 3}, - {105, 4, 3}, - {117, 4, 3}, - {101, 5, 3}, - {121, 5, 3}, - {127, 5, 3}, - {99, 7, 3} +#include "via_clock.h" + +static struct pll_limit cle266_pll_limits[] = { + {19, 19, 4, 0}, + {26, 102, 5, 0}, + {53, 112, 6, 0}, + {41, 100, 7, 0}, + {83, 108, 8, 0}, + {87, 118, 9, 0}, + {95, 115, 12, 0}, + {108, 108, 13, 0}, + {83, 83, 17, 0}, + {67, 98, 20, 0}, + {121, 121, 24, 0}, + {99, 99, 29, 0}, + {33, 33, 3, 1}, + {15, 23, 4, 1}, + {37, 121, 5, 1}, + {82, 82, 6, 1}, + {31, 84, 7, 1}, + {83, 83, 8, 1}, + {76, 127, 9, 1}, + {33, 121, 4, 2}, + {91, 118, 5, 2}, + {83, 109, 6, 2}, + {90, 90, 7, 2}, + {93, 93, 2, 3}, + {53, 53, 3, 3}, + {73, 117, 4, 3}, + {101, 127, 5, 3}, + {99, 99, 7, 3} }; -static struct pll_config k800_pll_config[] = { - {22, 2, 0}, - {28, 3, 0}, - {81, 3, 1}, - {85, 3, 1}, - {98, 3, 1}, - {112, 3, 1}, - {86, 4, 1}, - {166, 4, 1}, - {109, 5, 1}, - {113, 5, 1}, - {121, 5, 1}, - {131, 5, 1}, - {143, 5, 1}, - {153, 5, 1}, - {66, 3, 2}, - {68, 3, 2}, - {95, 3, 2}, - {106, 3, 2}, - {116, 3, 2}, - {93, 4, 2}, - {119, 4, 2}, - {121, 4, 2}, - {133, 4, 2}, - {137, 4, 2}, - {117, 5, 2}, - {118, 5, 2}, - {120, 5, 2}, - {124, 5, 2}, - {132, 5, 2}, - {137, 5, 2}, - {141, 5, 2}, - {166, 5, 2}, - {170, 5, 2}, - {191, 5, 2}, - {206, 5, 2}, - {208, 5, 2}, - {30, 2, 3}, - {69, 3, 3}, - {82, 3, 3}, - {83, 3, 3}, - {109, 3, 3}, - {114, 3, 3}, - {125, 3, 3}, - {89, 4, 3}, - {103, 4, 3}, - {117, 4, 3}, - {126, 4, 3}, - {150, 4, 3}, - {161, 4, 3}, - {121, 5, 3}, - {127, 5, 3}, - {131, 5, 3}, - {134, 5, 3}, - {148, 5, 3}, - {169, 5, 3}, - {172, 5, 3}, - {182, 5, 3}, - {195, 5, 3}, - {196, 5, 3}, - {208, 5, 3}, - {66, 2, 4}, - {85, 3, 4}, - {141, 4, 4}, - {146, 4, 4}, - {161, 4, 4}, - {177, 5, 4} +static struct pll_limit k800_pll_limits[] = { + {22, 22, 2, 0}, + {28, 28, 3, 0}, + {81, 112, 3, 1}, + {86, 166, 4, 1}, + {109, 153, 5, 1}, + {66, 116, 3, 2}, + {93, 137, 4, 2}, + {117, 208, 5, 2}, + {30, 30, 2, 3}, + {69, 125, 3, 3}, + {89, 161, 4, 3}, + {121, 208, 5, 3}, + {66, 66, 2, 4}, + {85, 85, 3, 4}, + {141, 161, 4, 4}, + {177, 177, 5, 4} }; -static struct pll_config cx700_pll_config[] = { - {98, 3, 1}, - {86, 4, 1}, - {109, 5, 1}, - {110, 5, 1}, - {113, 5, 1}, - {121, 5, 1}, - {131, 5, 1}, - {135, 5, 1}, - {142, 5, 1}, - {143, 5, 1}, - {153, 5, 1}, - {187, 5, 1}, - {208, 5, 1}, - {68, 2, 2}, - {95, 3, 2}, - {116, 3, 2}, - {93, 4, 2}, - {119, 4, 2}, - {133, 4, 2}, - {137, 4, 2}, - {151, 4, 2}, - {166, 4, 2}, - {110, 5, 2}, - {112, 5, 2}, - {117, 5, 2}, - {118, 5, 2}, - {120, 5, 2}, - {132, 5, 2}, - {137, 5, 2}, - {141, 5, 2}, - {151, 5, 2}, - {166, 5, 2}, - {175, 5, 2}, - {191, 5, 2}, - {206, 5, 2}, - {174, 7, 2}, - {82, 3, 3}, - {109, 3, 3}, - {117, 4, 3}, - {150, 4, 3}, - {161, 4, 3}, - {112, 5, 3}, - {115, 5, 3}, - {121, 5, 3}, - {127, 5, 3}, - {129, 5, 3}, - {131, 5, 3}, - {134, 5, 3}, - {138, 5, 3}, - {148, 5, 3}, - {157, 5, 3}, - {169, 5, 3}, - {172, 5, 3}, - {190, 5, 3}, - {195, 5, 3}, - {196, 5, 3}, - {208, 5, 3}, - {141, 5, 4}, - {150, 5, 4}, - {166, 5, 4}, - {176, 5, 4}, - {177, 5, 4}, - {183, 5, 4}, - {202, 5, 4} +static struct pll_limit cx700_pll_limits[] = { + {98, 98, 3, 1}, + {86, 86, 4, 1}, + {109, 208, 5, 1}, + {68, 68, 2, 2}, + {95, 116, 3, 2}, + {93, 166, 4, 2}, + {110, 206, 5, 2}, + {174, 174, 7, 2}, + {82, 109, 3, 3}, + {117, 161, 4, 3}, + {112, 208, 5, 3}, + {141, 202, 5, 4} }; -static struct pll_config vx855_pll_config[] = { - {86, 4, 1}, - {108, 5, 1}, - {110, 5, 1}, - {113, 5, 1}, - {121, 5, 1}, - {131, 5, 1}, - {135, 5, 1}, - {142, 5, 1}, - {143, 5, 1}, - {153, 5, 1}, - {164, 5, 1}, - {187, 5, 1}, - {208, 5, 1}, - {110, 5, 2}, - {112, 5, 2}, - {117, 5, 2}, - {118, 5, 2}, - {124, 5, 2}, - {132, 5, 2}, - {137, 5, 2}, - {141, 5, 2}, - {149, 5, 2}, - {151, 5, 2}, - {159, 5, 2}, - {166, 5, 2}, - {167, 5, 2}, - {172, 5, 2}, - {189, 5, 2}, - {191, 5, 2}, - {194, 5, 2}, - {206, 5, 2}, - {208, 5, 2}, - {83, 3, 3}, - {88, 3, 3}, - {109, 3, 3}, - {112, 3, 3}, - {103, 4, 3}, - {105, 4, 3}, - {161, 4, 3}, - {112, 5, 3}, - {115, 5, 3}, - {121, 5, 3}, - {127, 5, 3}, - {134, 5, 3}, - {137, 5, 3}, - {148, 5, 3}, - {157, 5, 3}, - {169, 5, 3}, - {172, 5, 3}, - {182, 5, 3}, - {191, 5, 3}, - {195, 5, 3}, - {209, 5, 3}, - {142, 4, 4}, - {146, 4, 4}, - {161, 4, 4}, - {141, 5, 4}, - {150, 5, 4}, - {165, 5, 4}, - {176, 5, 4} +static struct pll_limit vx855_pll_limits[] = { + {86, 86, 4, 1}, + {108, 208, 5, 1}, + {110, 208, 5, 2}, + {83, 112, 3, 3}, + {103, 161, 4, 3}, + {112, 209, 5, 3}, + {142, 161, 4, 4}, + {141, 176, 5, 4} }; /* according to VIA Technologies these values are based on experiment */ @@ -308,6 +118,42 @@ static struct io_reg scaling_parameters[] = { {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ }; +static struct io_reg common_vga[] = { + {VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8) + [1] vertical display end (bit 8) + [2] vertical retrace start (bit 8) + [3] start vertical blanking (bit 8) + [4] line compare (bit 8) + [5] vertical total (bit 9) + [6] vertical display end (bit 9) + [7] vertical retrace start (bit 9) */ + {VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan + [5-6] byte panning */ + {VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line + [5] start vertical blanking (bit 9) + [6] line compare (bit 9) + [7] scan doubling */ + {VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start + [5] cursor disable */ + {VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end + [5-6] cursor skew */ + {VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */ + {VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */ + {VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end + [6] memory refresh bandwidth + [7] CRTC register protect enable */ + {VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location + [5] divide memory address clock by 4 + [6] double word addressing */ + {VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14 + [2] divide scan line clock by 2 + [3] divide memory address clock by 2 + [5] address wrap + [6] byte mode select + [7] sync enable */ + {VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */ +}; + static struct fifo_depth_select display_fifo_depth_reg = { /* IGA1 FIFO Depth_Select */ {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } }, @@ -676,6 +522,9 @@ static struct via_device_mapping device_mapping[] = { {VIA_LVDS2, "LVDS2"} }; +/* structure with function pointers to support clock control */ +static struct via_clock clock; + static void load_fix_bit_crtc_reg(void); static void __devinit init_gfx_chip_info(int chip_type); static void __devinit init_tmds_chip_info(void); @@ -770,13 +619,14 @@ static u32 get_lcd_devices(int output_interface) /*Set IGA path for each device*/ void viafb_set_iga_path(void) { + int crt_iga_path = 0; if (viafb_SAMM_ON == 1) { if (viafb_CRT_ON) { if (viafb_primary_dev == CRT_Device) - viaparinfo->crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; else - viaparinfo->crt_setting_info->iga_path = IGA2; + crt_iga_path = IGA2; } if (viafb_DVI_ON) { @@ -793,8 +643,7 @@ void viafb_set_iga_path(void) UNICHROME_CLE266)) { viaparinfo-> lvds_setting_info->iga_path = IGA2; - viaparinfo-> - crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; viaparinfo-> tmds_setting_info->iga_path = IGA1; } else @@ -814,10 +663,10 @@ void viafb_set_iga_path(void) viafb_SAMM_ON = 0; if (viafb_CRT_ON && viafb_LCD_ON) { - viaparinfo->crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; viaparinfo->lvds_setting_info->iga_path = IGA2; } else if (viafb_CRT_ON && viafb_DVI_ON) { - viaparinfo->crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; viaparinfo->tmds_setting_info->iga_path = IGA2; } else if (viafb_LCD_ON && viafb_DVI_ON) { viaparinfo->tmds_setting_info->iga_path = IGA1; @@ -826,7 +675,7 @@ void viafb_set_iga_path(void) viaparinfo->lvds_setting_info->iga_path = IGA2; viaparinfo->lvds_setting_info2->iga_path = IGA2; } else if (viafb_CRT_ON) { - viaparinfo->crt_setting_info->iga_path = IGA1; + crt_iga_path = IGA1; } else if (viafb_LCD_ON) { viaparinfo->lvds_setting_info->iga_path = IGA2; } else if (viafb_DVI_ON) { @@ -837,7 +686,7 @@ void viafb_set_iga_path(void) viaparinfo->shared->iga1_devices = 0; viaparinfo->shared->iga2_devices = 0; if (viafb_CRT_ON) { - if (viaparinfo->crt_setting_info->iga_path == IGA1) + if (crt_iga_path == IGA1) viaparinfo->shared->iga1_devices |= VIA_CRT; else viaparinfo->shared->iga2_devices |= VIA_CRT; @@ -875,6 +724,10 @@ void viafb_set_iga_path(void) viaparinfo->chip_info-> lvds_chip_info2.output_interface); } + + /* looks like the OLPC has its display wired to DVP1 and LVDS2 */ + if (machine_is_olpc()) + viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2; } static void set_color_register(u8 index, u8 red, u8 green, u8 blue) @@ -1162,25 +1015,17 @@ void via_odev_to_seq(struct seq_file *m, u32 odev) static void load_fix_bit_crtc_reg(void) { + viafb_unlock_crt(); + /* always set to 1 */ viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7); /* line compare should set all bits = 1 (extend modes) */ - viafb_write_reg(CR18, VIACR, 0xff); - /* line compare should set all bits = 1 (extend modes) */ - viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4); - /* line compare should set all bits = 1 (extend modes) */ - viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6); - /* line compare should set all bits = 1 (extend modes) */ viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4); /* line compare should set all bits = 1 (extend modes) */ viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2); /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */ - /* extend mode always set to e3h */ - viafb_write_reg(CR17, VIACR, 0xe3); - /* extend mode always set to 0h */ - viafb_write_reg(CR08, VIACR, 0x00); - /* extend mode always set to 0h */ - viafb_write_reg(CR14, VIACR, 0x00); + + viafb_lock_crt(); /* If K8M800, enable Prefetch Mode. */ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) @@ -1601,69 +1446,54 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) } -static u32 cle266_encode_pll(struct pll_config pll) -{ - return (pll.multiplier << 8) - | (pll.rshift << 6) - | pll.divisor; -} - -static u32 k800_encode_pll(struct pll_config pll) -{ - return ((pll.divisor - 2) << 16) - | (pll.rshift << 10) - | (pll.multiplier - 2); -} - -static u32 vx855_encode_pll(struct pll_config pll) -{ - return (pll.divisor << 16) - | (pll.rshift << 10) - | pll.multiplier; -} - -static inline u32 get_pll_internal_frequency(u32 ref_freq, - struct pll_config pll) -{ - return ref_freq / pll.divisor * pll.multiplier; -} - -static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll) -{ - return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; -} - -static struct pll_config get_pll_config(struct pll_config *config, int size, +static struct via_pll_config get_pll_config(struct pll_limit *limits, int size, int clk) { - struct pll_config best = config[0]; + struct via_pll_config cur, up, down, best = {0, 1, 0}; const u32 f0 = 14318180; /* X1 frequency */ - int i; - - for (i = 1; i < size; i++) { - if (abs(get_pll_output_frequency(f0, config[i]) - clk) - < abs(get_pll_output_frequency(f0, best) - clk)) - best = config[i]; + int i, f; + + for (i = 0; i < size; i++) { + cur.rshift = limits[i].rshift; + cur.divisor = limits[i].divisor; + cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift); + f = abs(get_pll_output_frequency(f0, cur) - clk); + up = down = cur; + up.multiplier++; + down.multiplier--; + if (abs(get_pll_output_frequency(f0, up) - clk) < f) + cur = up; + else if (abs(get_pll_output_frequency(f0, down) - clk) < f) + cur = down; + + if (cur.multiplier < limits[i].multiplier_min) + cur.multiplier = limits[i].multiplier_min; + else if (cur.multiplier > limits[i].multiplier_max) + cur.multiplier = limits[i].multiplier_max; + + f = abs(get_pll_output_frequency(f0, cur) - clk); + if (f < abs(get_pll_output_frequency(f0, best) - clk)) + best = cur; } return best; } -u32 viafb_get_clk_value(int clk) +static struct via_pll_config get_best_pll_config(int clk) { - u32 value = 0; + struct via_pll_config config; switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: - value = cle266_encode_pll(get_pll_config(cle266_pll_config, - ARRAY_SIZE(cle266_pll_config), clk)); + config = get_pll_config(cle266_pll_limits, + ARRAY_SIZE(cle266_pll_limits), clk); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: - value = k800_encode_pll(get_pll_config(k800_pll_config, - ARRAY_SIZE(k800_pll_config), clk)); + config = get_pll_config(k800_pll_limits, + ARRAY_SIZE(k800_pll_limits), clk); break; case UNICHROME_CX700: case UNICHROME_CN750: @@ -1671,92 +1501,28 @@ u32 viafb_get_clk_value(int clk) case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: - value = k800_encode_pll(get_pll_config(cx700_pll_config, - ARRAY_SIZE(cx700_pll_config), clk)); + config = get_pll_config(cx700_pll_limits, + ARRAY_SIZE(cx700_pll_limits), clk); break; case UNICHROME_VX855: case UNICHROME_VX900: - value = vx855_encode_pll(get_pll_config(vx855_pll_config, - ARRAY_SIZE(vx855_pll_config), clk)); + config = get_pll_config(vx855_pll_limits, + ARRAY_SIZE(vx855_pll_limits), clk); break; } - return value; + return config; } /* Set VCLK*/ void viafb_set_vclock(u32 clk, int set_iga) { - /* H.W. Reset : ON */ - viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); - - if (set_iga == IGA1) { - /* Change D,N FOR VCLK */ - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_CLE266: - case UNICHROME_K400: - via_write_reg(VIASR, SR46, (clk & 0x00FF)); - via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8); - break; - - case UNICHROME_K800: - case UNICHROME_PM800: - case UNICHROME_CN700: - case UNICHROME_CX700: - case UNICHROME_CN750: - case UNICHROME_K8M890: - case UNICHROME_P4M890: - case UNICHROME_P4M900: - case UNICHROME_VX800: - case UNICHROME_VX855: - case UNICHROME_VX900: - via_write_reg(VIASR, SR44, (clk & 0x0000FF)); - via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); - via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16); - break; - } - } - - if (set_iga == IGA2) { - /* Change D,N FOR LCK */ - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_CLE266: - case UNICHROME_K400: - via_write_reg(VIASR, SR44, (clk & 0x00FF)); - via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8); - break; + struct via_pll_config config = get_best_pll_config(clk); - case UNICHROME_K800: - case UNICHROME_PM800: - case UNICHROME_CN700: - case UNICHROME_CX700: - case UNICHROME_CN750: - case UNICHROME_K8M890: - case UNICHROME_P4M890: - case UNICHROME_P4M900: - case UNICHROME_VX800: - case UNICHROME_VX855: - case UNICHROME_VX900: - via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); - via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); - via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16); - break; - } - } - - /* H.W. Reset : OFF */ - viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); - - /* Reset PLL */ - if (set_iga == IGA1) { - viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); - viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); - } - - if (set_iga == IGA2) { - viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); - viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); - } + if (set_iga == IGA1) + clock.set_primary_pll(config); + if (set_iga == IGA2) + clock.set_secondary_pll(config); /* Fire! */ via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ @@ -2002,7 +1768,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, int i; int index = 0; int h_addr, v_addr; - u32 pll_D_N, clock, refresh = viafb_refresh; + u32 clock, refresh = viafb_refresh; if (viafb_SAMM_ON && set_iga == IGA2) refresh = viafb_refresh1; @@ -2033,8 +1799,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, v_addr = crt_reg.ver_addr; if (set_iga == IGA1) { viafb_unlock_crt(); - viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */ - viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6); viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); } @@ -2047,7 +1811,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, break; } - load_fix_bit_crtc_reg(); viafb_lock_crt(); viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); @@ -2059,20 +1822,17 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, clock = crt_reg.hor_total * crt_reg.ver_total * crt_table[index].refresh_rate; - pll_D_N = viafb_get_clk_value(clock); - DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); - viafb_set_vclock(pll_D_N, set_iga); + viafb_set_vclock(clock, set_iga); } void __devinit viafb_init_chip_info(int chip_type) { + via_clock_init(&clock, chip_type); init_gfx_chip_info(chip_type); init_tmds_chip_info(); init_lvds_chip_info(); - viaparinfo->crt_setting_info->iga_path = IGA1; - /*Set IGA path for each device */ viafb_set_iga_path(); @@ -2354,6 +2114,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, outb(0x00, VIAAR); /* Write Common Setting for Video Mode */ + viafb_write_regx(common_vga, ARRAY_SIZE(common_vga)); switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs); @@ -2400,9 +2161,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); - /* Write CRTC */ - viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1); - /* Write Graphic Controller */ for (i = 0; i < StdGR; i++) via_write_reg(VIAGR, i, VPIT.GR[i]); @@ -2432,6 +2190,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, } } + load_fix_bit_crtc_reg(); via_set_primary_pitch(viafbinfo->fix.line_length); via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length : viafbinfo->fix.line_length); @@ -2451,15 +2210,15 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, /* CRT set mode */ if (viafb_CRT_ON) { - if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == - IGA2)) { + if (viafb_SAMM_ON && + viaparinfo->shared->iga2_devices & VIA_CRT) { viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, - video_bpp1 / 8, - viaparinfo->crt_setting_info->iga_path); + video_bpp1 / 8, IGA2); } else { viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, - viaparinfo->crt_setting_info->iga_path); + (viaparinfo->shared->iga1_devices & VIA_CRT) + ? IGA1 : IGA2); } /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode @@ -2557,6 +2316,33 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, get_sync(viafbinfo1)); } + clock.set_engine_pll_state(VIA_STATE_ON); + clock.set_primary_clock_source(VIA_CLKSRC_X1, true); + clock.set_secondary_clock_source(VIA_CLKSRC_X1, true); + +#ifdef CONFIG_FB_VIA_X_COMPATIBILITY + clock.set_primary_pll_state(VIA_STATE_ON); + clock.set_primary_clock_state(VIA_STATE_ON); + clock.set_secondary_pll_state(VIA_STATE_ON); + clock.set_secondary_clock_state(VIA_STATE_ON); +#else + if (viaparinfo->shared->iga1_devices) { + clock.set_primary_pll_state(VIA_STATE_ON); + clock.set_primary_clock_state(VIA_STATE_ON); + } else { + clock.set_primary_pll_state(VIA_STATE_OFF); + clock.set_primary_clock_state(VIA_STATE_OFF); + } + + if (viaparinfo->shared->iga2_devices) { + clock.set_secondary_pll_state(VIA_STATE_ON); + clock.set_secondary_clock_state(VIA_STATE_ON); + } else { + clock.set_secondary_pll_state(VIA_STATE_OFF); + clock.set_secondary_clock_state(VIA_STATE_OFF); + } +#endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/ + via_set_state(devices, VIA_STATE_ON); device_screen_on(); return 1; @@ -2600,7 +2386,7 @@ int viafb_get_refresh(int hres, int vres, u32 long_refresh) if (abs(best->refresh_rate - long_refresh) > 3) { if (hres == 1200 && vres == 900) - return 50; /* OLPC DCON only supports 50 Hz */ + return 49; /* OLPC DCON only supports 50 Hz */ else return 60; } diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 8858593405aa..c7239eb83bae 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -732,20 +732,13 @@ struct _lcd_scaling_factor { struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; }; -struct pll_config { - u16 multiplier; +struct pll_limit { + u16 multiplier_min; + u16 multiplier_max; u8 divisor; u8 rshift; }; -struct pll_map { - u32 clk; - struct pll_config cle266_pll; - struct pll_config k800_pll; - struct pll_config cx700_pll; - struct pll_config vx855_pll; -}; - struct rgbLUT { u8 red; u8 green; @@ -910,7 +903,6 @@ struct via_device_mapping { const char *name; }; -extern unsigned int viafb_second_virtual_xres; extern int viafb_SAMM_ON; extern int viafb_dual_fb; extern int viafb_LCD2_ON; @@ -936,7 +928,6 @@ void viafb_lock_crt(void); void viafb_unlock_crt(void); void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); void viafb_write_regx(struct io_reg RegTable[], int ItemNum); -u32 viafb_get_clk_value(int clk); void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ *p_gfx_dpa_setting); diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 64bc7e763103..6e06981d638b 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -48,7 +48,6 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = { {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } } }; -static int check_lvds_chip(int device_id_subaddr, int device_id); static bool lvds_identify_integratedlvds(void); static void __devinit fp_id_to_vindex(int panel_id); static int lvds_register_read(int index); @@ -84,12 +83,9 @@ static struct display_timing lcd_centering_timging(struct display_timing mode_crt_reg, struct display_timing panel_crt_reg); -static int check_lvds_chip(int device_id_subaddr, int device_id) +static inline bool check_lvds_chip(int device_id_subaddr, int device_id) { - if (lvds_register_read(device_id_subaddr) == device_id) - return OK; - else - return FAIL; + return lvds_register_read(device_id_subaddr) == device_id; } void __devinit viafb_init_lcd_size(void) @@ -150,7 +146,7 @@ static bool lvds_identify_integratedlvds(void) return true; } -int __devinit viafb_lvds_trasmitter_identify(void) +bool __devinit viafb_lvds_trasmitter_identify(void) { if (viafb_lvds_identify_vt1636(VIA_PORT_31)) { viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31; @@ -175,20 +171,20 @@ int __devinit viafb_lvds_trasmitter_identify(void) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = VT1631_LVDS_I2C_ADDR; - if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) { + if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID)) { DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n"); DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); DEBUG_MSG(KERN_INFO "\n %2d", viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); - return OK; + return true; } viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = NON_LVDS_TRANSMITTER; viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = VT1631_LVDS_I2C_ADDR; - return FAIL; + return false; } static void __devinit fp_id_to_vindex(int panel_id) @@ -562,7 +558,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, int set_vres = plvds_setting_info->v_active; int panel_hres = plvds_setting_info->lcd_panel_hres; int panel_vres = plvds_setting_info->lcd_panel_vres; - u32 pll_D_N, clock; + u32 clock; struct display_timing mode_crt_reg, panel_crt_reg; struct crt_mode_table *panel_crt_table = NULL; struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, @@ -613,10 +609,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, viafb_load_FIFO_reg(set_iga, set_hres, set_vres); fill_lcd_format(); - - pll_D_N = viafb_get_clk_value(clock); - DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); - viafb_set_vclock(pll_D_N, set_iga); + viafb_set_vclock(clock, set_iga); lcd_patch_skew(plvds_setting_info, plvds_chip_info); /* If K8M800, enable LCD Prefetch Mode. */ diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h index c7909fe29550..75f60a655b0e 100644 --- a/drivers/video/via/lcd.h +++ b/drivers/video/via/lcd.h @@ -79,7 +79,7 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); -int __devinit viafb_lvds_trasmitter_identify(void); +bool __devinit viafb_lvds_trasmitter_identify(void); void viafb_init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h index 4b7831f0d012..61b0bd596b85 100644 --- a/drivers/video/via/share.h +++ b/drivers/video/via/share.h @@ -22,14 +22,6 @@ #ifndef __SHARE_H__ #define __SHARE_H__ -/* Define Return Value */ -#define FAIL -1 -#define OK 1 - -#ifndef NULL -#define NULL 0 -#endif - /* Define Bit Field */ #define BIT0 0x01 #define BIT1 0x02 @@ -290,6 +282,7 @@ #define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10 /* Definition Refresh Rate */ +#define REFRESH_49 49 #define REFRESH_50 50 #define REFRESH_60 60 #define REFRESH_75 75 @@ -575,10 +568,6 @@ #define M1280X720_R50_HSP NEGATIVE #define M1280X720_R50_VSP POSITIVE -/* 1280x720@60 Sync Polarity (CEA Mode) */ -#define M1280X720_CEA_R60_HSP POSITIVE -#define M1280X720_CEA_R60_VSP POSITIVE - /* 1440x900@60 Sync Polarity (CVT Mode) */ #define M1440X900_R60_HSP NEGATIVE #define M1440X900_R60_VSP POSITIVE @@ -619,10 +608,6 @@ #define M1920X1200_RB_R60_HSP POSITIVE #define M1920X1200_RB_R60_VSP NEGATIVE -/* 1920x1080@60 Sync Polarity (CEA Mode) */ -#define M1920X1080_CEA_R60_HSP POSITIVE -#define M1920X1080_CEA_R60_VSP POSITIVE - /* 2048x1536@60 Sync Polarity (CVT Mode) */ #define M2048x1536_R60_HSP NEGATIVE #define M2048x1536_R60_VSP POSITIVE diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 6723d6910cde..eb112b621735 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c @@ -505,7 +505,14 @@ static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev) ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type); if (ret < 0) goto out_unmap; - vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len); + + /* try to map less memory on failure, 8 MB should be still enough */ + for (; vdev->fbmem_len >= 8 << 20; vdev->fbmem_len /= 2) { + vdev->fbmem = ioremap_wc(vdev->fbmem_start, vdev->fbmem_len); + if (vdev->fbmem) + break; + } + if (vdev->fbmem == NULL) { ret = -ENOMEM; goto out_unmap; diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c new file mode 100644 index 000000000000..af8f26b643c1 --- /dev/null +++ b/drivers/video/via/via_clock.c @@ -0,0 +1,349 @@ +/* + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> + * + * 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +/* + * clock and PLL management functions + */ + +#include <linux/kernel.h> +#include <linux/via-core.h> +#include "via_clock.h" +#include "global.h" +#include "debug.h" + +const char *via_slap = "Please slap VIA Technologies to motivate them " + "releasing full documentation for your platform!\n"; + +static inline u32 cle266_encode_pll(struct via_pll_config pll) +{ + return (pll.multiplier << 8) + | (pll.rshift << 6) + | pll.divisor; +} + +static inline u32 k800_encode_pll(struct via_pll_config pll) +{ + return ((pll.divisor - 2) << 16) + | (pll.rshift << 10) + | (pll.multiplier - 2); +} + +static inline u32 vx855_encode_pll(struct via_pll_config pll) +{ + return (pll.divisor << 16) + | (pll.rshift << 10) + | pll.multiplier; +} + +static inline void cle266_set_primary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ + via_write_reg(VIASR, 0x46, data & 0xFF); + via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ +} + +static inline void k800_set_primary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ + via_write_reg(VIASR, 0x44, data & 0xFF); + via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); + via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ +} + +static inline void cle266_set_secondary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ + via_write_reg(VIASR, 0x44, data & 0xFF); + via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ +} + +static inline void k800_set_secondary_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ + via_write_reg(VIASR, 0x4A, data & 0xFF); + via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF); + via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ +} + +static inline void set_engine_pll_encoded(u32 data) +{ + via_write_reg_mask(VIASR, 0x40, 0x01, 0x01); /* enable reset */ + via_write_reg(VIASR, 0x47, data & 0xFF); + via_write_reg(VIASR, 0x48, (data >> 8) & 0xFF); + via_write_reg(VIASR, 0x49, (data >> 16) & 0xFF); + via_write_reg_mask(VIASR, 0x40, 0x00, 0x01); /* disable reset */ +} + +static void cle266_set_primary_pll(struct via_pll_config config) +{ + cle266_set_primary_pll_encoded(cle266_encode_pll(config)); +} + +static void k800_set_primary_pll(struct via_pll_config config) +{ + k800_set_primary_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_primary_pll(struct via_pll_config config) +{ + k800_set_primary_pll_encoded(vx855_encode_pll(config)); +} + +static void cle266_set_secondary_pll(struct via_pll_config config) +{ + cle266_set_secondary_pll_encoded(cle266_encode_pll(config)); +} + +static void k800_set_secondary_pll(struct via_pll_config config) +{ + k800_set_secondary_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_secondary_pll(struct via_pll_config config) +{ + k800_set_secondary_pll_encoded(vx855_encode_pll(config)); +} + +static void k800_set_engine_pll(struct via_pll_config config) +{ + set_engine_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_engine_pll(struct via_pll_config config) +{ + set_engine_pll_encoded(vx855_encode_pll(config)); +} + +static void set_primary_pll_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x20; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2D, value, 0x30); +} + +static void set_secondary_pll_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x08; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2D, value, 0x0C); +} + +static void set_engine_pll_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x02; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2D, value, 0x03); +} + +static void set_primary_clock_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x20; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x1B, value, 0x30); +} + +static void set_secondary_clock_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x80; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x1B, value, 0xC0); +} + +static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll) +{ + u8 data = 0; + + switch (source) { + case VIA_CLKSRC_X1: + data = 0x00; + break; + case VIA_CLKSRC_TVX1: + data = 0x02; + break; + case VIA_CLKSRC_TVPLL: + data = 0x04; /* 0x06 should be the same */ + break; + case VIA_CLKSRC_DVP1TVCLKR: + data = 0x0A; + break; + case VIA_CLKSRC_CAP0: + data = 0xC; + break; + case VIA_CLKSRC_CAP1: + data = 0x0E; + break; + } + + if (!use_pll) + data |= 1; + + return data; +} + +static void set_primary_clock_source(enum via_clksrc source, bool use_pll) +{ + u8 data = set_clock_source_common(source, use_pll) << 4; + via_write_reg_mask(VIACR, 0x6C, data, 0xF0); +} + +static void set_secondary_clock_source(enum via_clksrc source, bool use_pll) +{ + u8 data = set_clock_source_common(source, use_pll); + via_write_reg_mask(VIACR, 0x6C, data, 0x0F); +} + +static void dummy_set_clock_state(u8 state) +{ + printk(KERN_INFO "Using undocumented set clock state.\n%s", via_slap); +} + +static void dummy_set_clock_source(enum via_clksrc source, bool use_pll) +{ + printk(KERN_INFO "Using undocumented set clock source.\n%s", via_slap); +} + +static void dummy_set_pll_state(u8 state) +{ + printk(KERN_INFO "Using undocumented set PLL state.\n%s", via_slap); +} + +static void dummy_set_pll(struct via_pll_config config) +{ + printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap); +} + +void via_clock_init(struct via_clock *clock, int gfx_chip) +{ + switch (gfx_chip) { + case UNICHROME_CLE266: + case UNICHROME_K400: + clock->set_primary_clock_state = dummy_set_clock_state; + clock->set_primary_clock_source = dummy_set_clock_source; + clock->set_primary_pll_state = dummy_set_pll_state; + clock->set_primary_pll = cle266_set_primary_pll; + + clock->set_secondary_clock_state = dummy_set_clock_state; + clock->set_secondary_clock_source = dummy_set_clock_source; + clock->set_secondary_pll_state = dummy_set_pll_state; + clock->set_secondary_pll = cle266_set_secondary_pll; + + clock->set_engine_pll_state = dummy_set_pll_state; + clock->set_engine_pll = dummy_set_pll; + break; + case UNICHROME_K800: + case UNICHROME_PM800: + case UNICHROME_CN700: + case UNICHROME_CX700: + case UNICHROME_CN750: + case UNICHROME_K8M890: + case UNICHROME_P4M890: + case UNICHROME_P4M900: + case UNICHROME_VX800: + clock->set_primary_clock_state = set_primary_clock_state; + clock->set_primary_clock_source = set_primary_clock_source; + clock->set_primary_pll_state = set_primary_pll_state; + clock->set_primary_pll = k800_set_primary_pll; + + clock->set_secondary_clock_state = set_secondary_clock_state; + clock->set_secondary_clock_source = set_secondary_clock_source; + clock->set_secondary_pll_state = set_secondary_pll_state; + clock->set_secondary_pll = k800_set_secondary_pll; + + clock->set_engine_pll_state = set_engine_pll_state; + clock->set_engine_pll = k800_set_engine_pll; + break; + case UNICHROME_VX855: + case UNICHROME_VX900: + clock->set_primary_clock_state = set_primary_clock_state; + clock->set_primary_clock_source = set_primary_clock_source; + clock->set_primary_pll_state = set_primary_pll_state; + clock->set_primary_pll = vx855_set_primary_pll; + + clock->set_secondary_clock_state = set_secondary_clock_state; + clock->set_secondary_clock_source = set_secondary_clock_source; + clock->set_secondary_pll_state = set_secondary_pll_state; + clock->set_secondary_pll = vx855_set_secondary_pll; + + clock->set_engine_pll_state = set_engine_pll_state; + clock->set_engine_pll = vx855_set_engine_pll; + break; + + } +} diff --git a/drivers/video/via/via_clock.h b/drivers/video/via/via_clock.h new file mode 100644 index 000000000000..88714ae0d157 --- /dev/null +++ b/drivers/video/via/via_clock.h @@ -0,0 +1,76 @@ +/* + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> + * + * 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +/* + * clock and PLL management functions + */ + +#ifndef __VIA_CLOCK_H__ +#define __VIA_CLOCK_H__ + +#include <linux/types.h> + +enum via_clksrc { + VIA_CLKSRC_X1 = 0, + VIA_CLKSRC_TVX1, + VIA_CLKSRC_TVPLL, + VIA_CLKSRC_DVP1TVCLKR, + VIA_CLKSRC_CAP0, + VIA_CLKSRC_CAP1, +}; + +struct via_pll_config { + u16 multiplier; + u8 divisor; + u8 rshift; +}; + +struct via_clock { + void (*set_primary_clock_state)(u8 state); + void (*set_primary_clock_source)(enum via_clksrc src, bool use_pll); + void (*set_primary_pll_state)(u8 state); + void (*set_primary_pll)(struct via_pll_config config); + + void (*set_secondary_clock_state)(u8 state); + void (*set_secondary_clock_source)(enum via_clksrc src, bool use_pll); + void (*set_secondary_pll_state)(u8 state); + void (*set_secondary_pll)(struct via_pll_config config); + + void (*set_engine_pll_state)(u8 state); + void (*set_engine_pll)(struct via_pll_config config); +}; + + +static inline u32 get_pll_internal_frequency(u32 ref_freq, + struct via_pll_config pll) +{ + return ref_freq / pll.divisor * pll.multiplier; +} + +static inline u32 get_pll_output_frequency(u32 ref_freq, + struct via_pll_config pll) +{ + return get_pll_internal_frequency(ref_freq, pll) >> pll.rshift; +} + +void via_clock_init(struct via_clock *clock, int gfx_chip); + +#endif /* __VIA_CLOCK_H__ */ diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index a542bed086e2..cf43c80d27f6 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -24,6 +24,7 @@ #include <linux/slab.h> #include <linux/stat.h> #include <linux/via-core.h> +#include <asm/olpc.h> #define _MASTER_FILE #include "global.h" @@ -37,6 +38,8 @@ static char *viafb_mode1; static int viafb_bpp = 32; static int viafb_bpp1 = 32; +static unsigned int viafb_second_xres = 640; +static unsigned int viafb_second_yres = 480; static unsigned int viafb_second_offset; static int viafb_second_size; @@ -440,8 +443,8 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) if (viafb_SAMM_ON == 1) { u.viamode.xres_sec = viafb_second_xres; u.viamode.yres_sec = viafb_second_yres; - u.viamode.virtual_xres_sec = viafb_second_virtual_xres; - u.viamode.virtual_yres_sec = viafb_second_virtual_yres; + u.viamode.virtual_xres_sec = viafb_dual_fb ? viafbinfo1->var.xres_virtual : viafbinfo->var.xres_virtual; + u.viamode.virtual_yres_sec = viafb_dual_fb ? viafbinfo1->var.yres_virtual : viafbinfo->var.yres_virtual; u.viamode.refresh_sec = viafb_refresh1; u.viamode.bpp_sec = viafb_bpp1; } else { @@ -930,10 +933,8 @@ static int get_primary_device(void) /* Rule: device on iga1 path are the primary device. */ if (viafb_SAMM_ON) { if (viafb_CRT_ON) { - if (viaparinfo->crt_setting_info->iga_path == IGA1) { - DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", - viaparinfo-> - crt_setting_info->iga_path); + if (viaparinfo->shared->iga1_devices & VIA_CRT) { + DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", IGA1); primary_device = CRT_Device; } } @@ -1011,8 +1012,13 @@ static int __init parse_active_dev(void) /* Note: The previous of active_dev is primary device, and the following is secondary device. */ if (!viafb_active_dev) { - viafb_CRT_ON = STATE_ON; - viafb_SAMM_ON = STATE_OFF; + if (machine_is_olpc()) { /* LCD only */ + viafb_LCD_ON = STATE_ON; + viafb_SAMM_ON = STATE_OFF; + } else { + viafb_CRT_ON = STATE_ON; + viafb_SAMM_ON = STATE_OFF; + } } else if (!strcmp(viafb_active_dev, "CRT+DVI")) { /* CRT+DVI */ viafb_CRT_ON = STATE_ON; @@ -1665,8 +1671,13 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres) char *ptr; if (!str) { - *xres = 640; - *yres = 480; + if (machine_is_olpc()) { + *xres = 1200; + *yres = 900; + } else { + *xres = 640; + *yres = 480; + } return 0; } @@ -1746,7 +1757,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; viaparinfo->lvds_setting_info2 = &viaparinfo->shared->lvds_setting_info2; - viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info; viaparinfo->chip_info = &viaparinfo->shared->chip_info; if (viafb_dual_fb) @@ -1793,14 +1803,10 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) parse_mode(viafb_mode, &default_xres, &default_yres); vmode_entry = viafb_get_mode(default_xres, default_yres); - if (viafb_SAMM_ON == 1) { + if (viafb_SAMM_ON == 1) parse_mode(viafb_mode1, &viafb_second_xres, &viafb_second_yres); - viafb_second_virtual_xres = viafb_second_xres; - viafb_second_virtual_yres = viafb_second_yres; - } - default_var.xres = default_xres; default_var.yres = default_yres; default_var.xres_virtual = default_xres; @@ -1844,8 +1850,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) default_var.xres = viafb_second_xres; default_var.yres = viafb_second_yres; - default_var.xres_virtual = viafb_second_virtual_xres; - default_var.yres_virtual = viafb_second_virtual_yres; + default_var.xres_virtual = viafb_second_xres; + default_var.yres_virtual = viafb_second_yres; default_var.bits_per_pixel = viafb_bpp1; viafb_fill_var_timing_info(&default_var, viafb_get_refresh( default_var.xres, default_var.yres, viafb_refresh1), @@ -1927,11 +1933,16 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev) } #ifndef MODULE -static int __init viafb_setup(char *options) +static int __init viafb_setup(void) { char *this_opt; + char *options; + DEBUG_MSG(KERN_INFO "viafb_setup!\n"); + if (fb_get_options("viafb", &options)) + return -ENODEV; + if (!options || !*options) return 0; @@ -2005,11 +2016,16 @@ static int __init viafb_setup(char *options) int __init viafb_init(void) { u32 dummy_x, dummy_y; + int r; + + if (machine_is_olpc()) + /* Apply XO-1.5-specific configuration. */ + viafb_lcd_panel_id = 23; + #ifndef MODULE - char *option = NULL; - if (fb_get_options("viafb", &option)) - return -ENODEV; - viafb_setup(option); + r = viafb_setup(); + if (r < 0) + return r; #endif if (parse_mode(viafb_mode, &dummy_x, &dummy_y) || !viafb_get_mode(dummy_x, dummy_y) diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 137996dc547e..d9440635d1d4 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -50,7 +50,6 @@ struct viafb_shared { /* All the information will be needed to set engine */ struct tmds_setting_information tmds_setting_info; - struct crt_setting_information crt_setting_info; struct lvds_setting_information lvds_setting_info; struct lvds_setting_information lvds_setting_info2; struct chip_information chip_info; @@ -79,14 +78,11 @@ struct viafb_par { /* All the information will be needed to set engine */ /* depreciated, use the ones in shared directly */ struct tmds_setting_information *tmds_setting_info; - struct crt_setting_information *crt_setting_info; struct lvds_setting_information *lvds_setting_info; struct lvds_setting_information *lvds_setting_info2; struct chip_information *chip_info; }; -extern unsigned int viafb_second_virtual_yres; -extern unsigned int viafb_second_virtual_xres; extern int viafb_SAMM_ON; extern int viafb_dual_fb; extern int viafb_LCD2_ON; diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c index 260d339b236c..58df74e1417e 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c @@ -30,10 +30,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIASR, SR1A, 0xFB, 0x08}, {VIASR, SR1E, 0x0F, 0x01}, {VIASR, SR2A, 0xFF, 0x00}, -{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ -{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ -{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ -{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ {VIACR, CR32, 0xFF, 0x00}, {VIACR, CR33, 0xFF, 0x00}, {VIACR, CR35, 0xFF, 0x00}, @@ -41,7 +37,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIACR, CR69, 0xFF, 0x00}, {VIACR, CR6A, 0xFF, 0x40}, {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00}, {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ @@ -87,7 +82,6 @@ struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIACR, CR69, 0xFF, 0x00}, {VIACR, CR6A, 0xFD, 0x40}, {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00}, {VIACR, CR77, 0xFF, 0x00}, /* LCD scaling Factor */ {VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */ {VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */ @@ -125,10 +119,6 @@ struct io_reg KM400_ModeXregs[] = { {VIASR, SR2A, 0xFF, 0x00}, /* Power Management Control 5 */ {VIASR, SR2D, 0xFF, 0xFF}, /* Power Management Control 1 */ {VIASR, SR2E, 0xFF, 0xFF}, /* Power Management Control 2 */ - {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ - {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ - {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ - {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ {VIACR, CR33, 0xFF, 0x00}, {VIACR, CR55, 0x80, 0x00}, {VIACR, CR5D, 0x80, 0x00}, @@ -161,11 +151,7 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIASR, SR1B, 0xFF, 0xF0}, {VIASR, SR1E, 0xFF, 0x01}, {VIASR, SR2A, 0xFF, 0x00}, -{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ -{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ -{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ -{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ -{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ +{VIASR, SR2D, 0xC0, 0xC0}, /* delayed E3_ECK */ {VIACR, CR32, 0xFF, 0x00}, {VIACR, CR33, 0xFF, 0x00}, {VIACR, CR35, 0xFF, 0x00}, @@ -174,7 +160,6 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01}, {VIACR, CR69, 0xFF, 0x00}, {VIACR, CR6A, 0xFF, 0x40}, {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00}, {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ @@ -204,14 +189,7 @@ struct io_reg VX855_ModeXregs[] = { {VIASR, SR2A, 0xF0, 0x00}, {VIASR, SR58, 0xFF, 0x00}, {VIASR, SR59, 0xFF, 0x00}, -{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ -{VIACR, CR09, 0xFF, 0x00}, /* Initial CR09=0*/ -{VIACR, CR11, 0x8F, 0x00}, /* IGA1 initial Vertical end */ -{VIACR, CR17, 0x7F, 0x00}, /* IGA1 CRT Mode control init */ -{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */ -{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */ -{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */ -{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */ +{VIASR, SR2D, 0xC0, 0xC0}, /* delayed E3_ECK */ {VIACR, CR32, 0xFF, 0x00}, {VIACR, CR33, 0x7F, 0x00}, {VIACR, CR35, 0xFF, 0x00}, @@ -219,7 +197,6 @@ struct io_reg VX855_ModeXregs[] = { {VIACR, CR69, 0xFF, 0x00}, {VIACR, CR6A, 0xFD, 0x60}, {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00}, {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ @@ -606,7 +583,7 @@ static struct crt_mode_table CRTM1200x720[] = { /* 1200x900 (DCON) */ static struct crt_mode_table DCON1200x900[] = { /* r_rate, hsp, vsp */ - {REFRESH_50, M1200X900_R60_HSP, M1200X900_R60_VSP, + {REFRESH_49, M1200X900_R60_HSP, M1200X900_R60_VSP, /* The correct htotal is 1240, but this doesn't raster on VX855. */ /* Via suggested changing to a multiple of 16, hence 1264. */ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ @@ -877,23 +854,6 @@ static struct VideoModeTable viafb_rb_modes[] = { {CRTM1920x1200_RB, ARRAY_SIZE(CRTM1920x1200_RB)} }; -struct crt_mode_table CEAM1280x720[] = { - {REFRESH_60, M1280X720_CEA_R60_HSP, M1280X720_CEA_R60_VSP, - /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ - {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} } -}; -struct crt_mode_table CEAM1920x1080[] = { - {REFRESH_60, M1920X1080_CEA_R60_HSP, M1920X1080_CEA_R60_VSP, - /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ - {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} } -}; -struct VideoModeTable CEA_HDMI_Modes[] = { - /* Display : 1280x720 */ - {CEAM1280x720, ARRAY_SIZE(CEAM1280x720)}, - {CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} -}; - -int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes); int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs); int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs); int NUM_TOTAL_KM400_ModeXregs = ARRAY_SIZE(KM400_ModeXregs); diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h index 8a67ea1b5ef0..3751289eb450 100644 --- a/drivers/video/via/viamode.h +++ b/drivers/video/via/viamode.h @@ -41,7 +41,6 @@ struct patch_table { struct io_reg *io_reg_table; }; -extern int NUM_TOTAL_CEA_MODES; extern int NUM_TOTAL_CN400_ModeXregs; extern int NUM_TOTAL_CN700_ModeXregs; extern int NUM_TOTAL_KM400_ModeXregs; @@ -50,14 +49,6 @@ extern int NUM_TOTAL_VX855_ModeXregs; extern int NUM_TOTAL_CLE266_ModeXregs; extern int NUM_TOTAL_PATCH_MODE; -/********************/ -/* Mode Table */ -/********************/ - -extern struct crt_mode_table CEAM1280x720[]; -extern struct crt_mode_table CEAM1920x1080[]; -extern struct VideoModeTable CEA_HDMI_Modes[]; - extern struct io_reg CN400_ModeXregs[]; extern struct io_reg CN700_ModeXregs[]; extern struct io_reg KM400_ModeXregs[]; |