aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-08-29 05:14:30 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-08-29 05:14:30 -0400
commitd4a7dbfdf180a656de3eb9e64614e2b991ffaa53 (patch)
treef7d0d548004751aea77f63e6fd695faf0785bde0 /drivers/video
parentb5480ed72e4f299c53d1857faaf4f492650ccc43 (diff)
parentfa514fbc57419505d0e9423dbb8742f2775f882e (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next
Conflicts: drivers/video/atmel_lcdfb.c
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig16
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/au1200fb.c297
-rw-r--r--drivers/video/backlight/adp8860_bl.c1
-rw-r--r--drivers/video/backlight/adp8870_bl.c1
-rw-r--r--drivers/video/carminefb.c6
-rw-r--r--drivers/video/controlfb.c2
-rw-r--r--drivers/video/da8xx-fb.c151
-rw-r--r--drivers/video/fb_defio.c3
-rw-r--r--drivers/video/fsl-diu-fb.c74
-rw-r--r--drivers/video/grvga.c579
-rw-r--r--drivers/video/msm/mdp.c4
-rw-r--r--drivers/video/platinumfb.c2
-rw-r--r--drivers/video/pm2fb.c2
-rw-r--r--drivers/video/pm3fb.c2
-rw-r--r--drivers/video/pxa3xx-gcu.c2
-rw-r--r--drivers/video/s3c2410fb.c1
-rw-r--r--drivers/video/s3fb.c2
-rw-r--r--drivers/video/skeletonfb.c2
-rw-r--r--drivers/video/udlfb.c21
-rw-r--r--drivers/video/valkyriefb.c2
-rw-r--r--drivers/video/via/via_modesetting.h5
-rw-r--r--drivers/video/via/viafbdev.c16
-rw-r--r--drivers/video/xilinxfb.c1
24 files changed, 966 insertions, 227 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 963b8b767b83..903ace58fec5 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -259,6 +259,15 @@ config FB_TILEBLITTING
259comment "Frame buffer hardware drivers" 259comment "Frame buffer hardware drivers"
260 depends on FB 260 depends on FB
261 261
262config FB_GRVGA
263 tristate "Aeroflex Gaisler framebuffer support"
264 depends on FB && SPARC
265 select FB_CFB_FILLRECT
266 select FB_CFB_COPYAREA
267 select FB_CFB_IMAGEBLIT
268 ---help---
269 This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
270
262config FB_CIRRUS 271config FB_CIRRUS
263 tristate "Cirrus Logic support" 272 tristate "Cirrus Logic support"
264 depends on FB && (ZORRO || PCI) 273 depends on FB && (ZORRO || PCI)
@@ -1756,9 +1765,10 @@ config FB_AU1100
1756config FB_AU1200 1765config FB_AU1200
1757 bool "Au1200 LCD Driver" 1766 bool "Au1200 LCD Driver"
1758 depends on (FB = y) && MIPS && SOC_AU1200 1767 depends on (FB = y) && MIPS && SOC_AU1200
1759 select FB_CFB_FILLRECT 1768 select FB_SYS_FILLRECT
1760 select FB_CFB_COPYAREA 1769 select FB_SYS_COPYAREA
1761 select FB_CFB_IMAGEBLIT 1770 select FB_SYS_IMAGEBLIT
1771 select FB_SYS_FOPS
1762 help 1772 help
1763 This is the framebuffer driver for the AMD Au1200 SOC. It can drive 1773 This is the framebuffer driver for the AMD Au1200 SOC. It can drive
1764 various panels and CRTs by passing in kernel cmd line option 1774 various panels and CRTs by passing in kernel cmd line option
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8b83129e209c..43079108bb16 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
33obj-$(CONFIG_FB_ARC) += arcfb.o 33obj-$(CONFIG_FB_ARC) += arcfb.o
34obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o 34obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
35obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o 35obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
36obj-$(CONFIG_FB_GRVGA) += grvga.o
36obj-$(CONFIG_FB_PM2) += pm2fb.o 37obj-$(CONFIG_FB_PM2) += pm2fb.o
37obj-$(CONFIG_FB_PM3) += pm3fb.o 38obj-$(CONFIG_FB_PM3) += pm3fb.o
38 39
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 5dff32ac8044..ed5dcdb29cf7 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -46,14 +46,6 @@
46#include <asm/mach-au1x00/au1000.h> 46#include <asm/mach-au1x00/au1000.h>
47#include "au1200fb.h" 47#include "au1200fb.h"
48 48
49#ifdef CONFIG_PM
50#include <asm/mach-au1x00/au1xxx_pm.h>
51#endif
52
53#ifndef CONFIG_FB_AU1200_DEVS
54#define CONFIG_FB_AU1200_DEVS 4
55#endif
56
57#define DRIVER_NAME "au1200fb" 49#define DRIVER_NAME "au1200fb"
58#define DRIVER_DESC "LCD controller driver for AU1200 processors" 50#define DRIVER_DESC "LCD controller driver for AU1200 processors"
59 51
@@ -150,7 +142,7 @@ struct au1200_lcd_iodata_t {
150 142
151/* Private, per-framebuffer management information (independent of the panel itself) */ 143/* Private, per-framebuffer management information (independent of the panel itself) */
152struct au1200fb_device { 144struct au1200fb_device {
153 struct fb_info fb_info; /* FB driver info record */ 145 struct fb_info *fb_info; /* FB driver info record */
154 146
155 int plane; 147 int plane;
156 unsigned char* fb_mem; /* FrameBuffer memory map */ 148 unsigned char* fb_mem; /* FrameBuffer memory map */
@@ -158,7 +150,6 @@ struct au1200fb_device {
158 dma_addr_t fb_phys; 150 dma_addr_t fb_phys;
159}; 151};
160 152
161static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
162/********************************************************************/ 153/********************************************************************/
163 154
164/* LCD controller restrictions */ 155/* LCD controller restrictions */
@@ -171,10 +162,18 @@ static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
171/* Default number of visible screen buffer to allocate */ 162/* Default number of visible screen buffer to allocate */
172#define AU1200FB_NBR_VIDEO_BUFFERS 1 163#define AU1200FB_NBR_VIDEO_BUFFERS 1
173 164
165/* Default maximum number of fb devices to create */
166#define MAX_DEVICE_COUNT 4
167
168/* Default window configuration entry to use (see windows[]) */
169#define DEFAULT_WINDOW_INDEX 2
170
174/********************************************************************/ 171/********************************************************************/
175 172
173static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
176static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR; 174static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
177static int window_index = 2; /* default is zero */ 175static int device_count = MAX_DEVICE_COUNT;
176static int window_index = DEFAULT_WINDOW_INDEX; /* default is zero */
178static int panel_index = 2; /* default is zero */ 177static int panel_index = 2; /* default is zero */
179static struct window_settings *win; 178static struct window_settings *win;
180static struct panel_settings *panel; 179static struct panel_settings *panel;
@@ -205,12 +204,6 @@ struct window_settings {
205extern int board_au1200fb_panel_init (void); 204extern int board_au1200fb_panel_init (void);
206extern int board_au1200fb_panel_shutdown (void); 205extern int board_au1200fb_panel_shutdown (void);
207 206
208#ifdef CONFIG_PM
209int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
210 au1xxx_request_t request, void *data);
211au1xxx_power_dev_t *LCD_pm_dev;
212#endif
213
214/* 207/*
215 * Default window configurations 208 * Default window configurations
216 */ 209 */
@@ -652,25 +645,6 @@ static struct panel_settings known_lcd_panels[] =
652 645
653/********************************************************************/ 646/********************************************************************/
654 647
655#ifdef CONFIG_PM
656static int set_brightness(unsigned int brightness)
657{
658 unsigned int hi1, divider;
659
660 /* limit brightness pwm duty to >= 30/1600 */
661 if (brightness < 30) {
662 brightness = 30;
663 }
664 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
665 hi1 = (lcd->pwmhi >> 16) + 1;
666 hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
667 lcd->pwmhi &= 0xFFFF;
668 lcd->pwmhi |= (hi1 << 16);
669
670 return brightness;
671}
672#endif /* CONFIG_PM */
673
674static int winbpp (unsigned int winctrl1) 648static int winbpp (unsigned int winctrl1)
675{ 649{
676 int bits = 0; 650 int bits = 0;
@@ -712,8 +686,8 @@ static int fbinfo2index (struct fb_info *fb_info)
712{ 686{
713 int i; 687 int i;
714 688
715 for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) { 689 for (i = 0; i < device_count; ++i) {
716 if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info)) 690 if (fb_info == _au1200fb_infos[i])
717 return i; 691 return i;
718 } 692 }
719 printk("au1200fb: ERROR: fbinfo2index failed!\n"); 693 printk("au1200fb: ERROR: fbinfo2index failed!\n");
@@ -962,7 +936,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev)
962 lcd->window[plane].winctrl2 = ( 0 936 lcd->window[plane].winctrl2 = ( 0
963 | LCD_WINCTRL2_CKMODE_00 937 | LCD_WINCTRL2_CKMODE_00
964 | LCD_WINCTRL2_DBM 938 | LCD_WINCTRL2_DBM
965 | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length) 939 | LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
966 | LCD_WINCTRL2_SCX_1 940 | LCD_WINCTRL2_SCX_1
967 | LCD_WINCTRL2_SCY_1 941 | LCD_WINCTRL2_SCY_1
968 ) ; 942 ) ;
@@ -1050,7 +1024,7 @@ static void au1200fb_update_fbinfo(struct fb_info *fbi)
1050static int au1200fb_fb_check_var(struct fb_var_screeninfo *var, 1024static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
1051 struct fb_info *fbi) 1025 struct fb_info *fbi)
1052{ 1026{
1053 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi; 1027 struct au1200fb_device *fbdev = fbi->par;
1054 u32 pixclock; 1028 u32 pixclock;
1055 int screen_size, plane; 1029 int screen_size, plane;
1056 1030
@@ -1142,7 +1116,7 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
1142 */ 1116 */
1143static int au1200fb_fb_set_par(struct fb_info *fbi) 1117static int au1200fb_fb_set_par(struct fb_info *fbi)
1144{ 1118{
1145 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi; 1119 struct au1200fb_device *fbdev = fbi->par;
1146 1120
1147 au1200fb_update_fbinfo(fbi); 1121 au1200fb_update_fbinfo(fbi);
1148 au1200_setmode(fbdev); 1122 au1200_setmode(fbdev);
@@ -1246,11 +1220,7 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1246{ 1220{
1247 unsigned int len; 1221 unsigned int len;
1248 unsigned long start=0, off; 1222 unsigned long start=0, off;
1249 struct au1200fb_device *fbdev = (struct au1200fb_device *) info; 1223 struct au1200fb_device *fbdev = info->par;
1250
1251#ifdef CONFIG_PM
1252 au1xxx_pm_access(LCD_pm_dev);
1253#endif
1254 1224
1255 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { 1225 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
1256 return -EINVAL; 1226 return -EINVAL;
@@ -1461,10 +1431,6 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
1461 int plane; 1431 int plane;
1462 int val; 1432 int val;
1463 1433
1464#ifdef CONFIG_PM
1465 au1xxx_pm_access(LCD_pm_dev);
1466#endif
1467
1468 plane = fbinfo2index(info); 1434 plane = fbinfo2index(info);
1469 print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane); 1435 print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
1470 1436
@@ -1536,9 +1502,11 @@ static struct fb_ops au1200fb_fb_ops = {
1536 .fb_set_par = au1200fb_fb_set_par, 1502 .fb_set_par = au1200fb_fb_set_par,
1537 .fb_setcolreg = au1200fb_fb_setcolreg, 1503 .fb_setcolreg = au1200fb_fb_setcolreg,
1538 .fb_blank = au1200fb_fb_blank, 1504 .fb_blank = au1200fb_fb_blank,
1539 .fb_fillrect = cfb_fillrect, 1505 .fb_fillrect = sys_fillrect,
1540 .fb_copyarea = cfb_copyarea, 1506 .fb_copyarea = sys_copyarea,
1541 .fb_imageblit = cfb_imageblit, 1507 .fb_imageblit = sys_imageblit,
1508 .fb_read = fb_sys_read,
1509 .fb_write = fb_sys_write,
1542 .fb_sync = NULL, 1510 .fb_sync = NULL,
1543 .fb_ioctl = au1200fb_ioctl, 1511 .fb_ioctl = au1200fb_ioctl,
1544 .fb_mmap = au1200fb_fb_mmap, 1512 .fb_mmap = au1200fb_fb_mmap,
@@ -1561,10 +1529,9 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
1561 1529
1562static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) 1530static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
1563{ 1531{
1564 struct fb_info *fbi = &fbdev->fb_info; 1532 struct fb_info *fbi = fbdev->fb_info;
1565 int bpp; 1533 int bpp;
1566 1534
1567 memset(fbi, 0, sizeof(struct fb_info));
1568 fbi->fbops = &au1200fb_fb_ops; 1535 fbi->fbops = &au1200fb_fb_ops;
1569 1536
1570 bpp = winbpp(win->w[fbdev->plane].mode_winctrl1); 1537 bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
@@ -1623,24 +1590,36 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
1623 1590
1624/* AU1200 LCD controller device driver */ 1591/* AU1200 LCD controller device driver */
1625 1592
1626static int au1200fb_drv_probe(struct platform_device *dev) 1593static int __devinit au1200fb_drv_probe(struct platform_device *dev)
1627{ 1594{
1628 struct au1200fb_device *fbdev; 1595 struct au1200fb_device *fbdev;
1596 struct fb_info *fbi = NULL;
1629 unsigned long page; 1597 unsigned long page;
1630 int bpp, plane, ret; 1598 int bpp, plane, ret, irq;
1631 1599
1632 if (!dev) 1600 /* shut gcc up */
1633 return -EINVAL; 1601 ret = 0;
1602 fbdev = NULL;
1603
1604 /* Kickstart the panel */
1605 au1200_setpanel(panel);
1634 1606
1635 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) { 1607 for (plane = 0; plane < device_count; ++plane) {
1636 bpp = winbpp(win->w[plane].mode_winctrl1); 1608 bpp = winbpp(win->w[plane].mode_winctrl1);
1637 if (win->w[plane].xres == 0) 1609 if (win->w[plane].xres == 0)
1638 win->w[plane].xres = panel->Xres; 1610 win->w[plane].xres = panel->Xres;
1639 if (win->w[plane].yres == 0) 1611 if (win->w[plane].yres == 0)
1640 win->w[plane].yres = panel->Yres; 1612 win->w[plane].yres = panel->Yres;
1641 1613
1642 fbdev = &_au1200fb_devices[plane]; 1614 fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
1643 memset(fbdev, 0, sizeof(struct au1200fb_device)); 1615 &dev->dev);
1616 if (!fbi)
1617 goto failed;
1618
1619 _au1200fb_infos[plane] = fbi;
1620 fbdev = fbi->par;
1621 fbdev->fb_info = fbi;
1622
1644 fbdev->plane = plane; 1623 fbdev->plane = plane;
1645 1624
1646 /* Allocate the framebuffer to the maximum screen size */ 1625 /* Allocate the framebuffer to the maximum screen size */
@@ -1673,30 +1652,31 @@ static int au1200fb_drv_probe(struct platform_device *dev)
1673 goto failed; 1652 goto failed;
1674 1653
1675 /* Register new framebuffer */ 1654 /* Register new framebuffer */
1676 if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) { 1655 ret = register_framebuffer(fbi);
1656 if (ret < 0) {
1677 print_err("cannot register new framebuffer"); 1657 print_err("cannot register new framebuffer");
1678 goto failed; 1658 goto failed;
1679 } 1659 }
1680 1660
1681 au1200fb_fb_set_par(&fbdev->fb_info); 1661 au1200fb_fb_set_par(fbi);
1682 1662
1683#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) 1663#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
1684 if (plane == 0) 1664 if (plane == 0)
1685 if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) { 1665 if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
1686 /* Start display and show logo on boot */ 1666 /* Start display and show logo on boot */
1687 fb_set_cmap(&fbdev->fb_info.cmap, 1667 fb_set_cmap(&fbi->cmap, fbi);
1688 &fbdev->fb_info); 1668 fb_show_logo(fbi, FB_ROTATE_UR);
1689
1690 fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
1691 } 1669 }
1692#endif 1670#endif
1693 } 1671 }
1694 1672
1695 /* Now hook interrupt too */ 1673 /* Now hook interrupt too */
1696 if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq, 1674 irq = platform_get_irq(dev, 0);
1697 IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev)) < 0) { 1675 ret = request_irq(irq, au1200fb_handle_irq,
1676 IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev);
1677 if (ret) {
1698 print_err("fail to request interrupt line %d (err: %d)", 1678 print_err("fail to request interrupt line %d (err: %d)",
1699 AU1200_LCD_INT, ret); 1679 irq, ret);
1700 goto failed; 1680 goto failed;
1701 } 1681 }
1702 1682
@@ -1705,84 +1685,108 @@ static int au1200fb_drv_probe(struct platform_device *dev)
1705failed: 1685failed:
1706 /* NOTE: This only does the current plane/window that failed; others are still active */ 1686 /* NOTE: This only does the current plane/window that failed; others are still active */
1707 if (fbdev->fb_mem) 1687 if (fbdev->fb_mem)
1708 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), 1688 dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
1709 fbdev->fb_mem, fbdev->fb_phys); 1689 fbdev->fb_mem, fbdev->fb_phys);
1710 if (fbdev->fb_info.cmap.len != 0) 1690 if (fbi) {
1711 fb_dealloc_cmap(&fbdev->fb_info.cmap); 1691 if (fbi->cmap.len != 0)
1712 if (fbdev->fb_info.pseudo_palette) 1692 fb_dealloc_cmap(&fbi->cmap);
1713 kfree(fbdev->fb_info.pseudo_palette); 1693 kfree(fbi->pseudo_palette);
1694 }
1714 if (plane == 0) 1695 if (plane == 0)
1715 free_irq(AU1200_LCD_INT, (void*)dev); 1696 free_irq(AU1200_LCD_INT, (void*)dev);
1716 return ret; 1697 return ret;
1717} 1698}
1718 1699
1719static int au1200fb_drv_remove(struct platform_device *dev) 1700static int __devexit au1200fb_drv_remove(struct platform_device *dev)
1720{ 1701{
1721 struct au1200fb_device *fbdev; 1702 struct au1200fb_device *fbdev;
1703 struct fb_info *fbi;
1722 int plane; 1704 int plane;
1723 1705
1724 if (!dev)
1725 return -ENODEV;
1726
1727 /* Turn off the panel */ 1706 /* Turn off the panel */
1728 au1200_setpanel(NULL); 1707 au1200_setpanel(NULL);
1729 1708
1730 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) 1709 for (plane = 0; plane < device_count; ++plane) {
1731 { 1710 fbi = _au1200fb_infos[plane];
1732 fbdev = &_au1200fb_devices[plane]; 1711 fbdev = fbi->par;
1733 1712
1734 /* Clean up all probe data */ 1713 /* Clean up all probe data */
1735 unregister_framebuffer(&fbdev->fb_info); 1714 unregister_framebuffer(fbi);
1736 if (fbdev->fb_mem) 1715 if (fbdev->fb_mem)
1737 dma_free_noncoherent(&dev->dev, 1716 dma_free_noncoherent(&dev->dev,
1738 PAGE_ALIGN(fbdev->fb_len), 1717 PAGE_ALIGN(fbdev->fb_len),
1739 fbdev->fb_mem, fbdev->fb_phys); 1718 fbdev->fb_mem, fbdev->fb_phys);
1740 if (fbdev->fb_info.cmap.len != 0) 1719 if (fbi->cmap.len != 0)
1741 fb_dealloc_cmap(&fbdev->fb_info.cmap); 1720 fb_dealloc_cmap(&fbi->cmap);
1742 if (fbdev->fb_info.pseudo_palette) 1721 kfree(fbi->pseudo_palette);
1743 kfree(fbdev->fb_info.pseudo_palette); 1722
1723 framebuffer_release(fbi);
1724 _au1200fb_infos[plane] = NULL;
1744 } 1725 }
1745 1726
1746 free_irq(AU1200_LCD_INT, (void *)dev); 1727 free_irq(platform_get_irq(dev, 0), (void *)dev);
1747 1728
1748 return 0; 1729 return 0;
1749} 1730}
1750 1731
1751#ifdef CONFIG_PM 1732#ifdef CONFIG_PM
1752static int au1200fb_drv_suspend(struct platform_device *dev, u32 state) 1733static int au1200fb_drv_suspend(struct device *dev)
1753{ 1734{
1754 /* TODO */ 1735 au1200_setpanel(NULL);
1736
1737 lcd->outmask = 0;
1738 au_sync();
1739
1755 return 0; 1740 return 0;
1756} 1741}
1757 1742
1758static int au1200fb_drv_resume(struct platform_device *dev) 1743static int au1200fb_drv_resume(struct device *dev)
1759{ 1744{
1760 /* TODO */ 1745 struct fb_info *fbi;
1746 int i;
1747
1748 /* Kickstart the panel */
1749 au1200_setpanel(panel);
1750
1751 for (i = 0; i < device_count; i++) {
1752 fbi = _au1200fb_infos[i];
1753 au1200fb_fb_set_par(fbi);
1754 }
1755
1761 return 0; 1756 return 0;
1762} 1757}
1758
1759static const struct dev_pm_ops au1200fb_pmops = {
1760 .suspend = au1200fb_drv_suspend,
1761 .resume = au1200fb_drv_resume,
1762 .freeze = au1200fb_drv_suspend,
1763 .thaw = au1200fb_drv_resume,
1764};
1765
1766#define AU1200FB_PMOPS (&au1200fb_pmops)
1767
1768#else
1769#define AU1200FB_PMOPS NULL
1763#endif /* CONFIG_PM */ 1770#endif /* CONFIG_PM */
1764 1771
1765static struct platform_driver au1200fb_driver = { 1772static struct platform_driver au1200fb_driver = {
1766 .driver = { 1773 .driver = {
1767 .name = "au1200-lcd", 1774 .name = "au1200-lcd",
1768 .owner = THIS_MODULE, 1775 .owner = THIS_MODULE,
1776 .pm = AU1200FB_PMOPS,
1769 }, 1777 },
1770 .probe = au1200fb_drv_probe, 1778 .probe = au1200fb_drv_probe,
1771 .remove = au1200fb_drv_remove, 1779 .remove = __devexit_p(au1200fb_drv_remove),
1772#ifdef CONFIG_PM
1773 .suspend = au1200fb_drv_suspend,
1774 .resume = au1200fb_drv_resume,
1775#endif
1776}; 1780};
1777 1781
1778/*-------------------------------------------------------------------------*/ 1782/*-------------------------------------------------------------------------*/
1779 1783
1780/* Kernel driver */ 1784/* Kernel driver */
1781 1785
1782static void au1200fb_setup(void) 1786static int au1200fb_setup(void)
1783{ 1787{
1784 char* options = NULL; 1788 char *options = NULL;
1785 char* this_opt; 1789 char *this_opt, *endptr;
1786 int num_panels = ARRAY_SIZE(known_lcd_panels); 1790 int num_panels = ARRAY_SIZE(known_lcd_panels);
1787 int panel_idx = -1; 1791 int panel_idx = -1;
1788 1792
@@ -1827,70 +1831,42 @@ static void au1200fb_setup(void)
1827 nohwcursor = 1; 1831 nohwcursor = 1;
1828 } 1832 }
1829 1833
1830 /* Unsupported option */ 1834 else if (strncmp(this_opt, "devices:", 8) == 0) {
1831 else { 1835 this_opt += 8;
1832 print_warn("Unsupported option \"%s\"", this_opt); 1836 device_count = simple_strtol(this_opt,
1837 &endptr, 0);
1838 if ((device_count < 0) ||
1839 (device_count > MAX_DEVICE_COUNT))
1840 device_count = MAX_DEVICE_COUNT;
1833 } 1841 }
1834 }
1835 }
1836}
1837 1842
1838#ifdef CONFIG_PM 1843 else if (strncmp(this_opt, "wincfg:", 7) == 0) {
1839static int au1200fb_pm_callback(au1xxx_power_dev_t *dev, 1844 this_opt += 7;
1840 au1xxx_request_t request, void *data) { 1845 window_index = simple_strtol(this_opt,
1841 int retval = -1; 1846 &endptr, 0);
1842 unsigned int d = 0; 1847 if ((window_index < 0) ||
1843 unsigned int brightness = 0; 1848 (window_index >= ARRAY_SIZE(windows)))
1844 1849 window_index = DEFAULT_WINDOW_INDEX;
1845 if (request == AU1XXX_PM_SLEEP) {
1846 board_au1200fb_panel_shutdown();
1847 }
1848 else if (request == AU1XXX_PM_WAKEUP) {
1849 if(dev->prev_state == SLEEP_STATE)
1850 {
1851 int plane;
1852 au1200_setpanel(panel);
1853 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
1854 struct au1200fb_device *fbdev;
1855 fbdev = &_au1200fb_devices[plane];
1856 au1200fb_fb_set_par(&fbdev->fb_info);
1857 } 1850 }
1858 }
1859 1851
1860 d = *((unsigned int*)data); 1852 else if (strncmp(this_opt, "off", 3) == 0)
1861 if(d <=10) brightness = 26; 1853 return 1;
1862 else if(d<=20) brightness = 51; 1854 /* Unsupported option */
1863 else if(d<=30) brightness = 77; 1855 else {
1864 else if(d<=40) brightness = 102; 1856 print_warn("Unsupported option \"%s\"", this_opt);
1865 else if(d<=50) brightness = 128; 1857 }
1866 else if(d<=60) brightness = 153;
1867 else if(d<=70) brightness = 179;
1868 else if(d<=80) brightness = 204;
1869 else if(d<=90) brightness = 230;
1870 else brightness = 255;
1871 set_brightness(brightness);
1872 } else if (request == AU1XXX_PM_GETSTATUS) {
1873 return dev->cur_state;
1874 } else if (request == AU1XXX_PM_ACCESS) {
1875 if (dev->cur_state != SLEEP_STATE)
1876 return retval;
1877 else {
1878 au1200_setpanel(panel);
1879 } 1858 }
1880 } else if (request == AU1XXX_PM_IDLE) {
1881 } else if (request == AU1XXX_PM_CLEANUP) {
1882 } 1859 }
1883 1860 return 0;
1884 return retval;
1885} 1861}
1886#endif
1887 1862
1888static int __init au1200fb_init(void) 1863static int __init au1200fb_init(void)
1889{ 1864{
1890 print_info("" DRIVER_DESC ""); 1865 print_info("" DRIVER_DESC "");
1891 1866
1892 /* Setup driver with options */ 1867 /* Setup driver with options */
1893 au1200fb_setup(); 1868 if (au1200fb_setup())
1869 return -ENODEV;
1894 1870
1895 /* Point to the panel selected */ 1871 /* Point to the panel selected */
1896 panel = &known_lcd_panels[panel_index]; 1872 panel = &known_lcd_panels[panel_index];
@@ -1899,17 +1875,6 @@ static int __init au1200fb_init(void)
1899 printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name); 1875 printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
1900 printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name); 1876 printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
1901 1877
1902 /* Kickstart the panel, the framebuffers/windows come soon enough */
1903 au1200_setpanel(panel);
1904
1905 #ifdef CONFIG_PM
1906 LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
1907 if ( LCD_pm_dev == NULL)
1908 printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
1909 else
1910 printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
1911 #endif
1912
1913 return platform_driver_register(&au1200fb_driver); 1878 return platform_driver_register(&au1200fb_driver);
1914} 1879}
1915 1880
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 183b6f639852..66bc74d9ce2a 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -7,7 +7,6 @@
7 */ 7 */
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/version.h>
11#include <linux/init.h> 10#include <linux/init.h>
12#include <linux/errno.h> 11#include <linux/errno.h>
13#include <linux/pm.h> 12#include <linux/pm.h>
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 05a8832bb3eb..383c4c364b5f 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -7,7 +7,6 @@
7 */ 7 */
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/version.h>
11#include <linux/init.h> 10#include <linux/init.h>
12#include <linux/errno.h> 11#include <linux/errno.h>
13#include <linux/pm.h> 12#include <linux/pm.h>
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c
index caaa27d4a46a..cb09aa1fa138 100644
--- a/drivers/video/carminefb.c
+++ b/drivers/video/carminefb.c
@@ -32,11 +32,11 @@
32#define CARMINEFB_DEFAULT_VIDEO_MODE 1 32#define CARMINEFB_DEFAULT_VIDEO_MODE 1
33 33
34static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE; 34static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
35module_param(fb_mode, uint, 444); 35module_param(fb_mode, uint, 0444);
36MODULE_PARM_DESC(fb_mode, "Initial video mode as integer."); 36MODULE_PARM_DESC(fb_mode, "Initial video mode as integer.");
37 37
38static char *fb_mode_str; 38static char *fb_mode_str;
39module_param(fb_mode_str, charp, 444); 39module_param(fb_mode_str, charp, 0444);
40MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters."); 40MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
41 41
42/* 42/*
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
46 * 0b010 Display 1 46 * 0b010 Display 1
47 */ 47 */
48static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1; 48static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1;
49module_param(fb_displays, int, 444); 49module_param(fb_displays, int, 0444);
50MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used"); 50MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used");
51 51
52struct carmine_hw { 52struct carmine_hw {
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 9075bea55879..7b2c40abae15 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -550,7 +550,7 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
550 550
551 551
552/* 552/*
553 * Parse user speficied options (`video=controlfb:') 553 * Parse user specified options (`video=controlfb:')
554 */ 554 */
555static void __init control_setup(char *options) 555static void __init control_setup(char *options)
556{ 556{
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 8d4e4ebd9977..217c05f74541 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -35,6 +35,9 @@
35 35
36#define DRIVER_NAME "da8xx_lcdc" 36#define DRIVER_NAME "da8xx_lcdc"
37 37
38#define LCD_VERSION_1 1
39#define LCD_VERSION_2 2
40
38/* LCD Status Register */ 41/* LCD Status Register */
39#define LCD_END_OF_FRAME1 BIT(9) 42#define LCD_END_OF_FRAME1 BIT(9)
40#define LCD_END_OF_FRAME0 BIT(8) 43#define LCD_END_OF_FRAME0 BIT(8)
@@ -49,7 +52,9 @@
49#define LCD_DMA_BURST_4 0x2 52#define LCD_DMA_BURST_4 0x2
50#define LCD_DMA_BURST_8 0x3 53#define LCD_DMA_BURST_8 0x3
51#define LCD_DMA_BURST_16 0x4 54#define LCD_DMA_BURST_16 0x4
52#define LCD_END_OF_FRAME_INT_ENA BIT(2) 55#define LCD_V1_END_OF_FRAME_INT_ENA BIT(2)
56#define LCD_V2_END_OF_FRAME0_INT_ENA BIT(8)
57#define LCD_V2_END_OF_FRAME1_INT_ENA BIT(9)
53#define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0) 58#define LCD_DUAL_FRAME_BUFFER_ENABLE BIT(0)
54 59
55/* LCD Control Register */ 60/* LCD Control Register */
@@ -65,12 +70,18 @@
65#define LCD_MONO_8BIT_MODE BIT(9) 70#define LCD_MONO_8BIT_MODE BIT(9)
66#define LCD_RASTER_ORDER BIT(8) 71#define LCD_RASTER_ORDER BIT(8)
67#define LCD_TFT_MODE BIT(7) 72#define LCD_TFT_MODE BIT(7)
68#define LCD_UNDERFLOW_INT_ENA BIT(6) 73#define LCD_V1_UNDERFLOW_INT_ENA BIT(6)
69#define LCD_PL_ENABLE BIT(4) 74#define LCD_V2_UNDERFLOW_INT_ENA BIT(5)
75#define LCD_V1_PL_INT_ENA BIT(4)
76#define LCD_V2_PL_INT_ENA BIT(6)
70#define LCD_MONOCHROME_MODE BIT(1) 77#define LCD_MONOCHROME_MODE BIT(1)
71#define LCD_RASTER_ENABLE BIT(0) 78#define LCD_RASTER_ENABLE BIT(0)
72#define LCD_TFT_ALT_ENABLE BIT(23) 79#define LCD_TFT_ALT_ENABLE BIT(23)
73#define LCD_STN_565_ENABLE BIT(24) 80#define LCD_STN_565_ENABLE BIT(24)
81#define LCD_V2_DMA_CLK_EN BIT(2)
82#define LCD_V2_LIDD_CLK_EN BIT(1)
83#define LCD_V2_CORE_CLK_EN BIT(0)
84#define LCD_V2_LPP_B10 26
74 85
75/* LCD Raster Timing 2 Register */ 86/* LCD Raster Timing 2 Register */
76#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16) 87#define LCD_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16)
@@ -82,6 +93,7 @@
82#define LCD_INVERT_FRAME_CLOCK BIT(20) 93#define LCD_INVERT_FRAME_CLOCK BIT(20)
83 94
84/* LCD Block */ 95/* LCD Block */
96#define LCD_PID_REG 0x0
85#define LCD_CTRL_REG 0x4 97#define LCD_CTRL_REG 0x4
86#define LCD_STAT_REG 0x8 98#define LCD_STAT_REG 0x8
87#define LCD_RASTER_CTRL_REG 0x28 99#define LCD_RASTER_CTRL_REG 0x28
@@ -94,6 +106,17 @@
94#define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C 106#define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C
95#define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50 107#define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50
96 108
109/* Interrupt Registers available only in Version 2 */
110#define LCD_RAW_STAT_REG 0x58
111#define LCD_MASKED_STAT_REG 0x5c
112#define LCD_INT_ENABLE_SET_REG 0x60
113#define LCD_INT_ENABLE_CLR_REG 0x64
114#define LCD_END_OF_INT_IND_REG 0x68
115
116/* Clock registers available only on Version 2 */
117#define LCD_CLK_ENABLE_REG 0x6c
118#define LCD_CLK_RESET_REG 0x70
119
97#define LCD_NUM_BUFFERS 2 120#define LCD_NUM_BUFFERS 2
98 121
99#define WSI_TIMEOUT 50 122#define WSI_TIMEOUT 50
@@ -105,6 +128,8 @@
105 128
106static resource_size_t da8xx_fb_reg_base; 129static resource_size_t da8xx_fb_reg_base;
107static struct resource *lcdc_regs; 130static struct resource *lcdc_regs;
131static unsigned int lcd_revision;
132static irq_handler_t lcdc_irq_handler;
108 133
109static inline unsigned int lcdc_read(unsigned int addr) 134static inline unsigned int lcdc_read(unsigned int addr)
110{ 135{
@@ -240,6 +265,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
240 u32 end; 265 u32 end;
241 u32 reg_ras; 266 u32 reg_ras;
242 u32 reg_dma; 267 u32 reg_dma;
268 u32 reg_int;
243 269
244 /* init reg to clear PLM (loading mode) fields */ 270 /* init reg to clear PLM (loading mode) fields */
245 reg_ras = lcdc_read(LCD_RASTER_CTRL_REG); 271 reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
@@ -252,7 +278,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
252 end = par->dma_end; 278 end = par->dma_end;
253 279
254 reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY); 280 reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY);
255 reg_dma |= LCD_END_OF_FRAME_INT_ENA; 281 if (lcd_revision == LCD_VERSION_1) {
282 reg_dma |= LCD_V1_END_OF_FRAME_INT_ENA;
283 } else {
284 reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
285 LCD_V2_END_OF_FRAME0_INT_ENA |
286 LCD_V2_END_OF_FRAME1_INT_ENA;
287 lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
288 }
256 reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; 289 reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
257 290
258 lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); 291 lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
@@ -264,7 +297,14 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
264 end = start + par->palette_sz - 1; 297 end = start + par->palette_sz - 1;
265 298
266 reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY); 299 reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY);
267 reg_ras |= LCD_PL_ENABLE; 300
301 if (lcd_revision == LCD_VERSION_1) {
302 reg_ras |= LCD_V1_PL_INT_ENA;
303 } else {
304 reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
305 LCD_V2_PL_INT_ENA;
306 lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
307 }
268 308
269 lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); 309 lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
270 lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); 310 lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
@@ -348,6 +388,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width,
348static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) 388static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
349{ 389{
350 u32 reg; 390 u32 reg;
391 u32 reg_int;
351 392
352 reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE | 393 reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(LCD_TFT_MODE |
353 LCD_MONO_8BIT_MODE | 394 LCD_MONO_8BIT_MODE |
@@ -375,7 +416,13 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg)
375 } 416 }
376 417
377 /* enable additional interrupts here */ 418 /* enable additional interrupts here */
378 reg |= LCD_UNDERFLOW_INT_ENA; 419 if (lcd_revision == LCD_VERSION_1) {
420 reg |= LCD_V1_UNDERFLOW_INT_ENA;
421 } else {
422 reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
423 LCD_V2_UNDERFLOW_INT_ENA;
424 lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
425 }
379 426
380 lcdc_write(reg, LCD_RASTER_CTRL_REG); 427 lcdc_write(reg, LCD_RASTER_CTRL_REG);
381 428
@@ -511,6 +558,9 @@ static void lcd_reset(struct da8xx_fb_par *par)
511 /* DMA has to be disabled */ 558 /* DMA has to be disabled */
512 lcdc_write(0, LCD_DMA_CTRL_REG); 559 lcdc_write(0, LCD_DMA_CTRL_REG);
513 lcdc_write(0, LCD_RASTER_CTRL_REG); 560 lcdc_write(0, LCD_RASTER_CTRL_REG);
561
562 if (lcd_revision == LCD_VERSION_2)
563 lcdc_write(0, LCD_INT_ENABLE_SET_REG);
514} 564}
515 565
516static void lcd_calc_clk_divider(struct da8xx_fb_par *par) 566static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
@@ -523,6 +573,11 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
523 /* Configure the LCD clock divisor. */ 573 /* Configure the LCD clock divisor. */
524 lcdc_write(LCD_CLK_DIVISOR(div) | 574 lcdc_write(LCD_CLK_DIVISOR(div) |
525 (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); 575 (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
576
577 if (lcd_revision == LCD_VERSION_2)
578 lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
579 LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
580
526} 581}
527 582
528static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, 583static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -583,7 +638,63 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
583 return 0; 638 return 0;
584} 639}
585 640
586static irqreturn_t lcdc_irq_handler(int irq, void *arg) 641/* IRQ handler for version 2 of LCDC */
642static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
643{
644 struct da8xx_fb_par *par = arg;
645 u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
646 u32 reg_int;
647
648 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
649 lcd_disable_raster();
650 lcdc_write(stat, LCD_MASKED_STAT_REG);
651 lcd_enable_raster();
652 } else if (stat & LCD_PL_LOAD_DONE) {
653 /*
654 * Must disable raster before changing state of any control bit.
655 * And also must be disabled before clearing the PL loading
656 * interrupt via the following write to the status register. If
657 * this is done after then one gets multiple PL done interrupts.
658 */
659 lcd_disable_raster();
660
661 lcdc_write(stat, LCD_MASKED_STAT_REG);
662
663 /* Disable PL completion inerrupt */
664 reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) |
665 (LCD_V2_PL_INT_ENA);
666 lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
667
668 /* Setup and start data loading mode */
669 lcd_blit(LOAD_DATA, par);
670 } else {
671 lcdc_write(stat, LCD_MASKED_STAT_REG);
672
673 if (stat & LCD_END_OF_FRAME0) {
674 lcdc_write(par->dma_start,
675 LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
676 lcdc_write(par->dma_end,
677 LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
678 par->vsync_flag = 1;
679 wake_up_interruptible(&par->vsync_wait);
680 }
681
682 if (stat & LCD_END_OF_FRAME1) {
683 lcdc_write(par->dma_start,
684 LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
685 lcdc_write(par->dma_end,
686 LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
687 par->vsync_flag = 1;
688 wake_up_interruptible(&par->vsync_wait);
689 }
690 }
691
692 lcdc_write(0, LCD_END_OF_INT_IND_REG);
693 return IRQ_HANDLED;
694}
695
696/* IRQ handler for version 1 LCDC */
697static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
587{ 698{
588 struct da8xx_fb_par *par = arg; 699 struct da8xx_fb_par *par = arg;
589 u32 stat = lcdc_read(LCD_STAT_REG); 700 u32 stat = lcdc_read(LCD_STAT_REG);
@@ -606,7 +717,7 @@ static irqreturn_t lcdc_irq_handler(int irq, void *arg)
606 717
607 /* Disable PL completion inerrupt */ 718 /* Disable PL completion inerrupt */
608 reg_ras = lcdc_read(LCD_RASTER_CTRL_REG); 719 reg_ras = lcdc_read(LCD_RASTER_CTRL_REG);
609 reg_ras &= ~LCD_PL_ENABLE; 720 reg_ras &= ~LCD_V1_PL_INT_ENA;
610 lcdc_write(reg_ras, LCD_RASTER_CTRL_REG); 721 lcdc_write(reg_ras, LCD_RASTER_CTRL_REG);
611 722
612 /* Setup and start data loading mode */ 723 /* Setup and start data loading mode */
@@ -945,6 +1056,22 @@ static int __devinit fb_probe(struct platform_device *device)
945 if (ret) 1056 if (ret)
946 goto err_clk_put; 1057 goto err_clk_put;
947 1058
1059 /* Determine LCD IP Version */
1060 switch (lcdc_read(LCD_PID_REG)) {
1061 case 0x4C100102:
1062 lcd_revision = LCD_VERSION_1;
1063 break;
1064 case 0x4F200800:
1065 lcd_revision = LCD_VERSION_2;
1066 break;
1067 default:
1068 dev_warn(&device->dev, "Unknown PID Reg value 0x%x, "
1069 "defaulting to LCD revision 1\n",
1070 lcdc_read(LCD_PID_REG));
1071 lcd_revision = LCD_VERSION_1;
1072 break;
1073 }
1074
948 for (i = 0, lcdc_info = known_lcd_panels; 1075 for (i = 0, lcdc_info = known_lcd_panels;
949 i < ARRAY_SIZE(known_lcd_panels); 1076 i < ARRAY_SIZE(known_lcd_panels);
950 i++, lcdc_info++) { 1077 i++, lcdc_info++) {
@@ -1085,7 +1212,13 @@ static int __devinit fb_probe(struct platform_device *device)
1085 } 1212 }
1086#endif 1213#endif
1087 1214
1088 ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par); 1215 if (lcd_revision == LCD_VERSION_1)
1216 lcdc_irq_handler = lcdc_irq_handler_rev01;
1217 else
1218 lcdc_irq_handler = lcdc_irq_handler_rev02;
1219
1220 ret = request_irq(par->irq, lcdc_irq_handler, 0,
1221 DRIVER_NAME, par);
1089 if (ret) 1222 if (ret)
1090 goto irq_freq; 1223 goto irq_freq;
1091 return 0; 1224 return 0;
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 32814e8800e0..c27e153d8882 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -223,8 +223,7 @@ void fb_deferred_io_cleanup(struct fb_info *info)
223 int i; 223 int i;
224 224
225 BUG_ON(!fbdefio); 225 BUG_ON(!fbdefio);
226 cancel_delayed_work(&info->deferred_work); 226 cancel_delayed_work_sync(&info->deferred_work);
227 flush_scheduled_work();
228 227
229 /* clear out the mapping that we setup */ 228 /* clear out the mapping that we setup */
230 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { 229 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 0acc7d65aeaa..0f1933b54596 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -31,8 +31,6 @@
31#include <linux/uaccess.h> 31#include <linux/uaccess.h>
32#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
33 33
34#include <linux/of_platform.h>
35
36#include <sysdev/fsl_soc.h> 34#include <sysdev/fsl_soc.h>
37#include <linux/fsl-diu-fb.h> 35#include <linux/fsl-diu-fb.h>
38#include "edid.h" 36#include "edid.h"
@@ -183,7 +181,8 @@ static struct fb_videomode __devinitdata fsl_diu_mode_db[] = {
183 181
184static char *fb_mode = "1024x768-32@60"; 182static char *fb_mode = "1024x768-32@60";
185static unsigned long default_bpp = 32; 183static unsigned long default_bpp = 32;
186static int monitor_port; 184static enum fsl_diu_monitor_port monitor_port;
185static char *monitor_string;
187 186
188#if defined(CONFIG_NOT_COHERENT_CACHE) 187#if defined(CONFIG_NOT_COHERENT_CACHE)
189static u8 *coherence_data; 188static u8 *coherence_data;
@@ -201,7 +200,7 @@ struct fsl_diu_data {
201 void *dummy_aoi_virt; 200 void *dummy_aoi_virt;
202 unsigned int irq; 201 unsigned int irq;
203 int fb_enabled; 202 int fb_enabled;
204 int monitor_port; 203 enum fsl_diu_monitor_port monitor_port;
205}; 204};
206 205
207struct mfb_info { 206struct mfb_info {
@@ -282,6 +281,37 @@ static struct diu_hw dr = {
282static struct diu_pool pool; 281static struct diu_pool pool;
283 282
284/** 283/**
284 * fsl_diu_name_to_port - convert a port name to a monitor port enum
285 *
286 * Takes the name of a monitor port ("dvi", "lvds", or "dlvds") and returns
287 * the enum fsl_diu_monitor_port that corresponds to that string.
288 *
289 * For compatibility with older versions, a number ("0", "1", or "2") is also
290 * supported.
291 *
292 * If the string is unknown, DVI is assumed.
293 *
294 * If the particular port is not supported by the platform, another port
295 * (platform-specific) is chosen instead.
296 */
297static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s)
298{
299 enum fsl_diu_monitor_port port = FSL_DIU_PORT_DVI;
300 unsigned long val;
301
302 if (s) {
303 if (!strict_strtoul(s, 10, &val) && (val <= 2))
304 port = (enum fsl_diu_monitor_port) val;
305 else if (strncmp(s, "lvds", 4) == 0)
306 port = FSL_DIU_PORT_LVDS;
307 else if (strncmp(s, "dlvds", 5) == 0)
308 port = FSL_DIU_PORT_DLVDS;
309 }
310
311 return diu_ops.valid_monitor_port(port);
312}
313
314/**
285 * fsl_diu_alloc - allocate memory for the DIU 315 * fsl_diu_alloc - allocate memory for the DIU
286 * @size: number of bytes to allocate 316 * @size: number of bytes to allocate
287 * @param: returned physical address of memory 317 * @param: returned physical address of memory
@@ -831,9 +861,8 @@ static int fsl_diu_set_par(struct fb_info *info)
831 } 861 }
832 } 862 }
833 863
834 ad->pix_fmt = 864 ad->pix_fmt = diu_ops.get_pixel_format(machine_data->monitor_port,
835 diu_ops.get_pixel_format(var->bits_per_pixel, 865 var->bits_per_pixel);
836 machine_data->monitor_port);
837 ad->addr = cpu_to_le32(info->fix.smem_start); 866 ad->addr = cpu_to_le32(info->fix.smem_start);
838 ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) | 867 ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) |
839 var->xres_virtual) | mfbi->g_alpha; 868 var->xres_virtual) | mfbi->g_alpha;
@@ -1439,16 +1468,12 @@ static void free_buf(struct device *dev, struct diu_addr *buf, u32 size,
1439static ssize_t store_monitor(struct device *device, 1468static ssize_t store_monitor(struct device *device,
1440 struct device_attribute *attr, const char *buf, size_t count) 1469 struct device_attribute *attr, const char *buf, size_t count)
1441{ 1470{
1442 int old_monitor_port; 1471 enum fsl_diu_monitor_port old_monitor_port;
1443 unsigned long val;
1444 struct fsl_diu_data *machine_data = 1472 struct fsl_diu_data *machine_data =
1445 container_of(attr, struct fsl_diu_data, dev_attr); 1473 container_of(attr, struct fsl_diu_data, dev_attr);
1446 1474
1447 if (strict_strtoul(buf, 10, &val))
1448 return 0;
1449
1450 old_monitor_port = machine_data->monitor_port; 1475 old_monitor_port = machine_data->monitor_port;
1451 machine_data->monitor_port = diu_ops.set_sysfs_monitor_port(val); 1476 machine_data->monitor_port = fsl_diu_name_to_port(buf);
1452 1477
1453 if (old_monitor_port != machine_data->monitor_port) { 1478 if (old_monitor_port != machine_data->monitor_port) {
1454 /* All AOIs need adjust pixel format 1479 /* All AOIs need adjust pixel format
@@ -1468,7 +1493,17 @@ static ssize_t show_monitor(struct device *device,
1468{ 1493{
1469 struct fsl_diu_data *machine_data = 1494 struct fsl_diu_data *machine_data =
1470 container_of(attr, struct fsl_diu_data, dev_attr); 1495 container_of(attr, struct fsl_diu_data, dev_attr);
1471 return diu_ops.show_monitor_port(machine_data->monitor_port, buf); 1496
1497 switch (machine_data->monitor_port) {
1498 case FSL_DIU_PORT_DVI:
1499 return sprintf(buf, "DVI\n");
1500 case FSL_DIU_PORT_LVDS:
1501 return sprintf(buf, "Single-link LVDS\n");
1502 case FSL_DIU_PORT_DLVDS:
1503 return sprintf(buf, "Dual-link LVDS\n");
1504 }
1505
1506 return 0;
1472} 1507}
1473 1508
1474static int __devinit fsl_diu_probe(struct platform_device *ofdev) 1509static int __devinit fsl_diu_probe(struct platform_device *ofdev)
@@ -1692,8 +1727,7 @@ static int __init fsl_diu_setup(char *options)
1692 if (!*opt) 1727 if (!*opt)
1693 continue; 1728 continue;
1694 if (!strncmp(opt, "monitor=", 8)) { 1729 if (!strncmp(opt, "monitor=", 8)) {
1695 if (!strict_strtoul(opt + 8, 10, &val) && (val <= 2)) 1730 monitor_port = fsl_diu_name_to_port(opt + 8);
1696 monitor_port = val;
1697 } else if (!strncmp(opt, "bpp=", 4)) { 1731 } else if (!strncmp(opt, "bpp=", 4)) {
1698 if (!strict_strtoul(opt + 4, 10, &val)) 1732 if (!strict_strtoul(opt + 4, 10, &val))
1699 default_bpp = val; 1733 default_bpp = val;
@@ -1746,6 +1780,8 @@ static int __init fsl_diu_init(void)
1746 if (fb_get_options("fslfb", &option)) 1780 if (fb_get_options("fslfb", &option))
1747 return -ENODEV; 1781 return -ENODEV;
1748 fsl_diu_setup(option); 1782 fsl_diu_setup(option);
1783#else
1784 monitor_port = fsl_diu_name_to_port(monitor_string);
1749#endif 1785#endif
1750 printk(KERN_INFO "Freescale DIU driver\n"); 1786 printk(KERN_INFO "Freescale DIU driver\n");
1751 1787
@@ -1812,7 +1848,7 @@ MODULE_PARM_DESC(mode,
1812 "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); 1848 "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
1813module_param_named(bpp, default_bpp, ulong, 0); 1849module_param_named(bpp, default_bpp, ulong, 0);
1814MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode"); 1850MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
1815module_param_named(monitor, monitor_port, int, 0); 1851module_param_named(monitor, monitor_string, charp, 0);
1816MODULE_PARM_DESC(monitor, 1852MODULE_PARM_DESC(monitor, "Specify the monitor port "
1817 "Specify the monitor port (0, 1 or 2) if supported by the platform"); 1853 "(\"dvi\", \"lvds\", or \"dlvds\") if supported by the platform");
1818 1854
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c
new file mode 100644
index 000000000000..f37e02538203
--- /dev/null
+++ b/drivers/video/grvga.c
@@ -0,0 +1,579 @@
1/*
2 * Driver for Aeroflex Gaisler SVGACTRL framebuffer device.
3 *
4 * 2011 (c) Aeroflex Gaisler AB
5 *
6 * Full documentation of the core can be found here:
7 * http://www.gaisler.com/products/grlib/grip.pdf
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * Contributors: Kristoffer Glembo <kristoffer@gaisler.com>
15 *
16 */
17
18#include <linux/platform_device.h>
19#include <linux/dma-mapping.h>
20#include <linux/of_platform.h>
21#include <linux/of_device.h>
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/string.h>
25#include <linux/delay.h>
26#include <linux/errno.h>
27#include <linux/init.h>
28#include <linux/slab.h>
29#include <linux/tty.h>
30#include <linux/mm.h>
31#include <linux/fb.h>
32#include <linux/io.h>
33
34struct grvga_regs {
35 u32 status; /* 0x00 */
36 u32 video_length; /* 0x04 */
37 u32 front_porch; /* 0x08 */
38 u32 sync_length; /* 0x0C */
39 u32 line_length; /* 0x10 */
40 u32 fb_pos; /* 0x14 */
41 u32 clk_vector[4]; /* 0x18 */
42 u32 clut; /* 0x20 */
43};
44
45struct grvga_par {
46 struct grvga_regs *regs;
47 u32 color_palette[16]; /* 16 entry pseudo palette used by fbcon in true color mode */
48 int clk_sel;
49 int fb_alloced; /* = 1 if framebuffer is allocated in main memory */
50};
51
52
53static const struct fb_videomode grvga_modedb[] = {
54 {
55 /* 640x480 @ 60 Hz */
56 NULL, 60, 640, 480, 40000, 48, 16, 39, 11, 96, 2,
57 0, FB_VMODE_NONINTERLACED
58 }, {
59 /* 800x600 @ 60 Hz */
60 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
61 0, FB_VMODE_NONINTERLACED
62 }, {
63 /* 800x600 @ 72 Hz */
64 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
65 0, FB_VMODE_NONINTERLACED
66 }, {
67 /* 1024x768 @ 60 Hz */
68 NULL, 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6,
69 0, FB_VMODE_NONINTERLACED
70 }
71 };
72
73static struct fb_fix_screeninfo grvga_fix __initdata = {
74 .id = "AG SVGACTRL",
75 .type = FB_TYPE_PACKED_PIXELS,
76 .visual = FB_VISUAL_PSEUDOCOLOR,
77 .xpanstep = 0,
78 .ypanstep = 1,
79 .ywrapstep = 0,
80 .accel = FB_ACCEL_NONE,
81};
82
83static int grvga_check_var(struct fb_var_screeninfo *var,
84 struct fb_info *info)
85{
86 struct grvga_par *par = info->par;
87 int i;
88
89 if (!var->xres)
90 var->xres = 1;
91 if (!var->yres)
92 var->yres = 1;
93 if (var->bits_per_pixel <= 8)
94 var->bits_per_pixel = 8;
95 else if (var->bits_per_pixel <= 16)
96 var->bits_per_pixel = 16;
97 else if (var->bits_per_pixel <= 24)
98 var->bits_per_pixel = 24;
99 else if (var->bits_per_pixel <= 32)
100 var->bits_per_pixel = 32;
101 else
102 return -EINVAL;
103
104 var->xres_virtual = var->xres;
105 var->yres_virtual = 2*var->yres;
106
107 if (info->fix.smem_len) {
108 if ((var->yres_virtual*var->xres_virtual*var->bits_per_pixel/8) > info->fix.smem_len)
109 return -ENOMEM;
110 }
111
112 /* Which clocks that are available can be read out in these registers */
113 for (i = 0; i <= 3 ; i++) {
114 if (var->pixclock == par->regs->clk_vector[i])
115 break;
116 }
117 if (i <= 3)
118 par->clk_sel = i;
119 else
120 return -EINVAL;
121
122 switch (info->var.bits_per_pixel) {
123 case 8:
124 var->red = (struct fb_bitfield) {0, 8, 0}; /* offset, length, msb-right */
125 var->green = (struct fb_bitfield) {0, 8, 0};
126 var->blue = (struct fb_bitfield) {0, 8, 0};
127 var->transp = (struct fb_bitfield) {0, 0, 0};
128 break;
129 case 16:
130 var->red = (struct fb_bitfield) {11, 5, 0};
131 var->green = (struct fb_bitfield) {5, 6, 0};
132 var->blue = (struct fb_bitfield) {0, 5, 0};
133 var->transp = (struct fb_bitfield) {0, 0, 0};
134 break;
135 case 24:
136 case 32:
137 var->red = (struct fb_bitfield) {16, 8, 0};
138 var->green = (struct fb_bitfield) {8, 8, 0};
139 var->blue = (struct fb_bitfield) {0, 8, 0};
140 var->transp = (struct fb_bitfield) {24, 8, 0};
141 break;
142 default:
143 return -EINVAL;
144 }
145
146 return 0;
147}
148
149static int grvga_set_par(struct fb_info *info)
150{
151
152 u32 func = 0;
153 struct grvga_par *par = info->par;
154
155 __raw_writel(((info->var.yres - 1) << 16) | (info->var.xres - 1),
156 &par->regs->video_length);
157
158 __raw_writel((info->var.lower_margin << 16) | (info->var.right_margin),
159 &par->regs->front_porch);
160
161 __raw_writel((info->var.vsync_len << 16) | (info->var.hsync_len),
162 &par->regs->sync_length);
163
164 __raw_writel(((info->var.yres + info->var.lower_margin + info->var.upper_margin + info->var.vsync_len - 1) << 16) |
165 (info->var.xres + info->var.right_margin + info->var.left_margin + info->var.hsync_len - 1),
166 &par->regs->line_length);
167
168 switch (info->var.bits_per_pixel) {
169 case 8:
170 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
171 func = 1;
172 break;
173 case 16:
174 info->fix.visual = FB_VISUAL_TRUECOLOR;
175 func = 2;
176 break;
177 case 24:
178 case 32:
179 info->fix.visual = FB_VISUAL_TRUECOLOR;
180 func = 3;
181 break;
182 default:
183 return -EINVAL;
184 }
185
186 __raw_writel((par->clk_sel << 6) | (func << 4) | 1,
187 &par->regs->status);
188
189 info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8;
190 return 0;
191}
192
193static int grvga_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info)
194{
195 struct grvga_par *par;
196 par = info->par;
197
198 if (regno >= 256) /* Size of CLUT */
199 return -EINVAL;
200
201 if (info->var.grayscale) {
202 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
203 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
204 }
205
206
207
208#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16)
209
210 red = CNVT_TOHW(red, info->var.red.length);
211 green = CNVT_TOHW(green, info->var.green.length);
212 blue = CNVT_TOHW(blue, info->var.blue.length);
213 transp = CNVT_TOHW(transp, info->var.transp.length);
214
215#undef CNVT_TOHW
216
217 /* In PSEUDOCOLOR we use the hardware CLUT */
218 if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
219 __raw_writel((regno << 24) | (red << 16) | (green << 8) | blue,
220 &par->regs->clut);
221
222 /* Truecolor uses the pseudo palette */
223 else if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
224 u32 v;
225 if (regno >= 16)
226 return -EINVAL;
227
228
229 v = (red << info->var.red.offset) |
230 (green << info->var.green.offset) |
231 (blue << info->var.blue.offset) |
232 (transp << info->var.transp.offset);
233
234 ((u32 *) (info->pseudo_palette))[regno] = v;
235 }
236 return 0;
237}
238
239static int grvga_pan_display(struct fb_var_screeninfo *var,
240 struct fb_info *info)
241{
242 struct grvga_par *par = info->par;
243 struct fb_fix_screeninfo *fix = &info->fix;
244 u32 base_addr;
245
246 if (var->xoffset != 0)
247 return -EINVAL;
248
249 base_addr = fix->smem_start + (var->yoffset * fix->line_length);
250 base_addr &= ~3UL;
251
252 /* Set framebuffer base address */
253 __raw_writel(base_addr,
254 &par->regs->fb_pos);
255
256 return 0;
257}
258
259static struct fb_ops grvga_ops = {
260 .owner = THIS_MODULE,
261 .fb_check_var = grvga_check_var,
262 .fb_set_par = grvga_set_par,
263 .fb_setcolreg = grvga_setcolreg,
264 .fb_pan_display = grvga_pan_display,
265 .fb_fillrect = cfb_fillrect,
266 .fb_copyarea = cfb_copyarea,
267 .fb_imageblit = cfb_imageblit
268};
269
270static int __init grvga_parse_custom(char *options,
271 struct fb_var_screeninfo *screendata)
272{
273 char *this_opt;
274 int count = 0;
275 if (!options || !*options)
276 return -1;
277
278 while ((this_opt = strsep(&options, " ")) != NULL) {
279 if (!*this_opt)
280 continue;
281
282 switch (count) {
283 case 0:
284 screendata->pixclock = simple_strtoul(this_opt, NULL, 0);
285 count++;
286 break;
287 case 1:
288 screendata->xres = screendata->xres_virtual = simple_strtoul(this_opt, NULL, 0);
289 count++;
290 break;
291 case 2:
292 screendata->right_margin = simple_strtoul(this_opt, NULL, 0);
293 count++;
294 break;
295 case 3:
296 screendata->hsync_len = simple_strtoul(this_opt, NULL, 0);
297 count++;
298 break;
299 case 4:
300 screendata->left_margin = simple_strtoul(this_opt, NULL, 0);
301 count++;
302 break;
303 case 5:
304 screendata->yres = screendata->yres_virtual = simple_strtoul(this_opt, NULL, 0);
305 count++;
306 break;
307 case 6:
308 screendata->lower_margin = simple_strtoul(this_opt, NULL, 0);
309 count++;
310 break;
311 case 7:
312 screendata->vsync_len = simple_strtoul(this_opt, NULL, 0);
313 count++;
314 break;
315 case 8:
316 screendata->upper_margin = simple_strtoul(this_opt, NULL, 0);
317 count++;
318 break;
319 case 9:
320 screendata->bits_per_pixel = simple_strtoul(this_opt, NULL, 0);
321 count++;
322 break;
323 default:
324 return -1;
325 }
326 }
327 screendata->activate = FB_ACTIVATE_NOW;
328 screendata->vmode = FB_VMODE_NONINTERLACED;
329 return 0;
330}
331
332static int __devinit grvga_probe(struct platform_device *dev)
333{
334 struct fb_info *info;
335 int retval = -ENOMEM;
336 unsigned long virtual_start;
337 unsigned long grvga_fix_addr = 0;
338 unsigned long physical_start = 0;
339 unsigned long grvga_mem_size = 0;
340 struct grvga_par *par = NULL;
341 char *options = NULL, *mode_opt = NULL;
342
343 info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
344 if (!info) {
345 dev_err(&dev->dev, "framebuffer_alloc failed\n");
346 return -ENOMEM;
347 }
348
349 /* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
350 *
351 * If modestring is custom:<custom mode string> we parse the string which then contains all videoparameters
352 * If address is left out, we allocate memory,
353 * if size is left out we only allocate enough to support the given mode.
354 */
355 if (fb_get_options("grvga", &options)) {
356 retval = -ENODEV;
357 goto err;
358 }
359
360 if (!options || !*options)
361 options = "640x480-8@60";
362
363 while (1) {
364 char *this_opt = strsep(&options, ",");
365
366 if (!this_opt)
367 break;
368
369 if (!strncmp(this_opt, "custom", 6)) {
370 if (grvga_parse_custom(this_opt, &info->var) < 0) {
371 dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
372 retval = -EINVAL;
373 goto err1;
374 }
375 } else if (!strncmp(this_opt, "addr", 4))
376 grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16);
377 else if (!strncmp(this_opt, "size", 4))
378 grvga_mem_size = simple_strtoul(this_opt + 5, NULL, 0);
379 else
380 mode_opt = this_opt;
381 }
382
383 par = info->par;
384 info->fbops = &grvga_ops;
385 info->fix = grvga_fix;
386 info->pseudo_palette = par->color_palette;
387 info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
388 info->fix.smem_len = grvga_mem_size;
389
390 if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) {
391 dev_err(&dev->dev, "registers already mapped\n");
392 retval = -EBUSY;
393 goto err;
394 }
395
396 par->regs = of_ioremap(&dev->resource[0], 0,
397 resource_size(&dev->resource[0]),
398 "grlib-svgactrl regs");
399
400 if (!par->regs) {
401 dev_err(&dev->dev, "failed to map registers\n");
402 retval = -ENOMEM;
403 goto err1;
404 }
405
406 retval = fb_alloc_cmap(&info->cmap, 256, 0);
407 if (retval < 0) {
408 dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n");
409 retval = -ENOMEM;
410 goto err2;
411 }
412
413 if (mode_opt) {
414 retval = fb_find_mode(&info->var, info, mode_opt,
415 grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8);
416 if (!retval || retval == 4) {
417 retval = -EINVAL;
418 goto err3;
419 }
420 }
421
422 if (!grvga_mem_size)
423 grvga_mem_size = info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel/8;
424
425 if (grvga_fix_addr) {
426 /* Got framebuffer base address from argument list */
427
428 physical_start = grvga_fix_addr;
429
430 if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) {
431 dev_err(&dev->dev, "failed to request memory region\n");
432 retval = -ENOMEM;
433 goto err3;
434 }
435
436 virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size);
437
438 if (!virtual_start) {
439 dev_err(&dev->dev, "error mapping framebuffer memory\n");
440 retval = -ENOMEM;
441 goto err4;
442 }
443 } else { /* Allocate frambuffer memory */
444
445 unsigned long page;
446
447 virtual_start = (unsigned long) __get_free_pages(GFP_DMA,
448 get_order(grvga_mem_size));
449 if (!virtual_start) {
450 dev_err(&dev->dev,
451 "unable to allocate framebuffer memory (%lu bytes)\n",
452 grvga_mem_size);
453 retval = -ENOMEM;
454 goto err3;
455 }
456
457 physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE);
458
459 /* Set page reserved so that mmap will work. This is necessary
460 * since we'll be remapping normal memory.
461 */
462 for (page = virtual_start;
463 page < PAGE_ALIGN(virtual_start + grvga_mem_size);
464 page += PAGE_SIZE) {
465 SetPageReserved(virt_to_page(page));
466 }
467
468 par->fb_alloced = 1;
469 }
470
471 memset((unsigned long *) virtual_start, 0, grvga_mem_size);
472
473 info->screen_base = (char __iomem *) virtual_start;
474 info->fix.smem_start = physical_start;
475 info->fix.smem_len = grvga_mem_size;
476
477 dev_set_drvdata(&dev->dev, info);
478
479 dev_info(&dev->dev,
480 "Aeroflex Gaisler framebuffer device (fb%d), %dx%d-%d, using %luK of video memory @ %p\n",
481 info->node, info->var.xres, info->var.yres, info->var.bits_per_pixel,
482 grvga_mem_size >> 10, info->screen_base);
483
484 retval = register_framebuffer(info);
485 if (retval < 0) {
486 dev_err(&dev->dev, "failed to register framebuffer\n");
487 goto err4;
488 }
489
490 __raw_writel(physical_start, &par->regs->fb_pos);
491 __raw_writel(__raw_readl(&par->regs->status) | 1, /* Enable framebuffer */
492 &par->regs->status);
493
494 return 0;
495
496err4:
497 dev_set_drvdata(&dev->dev, NULL);
498 if (grvga_fix_addr) {
499 release_mem_region(physical_start, grvga_mem_size);
500 iounmap((void *)virtual_start);
501 } else
502 kfree((void *)virtual_start);
503err3:
504 fb_dealloc_cmap(&info->cmap);
505err2:
506 of_iounmap(&dev->resource[0], par->regs,
507 resource_size(&dev->resource[0]));
508err1:
509 release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]));
510err:
511 framebuffer_release(info);
512
513 return retval;
514}
515
516static int __devexit grvga_remove(struct platform_device *device)
517{
518 struct fb_info *info = dev_get_drvdata(&device->dev);
519 struct grvga_par *par = info->par;
520
521 if (info) {
522 unregister_framebuffer(info);
523 fb_dealloc_cmap(&info->cmap);
524
525 of_iounmap(&device->resource[0], par->regs,
526 resource_size(&device->resource[0]));
527 release_mem_region(device->resource[0].start, resource_size(&device->resource[0]));
528
529 if (!par->fb_alloced) {
530 release_mem_region(info->fix.smem_start, info->fix.smem_len);
531 iounmap(info->screen_base);
532 } else
533 kfree((void *)info->screen_base);
534
535 framebuffer_release(info);
536 dev_set_drvdata(&device->dev, NULL);
537 }
538
539 return 0;
540}
541
542static struct of_device_id svgactrl_of_match[] = {
543 {
544 .name = "GAISLER_SVGACTRL",
545 },
546 {
547 .name = "01_063",
548 },
549 {},
550};
551MODULE_DEVICE_TABLE(of, svgactrl_of_match);
552
553static struct platform_driver grvga_driver = {
554 .driver = {
555 .name = "grlib-svgactrl",
556 .owner = THIS_MODULE,
557 .of_match_table = svgactrl_of_match,
558 },
559 .probe = grvga_probe,
560 .remove = __devexit_p(grvga_remove),
561};
562
563
564static int __init grvga_init(void)
565{
566 return platform_driver_register(&grvga_driver);
567}
568
569static void __exit grvga_exit(void)
570{
571 platform_driver_unregister(&grvga_driver);
572}
573
574module_init(grvga_init);
575module_exit(grvga_exit);
576
577MODULE_LICENSE("GPL");
578MODULE_AUTHOR("Aeroflex Gaisler");
579MODULE_DESCRIPTION("Aeroflex Gaisler framebuffer device driver");
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 243d16f09b8a..01fa660764b4 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -421,7 +421,8 @@ int mdp_probe(struct platform_device *pdev)
421 clk = clk_get(&pdev->dev, "mdp_clk"); 421 clk = clk_get(&pdev->dev, "mdp_clk");
422 if (IS_ERR(clk)) { 422 if (IS_ERR(clk)) {
423 printk(KERN_INFO "mdp: failed to get mdp clk"); 423 printk(KERN_INFO "mdp: failed to get mdp clk");
424 return PTR_ERR(clk); 424 ret = PTR_ERR(clk);
425 goto error_get_clk;
425 } 426 }
426 427
427 ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp); 428 ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
@@ -495,6 +496,7 @@ int mdp_probe(struct platform_device *pdev)
495error_device_register: 496error_device_register:
496 free_irq(mdp->irq, mdp); 497 free_irq(mdp->irq, mdp);
497error_request_irq: 498error_request_irq:
499error_get_clk:
498 iounmap(mdp->base); 500 iounmap(mdp->base);
499error_get_irq: 501error_get_irq:
500error_ioremap: 502error_ioremap:
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index f27ae16ead2e..66949232f85c 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -490,7 +490,7 @@ static int platinum_var_to_par(struct fb_var_screeninfo *var,
490 490
491 491
492/* 492/*
493 * Parse user speficied options (`video=platinumfb:') 493 * Parse user specified options (`video=platinumfb:')
494 */ 494 */
495static int __init platinumfb_setup(char *options) 495static int __init platinumfb_setup(char *options)
496{ 496{
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index f4f8ce802d02..dc7bfa91e57a 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -1773,7 +1773,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
1773 1773
1774#ifndef MODULE 1774#ifndef MODULE
1775/** 1775/**
1776 * Parse user speficied options. 1776 * Parse user specified options.
1777 * 1777 *
1778 * This is, comma-separated options following `video=pm2fb:'. 1778 * This is, comma-separated options following `video=pm2fb:'.
1779 */ 1779 */
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 8221b5b42da9..6632ee5ecb7e 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -1525,7 +1525,7 @@ static int __init pm3fb_setup(char *options)
1525{ 1525{
1526 char *this_opt; 1526 char *this_opt;
1527 1527
1528 /* Parse user speficied options (`video=pm3fb:') */ 1528 /* Parse user specified options (`video=pm3fb:') */
1529 if (!options || !*options) 1529 if (!options || !*options)
1530 return 0; 1530 return 0;
1531 1531
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c
index 0283c7021090..d8de5577d3cf 100644
--- a/drivers/video/pxa3xx-gcu.c
+++ b/drivers/video/pxa3xx-gcu.c
@@ -31,8 +31,6 @@
31 */ 31 */
32 32
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/version.h>
35
36#include <linux/platform_device.h> 34#include <linux/platform_device.h>
37#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
38#include <linux/miscdevice.h> 36#include <linux/miscdevice.h>
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 0aa13761de6e..798144a4eedd 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -767,7 +767,6 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
767static int s3c2410fb_cpufreq_transition(struct notifier_block *nb, 767static int s3c2410fb_cpufreq_transition(struct notifier_block *nb,
768 unsigned long val, void *data) 768 unsigned long val, void *data)
769{ 769{
770 struct cpufreq_freqs *freqs = data;
771 struct s3c2410fb_info *info; 770 struct s3c2410fb_info *info;
772 struct fb_info *fbinfo; 771 struct fb_info *fbinfo;
773 long delta_f; 772 long delta_f;
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 0f9af1aa5077..946a949f4c7d 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -1505,7 +1505,7 @@ static struct pci_driver s3fb_pci_driver = {
1505 .resume = s3_pci_resume, 1505 .resume = s3_pci_resume,
1506}; 1506};
1507 1507
1508/* Parse user speficied options */ 1508/* Parse user specified options */
1509 1509
1510#ifndef MODULE 1510#ifndef MODULE
1511static int __init s3fb_setup(char *options) 1511static int __init s3fb_setup(char *options)
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 89158bc71da2..30f7a815a62b 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -989,7 +989,7 @@ static struct platform_device *xxxfb_device;
989 */ 989 */
990int __init xxxfb_setup(char *options) 990int __init xxxfb_setup(char *options)
991{ 991{
992 /* Parse user speficied options (`video=xxxfb:') */ 992 /* Parse user specified options (`video=xxxfb:') */
993} 993}
994#endif /* MODULE */ 994#endif /* MODULE */
995 995
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 101846c2084a..3473e75ce785 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -48,13 +48,22 @@ static const u32 udlfb_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
48 FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR; 48 FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR;
49 49
50/* 50/*
51 * There are many DisplayLink-based products, all with unique PIDs. We are able 51 * There are many DisplayLink-based graphics products, all with unique PIDs.
52 * to support all volume ones (circa 2009) with a single driver, so we match 52 * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff)
53 * globally on VID. TODO: Probe() needs to detect when we might be running 53 * We also require a match on SubClass (0x00) and Protocol (0x00),
54 * "future" chips, and bail on those, so a compatible driver can match. 54 * which is compatible with all known USB 2.0 era graphics chips and firmware,
55 * but allows DisplayLink to increment those for any future incompatible chips
55 */ 56 */
56static struct usb_device_id id_table[] = { 57static struct usb_device_id id_table[] = {
57 {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, 58 {.idVendor = 0x17e9,
59 .bInterfaceClass = 0xff,
60 .bInterfaceSubClass = 0x00,
61 .bInterfaceProtocol = 0x00,
62 .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
63 USB_DEVICE_ID_MATCH_INT_CLASS |
64 USB_DEVICE_ID_MATCH_INT_SUBCLASS |
65 USB_DEVICE_ID_MATCH_INT_PROTOCOL,
66 },
58 {}, 67 {},
59}; 68};
60MODULE_DEVICE_TABLE(usb, id_table); 69MODULE_DEVICE_TABLE(usb, id_table);
@@ -1613,7 +1622,7 @@ static int dlfb_usb_probe(struct usb_interface *interface,
1613 /* We don't register a new USB class. Our client interface is fbdev */ 1622 /* We don't register a new USB class. Our client interface is fbdev */
1614 1623
1615 /* allocates framebuffer driver structure, not framebuffer memory */ 1624 /* allocates framebuffer driver structure, not framebuffer memory */
1616 info = framebuffer_alloc(0, &usbdev->dev); 1625 info = framebuffer_alloc(0, &interface->dev);
1617 if (!info) { 1626 if (!info) {
1618 retval = -ENOMEM; 1627 retval = -ENOMEM;
1619 pr_err("framebuffer_alloc failed\n"); 1628 pr_err("framebuffer_alloc failed\n");
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 6b52bf65f0b5..3f5a041601da 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -555,7 +555,7 @@ static int __init valkyrie_init_info(struct fb_info *info,
555 555
556 556
557/* 557/*
558 * Parse user speficied options (`video=valkyriefb:') 558 * Parse user specified options (`video=valkyriefb:')
559 */ 559 */
560int __init valkyriefb_setup(char *options) 560int __init valkyriefb_setup(char *options)
561{ 561{
diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/via/via_modesetting.h
index ae35cfdeb37c..013884543e91 100644
--- a/drivers/video/via/via_modesetting.h
+++ b/drivers/video/via/via_modesetting.h
@@ -28,6 +28,11 @@
28 28
29#include <linux/types.h> 29#include <linux/types.h>
30 30
31
32#define VIA_PITCH_SIZE (1<<3)
33#define VIA_PITCH_MAX 0x3FF8
34
35
31void via_set_primary_address(u32 addr); 36void via_set_primary_address(u32 addr);
32void via_set_secondary_address(u32 addr); 37void via_set_secondary_address(u32 addr);
33void via_set_primary_pitch(u32 pitch); 38void via_set_primary_pitch(u32 pitch);
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 53aa4430d86e..09fa57cea844 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -151,7 +151,8 @@ static void viafb_update_fix(struct fb_info *info)
151 151
152 info->fix.visual = 152 info->fix.visual =
153 bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 153 bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
154 info->fix.line_length = (info->var.xres_virtual * bpp / 8 + 7) & ~7; 154 info->fix.line_length = ALIGN(info->var.xres_virtual * bpp / 8,
155 VIA_PITCH_SIZE);
155} 156}
156 157
157static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, 158static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
@@ -238,8 +239,12 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
238 depth = 24; 239 depth = 24;
239 240
240 viafb_fill_var_color_info(var, depth); 241 viafb_fill_var_color_info(var, depth);
241 line = (var->xres_virtual * var->bits_per_pixel / 8 + 7) & ~7; 242 if (var->xres_virtual < var->xres)
242 if (line * var->yres_virtual > ppar->memsize) 243 var->xres_virtual = var->xres;
244
245 line = ALIGN(var->xres_virtual * var->bits_per_pixel / 8,
246 VIA_PITCH_SIZE);
247 if (line > VIA_PITCH_MAX || line * var->yres_virtual > ppar->memsize)
243 return -EINVAL; 248 return -EINVAL;
244 249
245 /* Based on var passed in to calculate the refresh, 250 /* Based on var passed in to calculate the refresh,
@@ -348,8 +353,9 @@ static int viafb_pan_display(struct fb_var_screeninfo *var,
348 struct fb_info *info) 353 struct fb_info *info)
349{ 354{
350 struct viafb_par *viapar = info->par; 355 struct viafb_par *viapar = info->par;
351 u32 vram_addr = (var->yoffset * var->xres_virtual + var->xoffset) 356 u32 vram_addr = viapar->vram_addr
352 * (var->bits_per_pixel / 8) + viapar->vram_addr; 357 + var->yoffset * info->fix.line_length
358 + var->xoffset * info->var.bits_per_pixel / 8;
353 359
354 DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr); 360 DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr);
355 if (!viafb_dual_fb) { 361 if (!viafb_dual_fb) {
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index 77dea015ff69..fcb6cd90f64d 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -23,7 +23,6 @@
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/version.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/string.h> 27#include <linux/string.h>
29#include <linux/mm.h> 28#include <linux/mm.h>