diff --git a/[refs] b/[refs] index 356b4f8e2c8c..8f832062b640 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dc7c0b6a6d28b0de231728de963ed53a9cee85cf +refs/heads/master: c36940e678fc30779c99246c034deca1fed61ae4 diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 954f6e9d8d5a..27c1fb4b1e0d 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -186,14 +186,6 @@ config FB_SYS_FOPS depends on FB default n -config FB_WMT_GE_ROPS - tristate - depends on FB - default n - ---help--- - Include functions for accelerated rectangle filling and area - copying using WonderMedia Graphics Engine operations. - config FB_DEFERRED_IO bool depends on FB @@ -1730,24 +1722,6 @@ config FB_AU1200 various panels and CRTs by passing in kernel cmd line option au1200fb:panel=. -config FB_VT8500 - bool "VT8500 LCD Driver" - depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_VT8500 - select FB_WMT_GE_ROPS - select FB_SYS_IMAGEBLIT - help - This is the framebuffer driver for VIA VT8500 integrated LCD - controller. - -config FB_WM8505 - bool "WM8505 frame buffer support" - depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_WM8505 - select FB_WMT_GE_ROPS - select FB_SYS_IMAGEBLIT - help - This is the framebuffer driver for WonderMedia WM8505 - integrated LCD controller. - source "drivers/video/geode/Kconfig" config FB_HIT diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index 8d916dcb379f..485e8ed1318c 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_FB_SVGALIB) += svgalib.o obj-$(CONFIG_FB_MACMODES) += macmodes.o obj-$(CONFIG_FB_DDC) += fb_ddc.o obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o -obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o # Hardware specific drivers go first obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o @@ -105,8 +104,6 @@ obj-$(CONFIG_FB_W100) += w100fb.o obj-$(CONFIG_FB_TMIO) += tmiofb.o obj-$(CONFIG_FB_AU1100) += au1100fb.o obj-$(CONFIG_FB_AU1200) += au1200fb.o -obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o -obj-$(CONFIG_FB_WM8505) += wm8505fb.o obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o diff --git a/trunk/drivers/video/sh_mobile_hdmi.c b/trunk/drivers/video/sh_mobile_hdmi.c index 55b3077ff6ff..ef41c215abae 100644 --- a/trunk/drivers/video/sh_mobile_hdmi.c +++ b/trunk/drivers/video/sh_mobile_hdmi.c @@ -685,11 +685,21 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi) } static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi, - const struct fb_videomode *mode) + const struct fb_videomode *mode, + unsigned long *hdmi_rate, unsigned long *parent_rate) { - long target = PICOS2KHZ(mode->pixclock) * 1000, - rate = clk_round_rate(hdmi->hdmi_clk, target); - unsigned long rate_error = rate > 0 ? abs(rate - target) : ULONG_MAX; + unsigned long target = PICOS2KHZ(mode->pixclock) * 1000, rate_error; + struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; + + *hdmi_rate = clk_round_rate(hdmi->hdmi_clk, target); + if ((long)*hdmi_rate < 0) + *hdmi_rate = clk_get_rate(hdmi->hdmi_clk); + + rate_error = (long)*hdmi_rate > 0 ? abs(*hdmi_rate - target) : ULONG_MAX; + if (rate_error && pdata->clk_optimize_parent) + rate_error = pdata->clk_optimize_parent(target, hdmi_rate, parent_rate); + else if (clk_get_parent(hdmi->hdmi_clk)) + *parent_rate = clk_get_rate(clk_get_parent(hdmi->hdmi_clk)); dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u\n", mode->left_margin, mode->xres, @@ -697,14 +707,15 @@ static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi, mode->upper_margin, mode->yres, mode->lower_margin, mode->vsync_len); - dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz\n", target, - rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0, - mode->refresh); + dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz, p=%luHz\n", target, + rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0, + mode->refresh, *parent_rate); return rate_error; } -static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) +static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate, + unsigned long *parent_rate) { struct fb_var_screeninfo tmpvar; struct fb_var_screeninfo *var = &tmpvar; @@ -754,11 +765,14 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) for (i = 0, mode = hdmi->monspec.modedb; f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match; i++, mode++) { - unsigned long rate_error = sh_hdmi_rate_error(hdmi, mode); + unsigned long rate_error; /* No interest in unmatching modes */ if (f_width != mode->xres || f_height != mode->yres) continue; + + rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate); + if (f_refresh == mode->refresh || (!f_refresh && !rate_error)) /* * Exact match if either the refresh rate matches or it @@ -802,7 +816,7 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) if (modelist) { found = &modelist->mode; - found_rate_error = sh_hdmi_rate_error(hdmi, found); + found_rate_error = sh_hdmi_rate_error(hdmi, found, hdmi_rate, parent_rate); } } @@ -810,10 +824,6 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) if (!found) return -ENXIO; - dev_info(hdmi->dev, "Using %s mode %ux%u@%uHz (%luHz), clock error %luHz\n", - modelist ? "default" : "EDID", found->xres, found->yres, - found->refresh, PICOS2KHZ(found->pixclock) * 1000, found_rate_error); - if ((found->xres == 720 && found->yres == 480) || (found->xres == 1280 && found->yres == 720) || (found->xres == 1920 && found->yres == 1080)) @@ -821,6 +831,11 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) else hdmi->preprogrammed_mode = false; + dev_dbg(hdmi->dev, "Using %s %s mode %ux%u@%uHz (%luHz), clock error %luHz\n", + modelist ? "default" : "EDID", hdmi->preprogrammed_mode ? "VIC" : "external", + found->xres, found->yres, found->refresh, + PICOS2KHZ(found->pixclock) * 1000, found_rate_error); + fb_videomode_to_var(&hdmi->var, found); sh_hdmi_external_video_param(hdmi); @@ -972,39 +987,38 @@ static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi) /** * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock - * @hdmi: driver context - * @pixclock: pixel clock period in picoseconds - * return: configured positive rate if successful - * 0 if couldn't set the rate, but managed to enable the clock - * negative error, if couldn't enable the clock + * @hdmi: driver context + * @hdmi_rate: HDMI clock frequency in Hz + * @parent_rate: if != 0 - set parent clock rate for optimal precision + * return: configured positive rate if successful + * 0 if couldn't set the rate, but managed to enable the + * clock, negative error, if couldn't enable the clock */ -static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long pixclock) +static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long hdmi_rate, + unsigned long parent_rate) { - long rate; + struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; int ret; - rate = PICOS2KHZ(pixclock) * 1000; - rate = clk_round_rate(hdmi->hdmi_clk, rate); - if (rate > 0) { - ret = clk_set_rate(hdmi->hdmi_clk, rate); + if (parent_rate && clk_get_parent(hdmi->hdmi_clk)) { + ret = clk_set_rate(clk_get_parent(hdmi->hdmi_clk), parent_rate); if (ret < 0) { - dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", rate, ret); - rate = 0; + dev_warn(hdmi->dev, "Cannot set parent rate %ld: %d\n", parent_rate, ret); + hdmi_rate = clk_round_rate(hdmi->hdmi_clk, hdmi_rate); } else { - dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", rate); + dev_dbg(hdmi->dev, "HDMI set parent frequency %lu\n", parent_rate); } - } else { - rate = 0; - dev_warn(hdmi->dev, "Cannot get suitable rate: %ld\n", rate); } - ret = clk_enable(hdmi->hdmi_clk); + ret = clk_set_rate(hdmi->hdmi_clk, hdmi_rate); if (ret < 0) { - dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret); - return ret; + dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", hdmi_rate, ret); + hdmi_rate = 0; + } else { + dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", hdmi_rate); } - return rate; + return hdmi_rate; } /* Hotplug interrupt occurred, read EDID */ @@ -1024,16 +1038,17 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) mutex_lock(&hdmi->mutex); if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) { + unsigned long parent_rate = 0, hdmi_rate; + /* A device has been plugged in */ pm_runtime_get_sync(hdmi->dev); - ret = sh_hdmi_read_edid(hdmi); + ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate); if (ret < 0) goto out; /* Reconfigure the clock */ - clk_disable(hdmi->hdmi_clk); - ret = sh_hdmi_clk_configure(hdmi, hdmi->var.pixclock); + ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate); if (ret < 0) goto out; @@ -1071,6 +1086,10 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) if (!hdmi->info) goto out; + hdmi->monspec.modedb_len = 0; + fb_destroy_modedb(hdmi->monspec.modedb); + hdmi->monspec.modedb = NULL; + acquire_console_sem(); /* HDMI disconnect */ @@ -1078,7 +1097,6 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) release_console_sem(); pm_runtime_put(hdmi->dev); - fb_destroy_modedb(hdmi->monspec.modedb); } out: @@ -1163,13 +1181,22 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) goto egetclk; } - /* Some arbitrary relaxed pixclock just to get things started */ - rate = sh_hdmi_clk_configure(hdmi, 37037); + /* An arbitrary relaxed pixclock just to get things started: from standard 480p */ + rate = clk_round_rate(hdmi->hdmi_clk, PICOS2KHZ(37037)); + if (rate > 0) + rate = sh_hdmi_clk_configure(hdmi, rate, 0); + if (rate < 0) { ret = rate; goto erate; } + ret = clk_enable(hdmi->hdmi_clk); + if (ret < 0) { + dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret); + goto erate; + } + dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate); if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { @@ -1187,10 +1214,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hdmi); - /* Product and revision IDs are 0 in sh-mobile version */ - dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", - hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID)); - /* Set up LCDC callbacks */ board_cfg = &pdata->lcd_chan->board_cfg; board_cfg->owner = THIS_MODULE; @@ -1203,6 +1226,10 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_resume(&pdev->dev); + /* Product and revision IDs are 0 in sh-mobile version */ + dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", + hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID)); + ret = request_irq(irq, sh_hdmi_hotplug, 0, dev_name(&pdev->dev), hdmi); if (ret < 0) { diff --git a/trunk/drivers/video/sh_mobile_lcdcfb.c b/trunk/drivers/video/sh_mobile_lcdcfb.c index 50963739a409..9b1364723c65 100644 --- a/trunk/drivers/video/sh_mobile_lcdcfb.c +++ b/trunk/drivers/video/sh_mobile_lcdcfb.c @@ -115,15 +115,16 @@ static const struct fb_videomode default_720p = { .xres = 1280, .yres = 720, - .left_margin = 200, - .right_margin = 88, - .hsync_len = 48, + .left_margin = 220, + .right_margin = 110, + .hsync_len = 40, .upper_margin = 20, .lower_margin = 5, .vsync_len = 5, .pixclock = 13468, + .refresh = 60, .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, }; @@ -1197,6 +1198,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) const struct fb_videomode *mode = cfg->lcd_cfg; unsigned long max_size = 0; int k; + int num_cfg; ch->info = framebuffer_alloc(0, &pdev->dev); if (!ch->info) { @@ -1232,8 +1234,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) info->fix = sh_mobile_lcdc_fix; info->fix.smem_len = max_size * (cfg->bpp / 8) * 2; - if (!mode) + if (!mode) { mode = &default_720p; + num_cfg = 1; + } else { + num_cfg = ch->cfg.num_cfg; + } + + fb_videomode_to_modelist(mode, num_cfg, &info->modelist); fb_videomode_to_var(var, mode); /* Default Y virtual resolution is 2x panel size */ @@ -1281,10 +1289,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) for (i = 0; i < j; i++) { struct sh_mobile_lcdc_chan *ch = priv->ch + i; - const struct fb_videomode *mode = ch->cfg.lcd_cfg; - - if (!mode) - mode = &default_720p; info = ch->info; @@ -1297,7 +1301,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) } } - fb_videomode_to_modelist(mode, ch->cfg.num_cfg, &info->modelist); error = register_framebuffer(info); if (error < 0) goto err1; diff --git a/trunk/drivers/video/via/via-core.c b/trunk/drivers/video/via/via-core.c index 6723d6910cde..a3aa91709503 100644 --- a/trunk/drivers/video/via/via-core.c +++ b/trunk/drivers/video/via/via-core.c @@ -15,9 +15,6 @@ #include #include #include -#include -#include -#include /* * The default port config. @@ -31,19 +28,6 @@ static struct via_port_cfg adap_configs[] = { { 0, 0, 0, 0 } }; -/* - * The OLPC XO-1.5 puts the camera power and reset lines onto - * GPIO 2C. - */ -static const struct via_port_cfg olpc_adap_configs[] = { - [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x26 }, - [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 }, - [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 }, - [VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x2c }, - [VIA_PORT_3D] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x3d }, - { 0, 0, 0, 0 } -}; - /* * We currently only support one viafb device (will there ever be * more than one?), so just declare it globally here. @@ -591,78 +575,6 @@ static void via_teardown_subdevs(void) } } -/* - * Power management functions - */ -#ifdef CONFIG_PM -static LIST_HEAD(viafb_pm_hooks); -static DEFINE_MUTEX(viafb_pm_hooks_lock); - -void viafb_pm_register(struct viafb_pm_hooks *hooks) -{ - INIT_LIST_HEAD(&hooks->list); - - mutex_lock(&viafb_pm_hooks_lock); - list_add_tail(&hooks->list, &viafb_pm_hooks); - mutex_unlock(&viafb_pm_hooks_lock); -} -EXPORT_SYMBOL_GPL(viafb_pm_register); - -void viafb_pm_unregister(struct viafb_pm_hooks *hooks) -{ - mutex_lock(&viafb_pm_hooks_lock); - list_del(&hooks->list); - mutex_unlock(&viafb_pm_hooks_lock); -} -EXPORT_SYMBOL_GPL(viafb_pm_unregister); - -static int via_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct viafb_pm_hooks *hooks; - - if (state.event != PM_EVENT_SUSPEND) - return 0; - /* - * "I've occasionally hit a few drivers that caused suspend - * failures, and each and every time it was a driver bug, and - * the right thing to do was to just ignore the error and suspend - * anyway - returning an error code and trying to undo the suspend - * is not what anybody ever really wants, even if our model - *_allows_ for it." - * -- Linus Torvalds, Dec. 7, 2009 - */ - mutex_lock(&viafb_pm_hooks_lock); - list_for_each_entry_reverse(hooks, &viafb_pm_hooks, list) - hooks->suspend(hooks->private); - mutex_unlock(&viafb_pm_hooks_lock); - - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int via_resume(struct pci_dev *pdev) -{ - struct viafb_pm_hooks *hooks; - - /* Get the bus side powered up */ - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - if (pci_enable_device(pdev)) - return 0; - - pci_set_master(pdev); - - /* Now bring back any subdevs */ - mutex_lock(&viafb_pm_hooks_lock); - list_for_each_entry(hooks, &viafb_pm_hooks, list) - hooks->resume(hooks->private); - mutex_unlock(&viafb_pm_hooks_lock); - - return 0; -} -#endif /* CONFIG_PM */ static int __devinit via_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -672,7 +584,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, ret = pci_enable_device(pdev); if (ret) return ret; - /* * Global device initialization. */ @@ -680,9 +591,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, global_dev.pdev = pdev; global_dev.chip_type = ent->driver_data; global_dev.port_cfg = adap_configs; - if (machine_is_olpc()) - global_dev.port_cfg = olpc_adap_configs; - spin_lock_init(&global_dev.reg_lock); ret = via_pci_setup_mmio(&global_dev); if (ret) @@ -755,8 +663,8 @@ static struct pci_driver via_driver = { .probe = via_pci_probe, .remove = __devexit_p(via_pci_remove), #ifdef CONFIG_PM - .suspend = via_suspend, - .resume = via_resume, + .suspend = viafb_suspend, + .resume = viafb_resume, #endif }; diff --git a/trunk/drivers/video/via/via-gpio.c b/trunk/drivers/video/via/via-gpio.c index c2a0a1cfd3b3..39acb37e7a1d 100644 --- a/trunk/drivers/video/via/via-gpio.c +++ b/trunk/drivers/video/via/via-gpio.c @@ -172,28 +172,6 @@ static void viafb_gpio_disable(struct viafb_gpio *gpio) via_write_reg_mask(VIASR, gpio->vg_port_index, 0, 0x02); } -#ifdef CONFIG_PM - -static int viafb_gpio_suspend(void *private) -{ - return 0; -} - -static int viafb_gpio_resume(void *private) -{ - int i; - - for (i = 0; i < gpio_config.gpio_chip.ngpio; i += 2) - viafb_gpio_enable(gpio_config.active_gpios[i]); - return 0; -} - -static struct viafb_pm_hooks viafb_gpio_pm_hooks = { - .suspend = viafb_gpio_suspend, - .resume = viafb_gpio_resume -}; -#endif /* CONFIG_PM */ - /* * Look up a specific gpio and return the number it was assigned. */ @@ -258,9 +236,6 @@ static __devinit int viafb_gpio_probe(struct platform_device *platdev) printk(KERN_ERR "viafb: failed to add gpios (%d)\n", ret); gpio_config.gpio_chip.ngpio = 0; } -#ifdef CONFIG_PM - viafb_pm_register(&viafb_gpio_pm_hooks); -#endif return ret; } @@ -270,10 +245,6 @@ static int viafb_gpio_remove(struct platform_device *platdev) unsigned long flags; int ret = 0, i; -#ifdef CONFIG_PM - viafb_pm_unregister(&viafb_gpio_pm_hooks); -#endif - /* * Get unregistered. */ diff --git a/trunk/drivers/video/via/viafbdev.c b/trunk/drivers/video/via/viafbdev.c index 289edd519527..d298cfccd6fc 100644 --- a/trunk/drivers/video/via/viafbdev.c +++ b/trunk/drivers/video/via/viafbdev.c @@ -1672,19 +1672,31 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres) #ifdef CONFIG_PM -static int viafb_suspend(void *unused) +int viafb_suspend(struct pci_dev *pdev, pm_message_t state) { - acquire_console_sem(); - fb_set_suspend(viafbinfo, 1); - viafb_sync(viafbinfo); - release_console_sem(); + if (state.event == PM_EVENT_SUSPEND) { + acquire_console_sem(); + fb_set_suspend(viafbinfo, 1); + + viafb_sync(viafbinfo); + + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + release_console_sem(); + } return 0; } -static int viafb_resume(void *unused) +int viafb_resume(struct pci_dev *pdev) { acquire_console_sem(); + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + if (pci_enable_device(pdev)) + goto fail; + pci_set_master(pdev); if (viaparinfo->shared->vdev->engine_mmio) viafb_reset_engine(viaparinfo); viafb_set_par(viafbinfo); @@ -1692,15 +1704,11 @@ static int viafb_resume(void *unused) viafb_set_par(viafbinfo1); fb_set_suspend(viafbinfo, 0); +fail: release_console_sem(); return 0; } -static struct viafb_pm_hooks viafb_fb_pm_hooks = { - .suspend = viafb_suspend, - .resume = viafb_resume -}; - #endif @@ -1891,10 +1899,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) viafb_init_proc(viaparinfo->shared); viafb_init_dac(IGA2); - -#ifdef CONFIG_PM - viafb_pm_register(&viafb_fb_pm_hooks); -#endif return 0; out_fb_unreg: diff --git a/trunk/drivers/video/via/viafbdev.h b/trunk/drivers/video/via/viafbdev.h index d66f963e930e..4960e3da6645 100644 --- a/trunk/drivers/video/via/viafbdev.h +++ b/trunk/drivers/video/via/viafbdev.h @@ -108,4 +108,6 @@ void via_fb_pci_remove(struct pci_dev *pdev); /* Temporary */ int viafb_init(void); void viafb_exit(void); +int viafb_suspend(struct pci_dev *pdev, pm_message_t state); +int viafb_resume(struct pci_dev *pdev); #endif /* __VIAFBDEV_H__ */ diff --git a/trunk/drivers/video/vt8500lcdfb.c b/trunk/drivers/video/vt8500lcdfb.c deleted file mode 100644 index 7617f12e4fd7..000000000000 --- a/trunk/drivers/video/vt8500lcdfb.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * linux/drivers/video/vt8500lcdfb.c - * - * Copyright (C) 2010 Alexey Charkov - * - * Based on skeletonfb.c and pxafb.c - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "vt8500lcdfb.h" -#include "wmt_ge_rops.h" - -#define to_vt8500lcd_info(__info) container_of(__info, \ - struct vt8500lcd_info, fb) - -static int vt8500lcd_set_par(struct fb_info *info) -{ - struct vt8500lcd_info *fbi = to_vt8500lcd_info(info); - int reg_bpp = 5; /* 16bpp */ - int i; - unsigned long control0; - - if (!fbi) - return -EINVAL; - - if (info->var.bits_per_pixel <= 8) { - /* palettized */ - info->var.red.offset = 0; - info->var.red.length = info->var.bits_per_pixel; - info->var.red.msb_right = 0; - - info->var.green.offset = 0; - info->var.green.length = info->var.bits_per_pixel; - info->var.green.msb_right = 0; - - info->var.blue.offset = 0; - info->var.blue.length = info->var.bits_per_pixel; - info->var.blue.msb_right = 0; - - info->var.transp.offset = 0; - info->var.transp.length = 0; - info->var.transp.msb_right = 0; - - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - info->fix.line_length = info->var.xres_virtual / - (8/info->var.bits_per_pixel); - } else { - /* non-palettized */ - info->var.transp.offset = 0; - info->var.transp.length = 0; - info->var.transp.msb_right = 0; - - if (info->var.bits_per_pixel == 16) { - /* RGB565 */ - info->var.red.offset = 11; - info->var.red.length = 5; - info->var.red.msb_right = 0; - info->var.green.offset = 5; - info->var.green.length = 6; - info->var.green.msb_right = 0; - info->var.blue.offset = 0; - info->var.blue.length = 5; - info->var.blue.msb_right = 0; - } else { - /* Equal depths per channel */ - info->var.red.offset = info->var.bits_per_pixel - * 2 / 3; - info->var.red.length = info->var.bits_per_pixel / 3; - info->var.red.msb_right = 0; - info->var.green.offset = info->var.bits_per_pixel / 3; - info->var.green.length = info->var.bits_per_pixel / 3; - info->var.green.msb_right = 0; - info->var.blue.offset = 0; - info->var.blue.length = info->var.bits_per_pixel / 3; - info->var.blue.msb_right = 0; - } - - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.line_length = info->var.bits_per_pixel > 16 ? - info->var.xres_virtual << 2 : - info->var.xres_virtual << 1; - } - - for (i = 0; i < 8; i++) { - if (bpp_values[i] == info->var.bits_per_pixel) { - reg_bpp = i; - continue; - } - } - - control0 = readl(fbi->regbase) & ~0xf; - writel(0, fbi->regbase); - while (readl(fbi->regbase + 0x38) & 0x10) - /* wait */; - writel((((info->var.hsync_len - 1) & 0x3f) << 26) - | ((info->var.left_margin & 0xff) << 18) - | (((info->var.xres - 1) & 0x3ff) << 8) - | (info->var.right_margin & 0xff), fbi->regbase + 0x4); - writel((((info->var.vsync_len - 1) & 0x3f) << 26) - | ((info->var.upper_margin & 0xff) << 18) - | (((info->var.yres - 1) & 0x3ff) << 8) - | (info->var.lower_margin & 0xff), fbi->regbase + 0x8); - writel((((info->var.yres - 1) & 0x400) << 2) - | ((info->var.xres - 1) & 0x400), fbi->regbase + 0x10); - writel(0x80000000, fbi->regbase + 0x20); - writel(control0 | (reg_bpp << 1) | 0x100, fbi->regbase); - - return 0; -} - -static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) -{ - chan &= 0xffff; - chan >>= 16 - bf->length; - return chan << bf->offset; -} - -static int vt8500lcd_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) { - struct vt8500lcd_info *fbi = to_vt8500lcd_info(info); - int ret = 1; - unsigned int val; - if (regno >= 256) - return -EINVAL; - - if (info->var.grayscale) - red = green = blue = - (19595 * red + 38470 * green + 7471 * blue) >> 16; - - switch (fbi->fb.fix.visual) { - case FB_VISUAL_TRUECOLOR: - if (regno < 16) { - u32 *pal = fbi->fb.pseudo_palette; - - val = chan_to_field(red, &fbi->fb.var.red); - val |= chan_to_field(green, &fbi->fb.var.green); - val |= chan_to_field(blue, &fbi->fb.var.blue); - - pal[regno] = val; - ret = 0; - } - break; - - case FB_VISUAL_STATIC_PSEUDOCOLOR: - case FB_VISUAL_PSEUDOCOLOR: - writew((red & 0xf800) - | ((green >> 5) & 0x7e0) - | ((blue >> 11) & 0x1f), - fbi->palette_cpu + sizeof(u16) * regno); - break; - } - - return ret; -} - -static int vt8500lcd_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) -{ - int ret = 0; - struct vt8500lcd_info *fbi = to_vt8500lcd_info(info); - - if (cmd == FBIO_WAITFORVSYNC) { - /* Unmask End of Frame interrupt */ - writel(0xffffffff ^ (1 << 3), fbi->regbase + 0x3c); - ret = wait_event_interruptible_timeout(fbi->wait, - readl(fbi->regbase + 0x38) & (1 << 3), HZ / 10); - /* Mask back to reduce unwanted interrupt traffic */ - writel(0xffffffff, fbi->regbase + 0x3c); - if (ret < 0) - return ret; - if (ret == 0) - return -ETIMEDOUT; - } - - return ret; -} - -static int vt8500lcd_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - unsigned pixlen = info->fix.line_length / info->var.xres_virtual; - unsigned off = pixlen * var->xoffset - + info->fix.line_length * var->yoffset; - struct vt8500lcd_info *fbi = to_vt8500lcd_info(info); - - writel((1 << 31) - | (((var->xres_virtual - var->xres) * pixlen / 4) << 20) - | (off >> 2), fbi->regbase + 0x20); - return 0; -} - -static struct fb_ops vt8500lcd_ops = { - .owner = THIS_MODULE, - .fb_set_par = vt8500lcd_set_par, - .fb_setcolreg = vt8500lcd_setcolreg, - .fb_fillrect = wmt_ge_fillrect, - .fb_copyarea = wmt_ge_copyarea, - .fb_imageblit = sys_imageblit, - .fb_sync = wmt_ge_sync, - .fb_ioctl = vt8500lcd_ioctl, - .fb_pan_display = vt8500lcd_pan_display, -}; - -static irqreturn_t vt8500lcd_handle_irq(int irq, void *dev_id) -{ - struct vt8500lcd_info *fbi = dev_id; - - if (readl(fbi->regbase + 0x38) & (1 << 3)) - wake_up_interruptible(&fbi->wait); - - writel(0xffffffff, fbi->regbase + 0x38); - return IRQ_HANDLED; -} - -static int __devinit vt8500lcd_probe(struct platform_device *pdev) -{ - struct vt8500lcd_info *fbi; - struct resource *res; - struct vt8500fb_platform_data *pdata = pdev->dev.platform_data; - void *addr; - int irq, ret; - - ret = -ENOMEM; - fbi = NULL; - - fbi = kzalloc(sizeof(struct vt8500lcd_info) + sizeof(u32) * 16, - GFP_KERNEL); - if (!fbi) { - dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); - ret = -ENOMEM; - goto failed; - } - - strcpy(fbi->fb.fix.id, "VT8500 LCD"); - - fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; - fbi->fb.fix.xpanstep = 0; - fbi->fb.fix.ypanstep = 1; - fbi->fb.fix.ywrapstep = 0; - fbi->fb.fix.accel = FB_ACCEL_NONE; - - fbi->fb.var.nonstd = 0; - fbi->fb.var.activate = FB_ACTIVATE_NOW; - fbi->fb.var.height = -1; - fbi->fb.var.width = -1; - fbi->fb.var.vmode = FB_VMODE_NONINTERLACED; - - fbi->fb.fbops = &vt8500lcd_ops; - fbi->fb.flags = FBINFO_DEFAULT - | FBINFO_HWACCEL_COPYAREA - | FBINFO_HWACCEL_FILLRECT - | FBINFO_HWACCEL_YPAN - | FBINFO_VIRTFB - | FBINFO_PARTIAL_PAN_OK; - fbi->fb.node = -1; - - addr = fbi; - addr = addr + sizeof(struct vt8500lcd_info); - fbi->fb.pseudo_palette = addr; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no I/O memory resource defined\n"); - ret = -ENODEV; - goto failed_fbi; - } - - res = request_mem_region(res->start, resource_size(res), "vt8500lcd"); - if (res == NULL) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - ret = -EBUSY; - goto failed_fbi; - } - - fbi->regbase = ioremap(res->start, resource_size(res)); - if (fbi->regbase == NULL) { - dev_err(&pdev->dev, "failed to map I/O memory\n"); - ret = -EBUSY; - goto failed_free_res; - } - - fbi->fb.fix.smem_start = pdata->video_mem_phys; - fbi->fb.fix.smem_len = pdata->video_mem_len; - fbi->fb.screen_base = pdata->video_mem_virt; - - fbi->palette_size = PAGE_ALIGN(512); - fbi->palette_cpu = dma_alloc_coherent(&pdev->dev, - fbi->palette_size, - &fbi->palette_phys, - GFP_KERNEL); - if (fbi->palette_cpu == NULL) { - dev_err(&pdev->dev, "Failed to allocate palette buffer\n"); - ret = -ENOMEM; - goto failed_free_io; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no IRQ defined\n"); - ret = -ENODEV; - goto failed_free_palette; - } - - ret = request_irq(irq, vt8500lcd_handle_irq, IRQF_DISABLED, "LCD", fbi); - if (ret) { - dev_err(&pdev->dev, "request_irq failed: %d\n", ret); - ret = -EBUSY; - goto failed_free_palette; - } - - init_waitqueue_head(&fbi->wait); - - if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) { - dev_err(&pdev->dev, "Failed to allocate color map\n"); - ret = -ENOMEM; - goto failed_free_irq; - } - - fb_videomode_to_var(&fbi->fb.var, &pdata->mode); - fbi->fb.var.bits_per_pixel = pdata->bpp; - fbi->fb.var.xres_virtual = pdata->xres_virtual; - fbi->fb.var.yres_virtual = pdata->yres_virtual; - - ret = vt8500lcd_set_par(&fbi->fb); - if (ret) { - dev_err(&pdev->dev, "Failed to set parameters\n"); - goto failed_free_cmap; - } - - writel(fbi->fb.fix.smem_start >> 22, fbi->regbase + 0x1c); - writel((fbi->palette_phys & 0xfffffe00) | 1, fbi->regbase + 0x18); - - platform_set_drvdata(pdev, fbi); - - ret = register_framebuffer(&fbi->fb); - if (ret < 0) { - dev_err(&pdev->dev, - "Failed to register framebuffer device: %d\n", ret); - goto failed_free_cmap; - } - - /* - * Ok, now enable the LCD controller - */ - writel(readl(fbi->regbase) | 1, fbi->regbase); - - return 0; - -failed_free_cmap: - if (fbi->fb.cmap.len) - fb_dealloc_cmap(&fbi->fb.cmap); -failed_free_irq: - free_irq(irq, fbi); -failed_free_palette: - dma_free_coherent(&pdev->dev, fbi->palette_size, - fbi->palette_cpu, fbi->palette_phys); -failed_free_io: - iounmap(fbi->regbase); -failed_free_res: - release_mem_region(res->start, resource_size(res)); -failed_fbi: - platform_set_drvdata(pdev, NULL); - kfree(fbi); -failed: - return ret; -} - -static int __devexit vt8500lcd_remove(struct platform_device *pdev) -{ - struct vt8500lcd_info *fbi = platform_get_drvdata(pdev); - struct resource *res; - int irq; - - unregister_framebuffer(&fbi->fb); - - writel(0, fbi->regbase); - - if (fbi->fb.cmap.len) - fb_dealloc_cmap(&fbi->fb.cmap); - - irq = platform_get_irq(pdev, 0); - free_irq(irq, fbi); - - dma_free_coherent(&pdev->dev, fbi->palette_size, - fbi->palette_cpu, fbi->palette_phys); - - iounmap(fbi->regbase); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - - kfree(fbi); - - return 0; -} - -static struct platform_driver vt8500lcd_driver = { - .probe = vt8500lcd_probe, - .remove = __devexit_p(vt8500lcd_remove), - .driver = { - .owner = THIS_MODULE, - .name = "vt8500-lcd", - }, -}; - -static int __init vt8500lcd_init(void) -{ - return platform_driver_register(&vt8500lcd_driver); -} - -static void __exit vt8500lcd_exit(void) -{ - platform_driver_unregister(&vt8500lcd_driver); -} - -module_init(vt8500lcd_init); -module_exit(vt8500lcd_exit); - -MODULE_AUTHOR("Alexey Charkov "); -MODULE_DESCRIPTION("LCD controller driver for VIA VT8500"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/video/vt8500lcdfb.h b/trunk/drivers/video/vt8500lcdfb.h deleted file mode 100644 index 36ca3ca09d83..000000000000 --- a/trunk/drivers/video/vt8500lcdfb.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * linux/drivers/video/vt8500lcdfb.h - * - * Copyright (C) 2010 Alexey Charkov - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -struct vt8500lcd_info { - struct fb_info fb; - void __iomem *regbase; - void __iomem *palette_cpu; - dma_addr_t palette_phys; - size_t palette_size; - wait_queue_head_t wait; -}; - -static int bpp_values[] = { - 1, - 2, - 4, - 8, - 12, - 16, - 18, - 24, -}; diff --git a/trunk/drivers/video/wm8505fb.c b/trunk/drivers/video/wm8505fb.c deleted file mode 100644 index e37251b792c9..000000000000 --- a/trunk/drivers/video/wm8505fb.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * WonderMedia WM8505 Frame Buffer device driver - * - * Copyright (C) 2010 Ed Spiridonov - * Based on vt8500lcdfb.c - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "wm8505fb_regs.h" -#include "wmt_ge_rops.h" - -#define DRIVER_NAME "wm8505-fb" - -#define to_wm8505fb_info(__info) container_of(__info, \ - struct wm8505fb_info, fb) -struct wm8505fb_info { - struct fb_info fb; - void __iomem *regbase; - unsigned int contrast; -}; - - -static int wm8505fb_init_hw(struct fb_info *info) -{ - struct wm8505fb_info *fbi = to_wm8505fb_info(info); - - int i; - - /* I know the purpose only of few registers, so clear unknown */ - for (i = 0; i < 0x200; i += 4) - writel(0, fbi->regbase + i); - - /* Set frame buffer address */ - writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR); - writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR1); - - /* Set in-memory picture format to RGB 32bpp */ - writel(0x1c, fbi->regbase + WMT_GOVR_COLORSPACE); - writel(1, fbi->regbase + WMT_GOVR_COLORSPACE1); - - /* Virtual buffer size */ - writel(info->var.xres, fbi->regbase + WMT_GOVR_XRES); - writel(info->var.xres_virtual, fbi->regbase + WMT_GOVR_XRES_VIRTUAL); - - /* black magic ;) */ - writel(0xf, fbi->regbase + WMT_GOVR_FHI); - writel(4, fbi->regbase + WMT_GOVR_DVO_SET); - writel(1, fbi->regbase + WMT_GOVR_MIF_ENABLE); - writel(1, fbi->regbase + WMT_GOVR_REG_UPDATE); - - return 0; -} - -static int wm8505fb_set_timing(struct fb_info *info) -{ - struct wm8505fb_info *fbi = to_wm8505fb_info(info); - - int h_start = info->var.left_margin; - int h_end = h_start + info->var.xres; - int h_all = h_end + info->var.right_margin; - int h_sync = info->var.hsync_len; - - int v_start = info->var.upper_margin; - int v_end = v_start + info->var.yres; - int v_all = v_end + info->var.lower_margin; - int v_sync = info->var.vsync_len + 1; - - writel(0, fbi->regbase + WMT_GOVR_TG); - - writel(h_start, fbi->regbase + WMT_GOVR_TIMING_H_START); - writel(h_end, fbi->regbase + WMT_GOVR_TIMING_H_END); - writel(h_all, fbi->regbase + WMT_GOVR_TIMING_H_ALL); - writel(h_sync, fbi->regbase + WMT_GOVR_TIMING_H_SYNC); - - writel(v_start, fbi->regbase + WMT_GOVR_TIMING_V_START); - writel(v_end, fbi->regbase + WMT_GOVR_TIMING_V_END); - writel(v_all, fbi->regbase + WMT_GOVR_TIMING_V_ALL); - writel(v_sync, fbi->regbase + WMT_GOVR_TIMING_V_SYNC); - - writel(1, fbi->regbase + WMT_GOVR_TG); - - return 0; -} - - -static int wm8505fb_set_par(struct fb_info *info) -{ - struct wm8505fb_info *fbi = to_wm8505fb_info(info); - - if (!fbi) - return -EINVAL; - - if (info->var.bits_per_pixel == 32) { - info->var.red.offset = 16; - info->var.red.length = 8; - info->var.red.msb_right = 0; - info->var.green.offset = 8; - info->var.green.length = 8; - info->var.green.msb_right = 0; - info->var.blue.offset = 0; - info->var.blue.length = 8; - info->var.blue.msb_right = 0; - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.line_length = info->var.xres_virtual << 2; - } - - wm8505fb_set_timing(info); - - writel(fbi->contrast<<16 | fbi->contrast<<8 | fbi->contrast, - fbi->regbase + WMT_GOVR_CONTRAST); - - return 0; -} - -static ssize_t contrast_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct wm8505fb_info *fbi = to_wm8505fb_info(info); - - return sprintf(buf, "%d\n", fbi->contrast); -} - -static ssize_t contrast_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct wm8505fb_info *fbi = to_wm8505fb_info(info); - unsigned long tmp; - - if (strict_strtoul(buf, 10, &tmp) || (tmp > 0xff)) - return -EINVAL; - fbi->contrast = tmp; - - wm8505fb_set_par(info); - - return count; -} - -static DEVICE_ATTR(contrast, 0644, contrast_show, contrast_store); - -static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) -{ - chan &= 0xffff; - chan >>= 16 - bf->length; - return chan << bf->offset; -} - -static int wm8505fb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) { - struct wm8505fb_info *fbi = to_wm8505fb_info(info); - int ret = 1; - unsigned int val; - if (regno >= 256) - return -EINVAL; - - if (info->var.grayscale) - red = green = blue = - (19595 * red + 38470 * green + 7471 * blue) >> 16; - - switch (fbi->fb.fix.visual) { - case FB_VISUAL_TRUECOLOR: - if (regno < 16) { - u32 *pal = info->pseudo_palette; - - val = chan_to_field(red, &fbi->fb.var.red); - val |= chan_to_field(green, &fbi->fb.var.green); - val |= chan_to_field(blue, &fbi->fb.var.blue); - - pal[regno] = val; - ret = 0; - } - break; - } - - return ret; -} - -static int wm8505fb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - struct wm8505fb_info *fbi = to_wm8505fb_info(info); - - writel(var->xoffset, fbi->regbase + WMT_GOVR_XPAN); - writel(var->yoffset, fbi->regbase + WMT_GOVR_YPAN); - return 0; -} - -static int wm8505fb_blank(int blank, struct fb_info *info) -{ - struct wm8505fb_info *fbi = to_wm8505fb_info(info); - - switch (blank) { - case FB_BLANK_UNBLANK: - wm8505fb_set_timing(info); - break; - default: - writel(0, fbi->regbase + WMT_GOVR_TIMING_V_SYNC); - break; - } - - return 0; -} - -static struct fb_ops wm8505fb_ops = { - .owner = THIS_MODULE, - .fb_set_par = wm8505fb_set_par, - .fb_setcolreg = wm8505fb_setcolreg, - .fb_fillrect = wmt_ge_fillrect, - .fb_copyarea = wmt_ge_copyarea, - .fb_imageblit = sys_imageblit, - .fb_sync = wmt_ge_sync, - .fb_pan_display = wm8505fb_pan_display, - .fb_blank = wm8505fb_blank, -}; - -static int __devinit wm8505fb_probe(struct platform_device *pdev) -{ - struct wm8505fb_info *fbi; - struct resource *res; - void *addr; - struct vt8500fb_platform_data *pdata; - int ret; - - pdata = pdev->dev.platform_data; - - ret = -ENOMEM; - fbi = NULL; - - fbi = kzalloc(sizeof(struct wm8505fb_info) + sizeof(u32) * 16, - GFP_KERNEL); - if (!fbi) { - dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); - ret = -ENOMEM; - goto failed; - } - - strcpy(fbi->fb.fix.id, DRIVER_NAME); - - fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; - fbi->fb.fix.xpanstep = 1; - fbi->fb.fix.ypanstep = 1; - fbi->fb.fix.ywrapstep = 0; - fbi->fb.fix.accel = FB_ACCEL_NONE; - - fbi->fb.fbops = &wm8505fb_ops; - fbi->fb.flags = FBINFO_DEFAULT - | FBINFO_HWACCEL_COPYAREA - | FBINFO_HWACCEL_FILLRECT - | FBINFO_HWACCEL_XPAN - | FBINFO_HWACCEL_YPAN - | FBINFO_VIRTFB - | FBINFO_PARTIAL_PAN_OK; - fbi->fb.node = -1; - - addr = fbi; - addr = addr + sizeof(struct wm8505fb_info); - fbi->fb.pseudo_palette = addr; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no I/O memory resource defined\n"); - ret = -ENODEV; - goto failed_fbi; - } - - res = request_mem_region(res->start, resource_size(res), "wm8505fb"); - if (res == NULL) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - ret = -EBUSY; - goto failed_fbi; - } - - fbi->regbase = ioremap(res->start, resource_size(res)); - if (fbi->regbase == NULL) { - dev_err(&pdev->dev, "failed to map I/O memory\n"); - ret = -EBUSY; - goto failed_free_res; - } - - fb_videomode_to_var(&fbi->fb.var, &pdata->mode); - - fbi->fb.var.nonstd = 0; - fbi->fb.var.activate = FB_ACTIVATE_NOW; - - fbi->fb.var.height = -1; - fbi->fb.var.width = -1; - fbi->fb.var.xres_virtual = pdata->xres_virtual; - fbi->fb.var.yres_virtual = pdata->yres_virtual; - fbi->fb.var.bits_per_pixel = pdata->bpp; - - fbi->fb.fix.smem_start = pdata->video_mem_phys; - fbi->fb.fix.smem_len = pdata->video_mem_len; - fbi->fb.screen_base = pdata->video_mem_virt; - fbi->fb.screen_size = pdata->video_mem_len; - - if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) { - dev_err(&pdev->dev, "Failed to allocate color map\n"); - ret = -ENOMEM; - goto failed_free_io; - } - - wm8505fb_init_hw(&fbi->fb); - - fbi->contrast = 0x80; - ret = wm8505fb_set_par(&fbi->fb); - if (ret) { - dev_err(&pdev->dev, "Failed to set parameters\n"); - goto failed_free_cmap; - } - - platform_set_drvdata(pdev, fbi); - - ret = register_framebuffer(&fbi->fb); - if (ret < 0) { - dev_err(&pdev->dev, - "Failed to register framebuffer device: %d\n", ret); - goto failed_free_cmap; - } - - ret = device_create_file(&pdev->dev, &dev_attr_contrast); - if (ret < 0) { - printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n", - fbi->fb.node, ret); - } - - printk(KERN_INFO "fb%d: %s frame buffer at 0x%lx-0x%lx\n", - fbi->fb.node, fbi->fb.fix.id, fbi->fb.fix.smem_start, - fbi->fb.fix.smem_start + fbi->fb.fix.smem_len - 1); - - return 0; - -failed_free_cmap: - if (fbi->fb.cmap.len) - fb_dealloc_cmap(&fbi->fb.cmap); -failed_free_io: - iounmap(fbi->regbase); -failed_free_res: - release_mem_region(res->start, resource_size(res)); -failed_fbi: - platform_set_drvdata(pdev, NULL); - kfree(fbi); -failed: - return ret; -} - -static int __devexit wm8505fb_remove(struct platform_device *pdev) -{ - struct wm8505fb_info *fbi = platform_get_drvdata(pdev); - struct resource *res; - - device_remove_file(&pdev->dev, &dev_attr_contrast); - - unregister_framebuffer(&fbi->fb); - - writel(0, fbi->regbase); - - if (fbi->fb.cmap.len) - fb_dealloc_cmap(&fbi->fb.cmap); - - iounmap(fbi->regbase); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - - kfree(fbi); - - return 0; -} - -static struct platform_driver wm8505fb_driver = { - .probe = wm8505fb_probe, - .remove = __devexit_p(wm8505fb_remove), - .driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - }, -}; - -static int __init wm8505fb_init(void) -{ - return platform_driver_register(&wm8505fb_driver); -} - -static void __exit wm8505fb_exit(void) -{ - platform_driver_unregister(&wm8505fb_driver); -} - -module_init(wm8505fb_init); -module_exit(wm8505fb_exit); - -MODULE_AUTHOR("Ed Spiridonov "); -MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/video/wm8505fb_regs.h b/trunk/drivers/video/wm8505fb_regs.h deleted file mode 100644 index 4dd41668c6d1..000000000000 --- a/trunk/drivers/video/wm8505fb_regs.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * GOVR registers list for WM8505 chips - * - * Copyright (C) 2010 Ed Spiridonov - * Based on VIA/WonderMedia wm8510-govrh-reg.h - * http://github.com/projectgus/kernel_wm8505/blob/wm8505_2.6.29/ - * drivers/video/wmt/register/wm8510/wm8510-govrh-reg.h - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _WM8505FB_REGS_H -#define _WM8505FB_REGS_H - -/* - * Color space select register, default value 0x1c - * BIT0 GOVRH_DVO_YUV2RGB_ENABLE - * BIT1 GOVRH_VGA_YUV2RGB_ENABLE - * BIT2 GOVRH_RGB_MODE - * BIT3 GOVRH_DAC_CLKINV - * BIT4 GOVRH_BLANK_ZERO - */ -#define WMT_GOVR_COLORSPACE 0x1e4 -/* - * Another colorspace select register, default value 1 - * BIT0 GOVRH_DVO_RGB - * BIT1 GOVRH_DVO_YUV422 - */ -#define WMT_GOVR_COLORSPACE1 0x30 - -#define WMT_GOVR_CONTRAST 0x1b8 -#define WMT_GOVR_BRGHTNESS 0x1bc /* incompatible with RGB? */ - -/* Framubeffer address */ -#define WMT_GOVR_FBADDR 0x90 -#define WMT_GOVR_FBADDR1 0x94 /* UV offset in YUV mode */ - -/* Offset of visible window */ -#define WMT_GOVR_XPAN 0xa4 -#define WMT_GOVR_YPAN 0xa0 - -#define WMT_GOVR_XRES 0x98 -#define WMT_GOVR_XRES_VIRTUAL 0x9c - -#define WMT_GOVR_MIF_ENABLE 0x80 -#define WMT_GOVR_FHI 0xa8 -#define WMT_GOVR_REG_UPDATE 0xe4 - -/* - * BIT0 GOVRH_DVO_OUTWIDTH - * BIT1 GOVRH_DVO_SYNC_POLAR - * BIT2 GOVRH_DVO_ENABLE - */ -#define WMT_GOVR_DVO_SET 0x148 - -/* Timing generator? */ -#define WMT_GOVR_TG 0x100 - -/* Timings */ -#define WMT_GOVR_TIMING_H_ALL 0x108 -#define WMT_GOVR_TIMING_V_ALL 0x10c -#define WMT_GOVR_TIMING_V_START 0x110 -#define WMT_GOVR_TIMING_V_END 0x114 -#define WMT_GOVR_TIMING_H_START 0x118 -#define WMT_GOVR_TIMING_H_END 0x11c -#define WMT_GOVR_TIMING_V_SYNC 0x128 -#define WMT_GOVR_TIMING_H_SYNC 0x12c - -#endif /* _WM8505FB_REGS_H */ diff --git a/trunk/drivers/video/wmt_ge_rops.c b/trunk/drivers/video/wmt_ge_rops.c deleted file mode 100644 index f31883f8eaf7..000000000000 --- a/trunk/drivers/video/wmt_ge_rops.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * linux/drivers/video/wmt_ge_rops.c - * - * Accelerators for raster operations using WonderMedia Graphics Engine - * - * Copyright (C) 2010 Alexey Charkov - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "fb_draw.h" - -#define GE_COMMAND_OFF 0x00 -#define GE_DEPTH_OFF 0x04 -#define GE_HIGHCOLOR_OFF 0x08 -#define GE_ROPCODE_OFF 0x14 -#define GE_FIRE_OFF 0x18 -#define GE_SRCBASE_OFF 0x20 -#define GE_SRCDISPW_OFF 0x24 -#define GE_SRCDISPH_OFF 0x28 -#define GE_SRCAREAX_OFF 0x2c -#define GE_SRCAREAY_OFF 0x30 -#define GE_SRCAREAW_OFF 0x34 -#define GE_SRCAREAH_OFF 0x38 -#define GE_DESTBASE_OFF 0x3c -#define GE_DESTDISPW_OFF 0x40 -#define GE_DESTDISPH_OFF 0x44 -#define GE_DESTAREAX_OFF 0x48 -#define GE_DESTAREAY_OFF 0x4c -#define GE_DESTAREAW_OFF 0x50 -#define GE_DESTAREAH_OFF 0x54 -#define GE_PAT0C_OFF 0x88 /* Pattern 0 color */ -#define GE_ENABLE_OFF 0xec -#define GE_INTEN_OFF 0xf0 -#define GE_STATUS_OFF 0xf8 - -static void __iomem *regbase; - -void wmt_ge_fillrect(struct fb_info *p, const struct fb_fillrect *rect) -{ - unsigned long fg, pat; - - if (p->state != FBINFO_STATE_RUNNING) - return; - - if (p->fix.visual == FB_VISUAL_TRUECOLOR || - p->fix.visual == FB_VISUAL_DIRECTCOLOR) - fg = ((u32 *) (p->pseudo_palette))[rect->color]; - else - fg = rect->color; - - pat = pixel_to_pat(p->var.bits_per_pixel, fg); - - if (p->fbops->fb_sync) - p->fbops->fb_sync(p); - - writel(p->var.bits_per_pixel == 32 ? 3 : - (p->var.bits_per_pixel == 8 ? 0 : 1), regbase + GE_DEPTH_OFF); - writel(p->var.bits_per_pixel == 15 ? 1 : 0, regbase + GE_HIGHCOLOR_OFF); - writel(p->fix.smem_start, regbase + GE_DESTBASE_OFF); - writel(p->var.xres_virtual - 1, regbase + GE_DESTDISPW_OFF); - writel(p->var.yres_virtual - 1, regbase + GE_DESTDISPH_OFF); - writel(rect->dx, regbase + GE_DESTAREAX_OFF); - writel(rect->dy, regbase + GE_DESTAREAY_OFF); - writel(rect->width - 1, regbase + GE_DESTAREAW_OFF); - writel(rect->height - 1, regbase + GE_DESTAREAH_OFF); - - writel(pat, regbase + GE_PAT0C_OFF); - writel(1, regbase + GE_COMMAND_OFF); - writel(rect->rop == ROP_XOR ? 0x5a : 0xf0, regbase + GE_ROPCODE_OFF); - writel(1, regbase + GE_FIRE_OFF); -} -EXPORT_SYMBOL_GPL(wmt_ge_fillrect); - -void wmt_ge_copyarea(struct fb_info *p, const struct fb_copyarea *area) -{ - if (p->state != FBINFO_STATE_RUNNING) - return; - - if (p->fbops->fb_sync) - p->fbops->fb_sync(p); - - writel(p->var.bits_per_pixel > 16 ? 3 : - (p->var.bits_per_pixel > 8 ? 1 : 0), regbase + GE_DEPTH_OFF); - - writel(p->fix.smem_start, regbase + GE_SRCBASE_OFF); - writel(p->var.xres_virtual - 1, regbase + GE_SRCDISPW_OFF); - writel(p->var.yres_virtual - 1, regbase + GE_SRCDISPH_OFF); - writel(area->sx, regbase + GE_SRCAREAX_OFF); - writel(area->sy, regbase + GE_SRCAREAY_OFF); - writel(area->width - 1, regbase + GE_SRCAREAW_OFF); - writel(area->height - 1, regbase + GE_SRCAREAH_OFF); - - writel(p->fix.smem_start, regbase + GE_DESTBASE_OFF); - writel(p->var.xres_virtual - 1, regbase + GE_DESTDISPW_OFF); - writel(p->var.yres_virtual - 1, regbase + GE_DESTDISPH_OFF); - writel(area->dx, regbase + GE_DESTAREAX_OFF); - writel(area->dy, regbase + GE_DESTAREAY_OFF); - writel(area->width - 1, regbase + GE_DESTAREAW_OFF); - writel(area->height - 1, regbase + GE_DESTAREAH_OFF); - - writel(0xcc, regbase + GE_ROPCODE_OFF); - writel(1, regbase + GE_COMMAND_OFF); - writel(1, regbase + GE_FIRE_OFF); -} -EXPORT_SYMBOL_GPL(wmt_ge_copyarea); - -int wmt_ge_sync(struct fb_info *p) -{ - int loops = 5000000; - while ((readl(regbase + GE_STATUS_OFF) & 4) && --loops) - cpu_relax(); - return loops > 0 ? 0 : -EBUSY; -} -EXPORT_SYMBOL_GPL(wmt_ge_sync); - -static int __devinit wmt_ge_rops_probe(struct platform_device *pdev) -{ - struct resource *res; - int ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no I/O memory resource defined\n"); - ret = -ENODEV; - goto error; - } - - /* Only one ROP engine is presently supported. */ - if (unlikely(regbase)) { - WARN_ON(1); - return -EBUSY; - } - - regbase = ioremap(res->start, resource_size(res)); - if (regbase == NULL) { - dev_err(&pdev->dev, "failed to map I/O memory\n"); - ret = -EBUSY; - goto error; - } - - writel(1, regbase + GE_ENABLE_OFF); - printk(KERN_INFO "Enabled support for WMT GE raster acceleration\n"); - - return 0; - -error: - return ret; -} - -static int __devexit wmt_ge_rops_remove(struct platform_device *pdev) -{ - iounmap(regbase); - return 0; -} - -static struct platform_driver wmt_ge_rops_driver = { - .probe = wmt_ge_rops_probe, - .remove = __devexit_p(wmt_ge_rops_remove), - .driver = { - .owner = THIS_MODULE, - .name = "wmt_ge_rops", - }, -}; - -static int __init wmt_ge_rops_init(void) -{ - return platform_driver_register(&wmt_ge_rops_driver); -} - -static void __exit wmt_ge_rops_exit(void) -{ - platform_driver_unregister(&wmt_ge_rops_driver); -} - -module_init(wmt_ge_rops_init); -module_exit(wmt_ge_rops_exit); - -MODULE_AUTHOR("Alexey Charkov