aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:45:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:45:12 -0400
commitd4fdc32517efaab0493c134d5cc070c252d51275 (patch)
tree7b70d93a65fa1b74f84af835cd941c3f2c55019a /drivers/video
parent9a51cf28a3377689edfe190b9590da7d46e8f3fb (diff)
parenta0239073fd75489d25575cf3aaf71ab55b416020 (diff)
Merge tag 'fbdev-updates-for-3.6' of git://github.com/schandinat/linux-2.6
Pull fbdev updates from Florian Tobias Schandinat: - large updates for OMAP - support for LCD3 overlay manager (omap5) - omapdss output cleanup - removal of passive matrix LCD support as there are no drivers for such panels for DSS or DSS2 and nobody complained (cleanup) - large updates for SH Mobile - overlay support - separating MERAM (cache) from framebuffer driver - some updates for Exynos and da8xx-fb - various other small patches * tag 'fbdev-updates-for-3.6' of git://github.com/schandinat/linux-2.6: (78 commits) da8xx-fb: fix compile issue due to missing include fbdev: Make pixel_to_pat() failure mode more friendly da8xx-fb: do not turn ON LCD backlight unless LCDC is enabled fbdev: sh_mobile_lcdc: Fix vertical panning step video: exynos mipi dsi: Fix mipi dsi regulators handling issue video: da8xx-fb: do clock reset of revision 2 LCDC before enabling arm: da850: configure LCDC fifo threshold video: da8xx-fb: configure FIFO threshold to reduce underflow errors video: da8xx-fb: fix flicker due to 1 frame delay in updated frame video: da8xx-fb rev2: fix disabling of palette completion interrupt da8xx-fb: add missing FB_BLANK operations video: exynos_dp: use usleep_range instead of delay video: exynos_dp: check the only INTERLANE_ALIGN_DONE bit during Link Training fb: epson1355fb: Fix section mismatch video: exynos_dp: fix wrong DPCD address during Link Training video/smscufx: fix line counting in fb_write aty128fb: Fix coding style issues fbdev: sh_mobile_lcdc: Fix pan offset computation in YUV mode fbdev: sh_mobile_lcdc: Fix overlay registers update during pan operation fbdev: sh_mobile_lcdc: Support horizontal panning ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/aty/aty128fb.c180
-rw-r--r--drivers/video/da8xx-fb.c78
-rw-r--r--drivers/video/epson1355fb.c8
-rw-r--r--drivers/video/exynos/exynos_dp_core.c23
-rw-r--r--drivers/video/exynos/exynos_dp_core.h4
-rw-r--r--drivers/video/exynos/exynos_dp_reg.c4
-rw-r--r--drivers/video/exynos/exynos_mipi_dsi.c2
-rw-r--r--drivers/video/exynos/s6e8ax0.h21
-rw-r--r--drivers/video/fb_draw.h7
-rw-r--r--drivers/video/grvga.c47
-rw-r--r--drivers/video/mx3fb.c55
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c10
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c179
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c8
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c1
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c9
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.c9
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c9
-rw-r--r--drivers/video/omap2/displays/panel-taal.c1
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c7
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c8
-rw-r--r--drivers/video/omap2/dss/Kconfig4
-rw-r--r--drivers/video/omap2/dss/apply.c91
-rw-r--r--drivers/video/omap2/dss/dispc.c494
-rw-r--r--drivers/video/omap2/dss/dispc.h28
-rw-r--r--drivers/video/omap2/dss/display.c40
-rw-r--r--drivers/video/omap2/dss/dpi.c64
-rw-r--r--drivers/video/omap2/dss/dsi.c152
-rw-r--r--drivers/video/omap2/dss/dss.c19
-rw-r--r--drivers/video/omap2/dss/dss.h54
-rw-r--r--drivers/video/omap2/dss/dss_features.h5
-rw-r--r--drivers/video/omap2/dss/hdmi.c246
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c9
-rw-r--r--drivers/video/omap2/dss/manager.c51
-rw-r--r--drivers/video/omap2/dss/overlay.c33
-rw-r--r--drivers/video/omap2/dss/rfbi.c40
-rw-r--r--drivers/video/omap2/dss/sdi.c42
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h21
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c26
-rw-r--r--drivers/video/omap2/dss/venc.c8
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c51
-rw-r--r--drivers/video/s3fb.c31
-rw-r--r--drivers/video/sh_mipi_dsi.c7
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c1117
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h5
-rw-r--r--drivers/video/sh_mobile_meram.c235
-rw-r--r--drivers/video/smscufx.c2
-rw-r--r--drivers/video/w100fb.c12
48 files changed, 2468 insertions, 1089 deletions
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index b0b2ac335347..747442d2c0f6 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -90,7 +90,8 @@
90#undef DEBUG 90#undef DEBUG
91 91
92#ifdef DEBUG 92#ifdef DEBUG
93#define DBG(fmt, args...) printk(KERN_DEBUG "aty128fb: %s " fmt, __func__, ##args); 93#define DBG(fmt, args...) \
94 printk(KERN_DEBUG "aty128fb: %s " fmt, __func__, ##args);
94#else 95#else
95#define DBG(fmt, args...) 96#define DBG(fmt, args...)
96#endif 97#endif
@@ -449,8 +450,9 @@ static int aty128_decode_var(struct fb_var_screeninfo *var,
449 struct aty128fb_par *par); 450 struct aty128fb_par *par);
450#if 0 451#if 0
451static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, 452static void __devinit aty128_get_pllinfo(struct aty128fb_par *par,
452 void __iomem *bios); 453 void __iomem *bios);
453static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); 454static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev,
455 const struct aty128fb_par *par);
454#endif 456#endif
455static void aty128_timings(struct aty128fb_par *par); 457static void aty128_timings(struct aty128fb_par *par);
456static void aty128_init_engine(struct aty128fb_par *par); 458static void aty128_init_engine(struct aty128fb_par *par);
@@ -779,7 +781,8 @@ static u32 depth_to_dst(u32 depth)
779 781
780 782
781#ifndef __sparc__ 783#ifndef __sparc__
782static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) 784static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par,
785 struct pci_dev *dev)
783{ 786{
784 u16 dptr; 787 u16 dptr;
785 u8 rom_type; 788 u8 rom_type;
@@ -811,13 +814,14 @@ static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, s
811 /* Look for the PCI data to check the ROM type */ 814 /* Look for the PCI data to check the ROM type */
812 dptr = BIOS_IN16(0x18); 815 dptr = BIOS_IN16(0x18);
813 816
814 /* Check the PCI data signature. If it's wrong, we still assume a normal x86 ROM 817 /* Check the PCI data signature. If it's wrong, we still assume a normal
815 * for now, until I've verified this works everywhere. The goal here is more 818 * x86 ROM for now, until I've verified this works everywhere.
816 * to phase out Open Firmware images. 819 * The goal here is more to phase out Open Firmware images.
817 * 820 *
818 * Currently, we only look at the first PCI data, we could iteratre and deal with 821 * Currently, we only look at the first PCI data, we could iteratre and
819 * them all, and we should use fb_bios_start relative to start of image and not 822 * deal with them all, and we should use fb_bios_start relative to start
820 * relative start of ROM, but so far, I never found a dual-image ATI card 823 * of image and not relative start of ROM, but so far, I never found a
824 * dual-image ATI card.
821 * 825 *
822 * typedef struct { 826 * typedef struct {
823 * u32 signature; + 0x00 827 * u32 signature; + 0x00
@@ -852,7 +856,8 @@ static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, s
852 printk(KERN_INFO "aty128fb: Found HP PA-RISC ROM Image\n"); 856 printk(KERN_INFO "aty128fb: Found HP PA-RISC ROM Image\n");
853 goto failed; 857 goto failed;
854 default: 858 default:
855 printk(KERN_INFO "aty128fb: Found unknown type %d ROM Image\n", rom_type); 859 printk(KERN_INFO "aty128fb: Found unknown type %d ROM Image\n",
860 rom_type);
856 goto failed; 861 goto failed;
857 } 862 }
858 anyway: 863 anyway:
@@ -863,7 +868,8 @@ static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, s
863 return NULL; 868 return NULL;
864} 869}
865 870
866static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) 871static void __devinit aty128_get_pllinfo(struct aty128fb_par *par,
872 unsigned char __iomem *bios)
867{ 873{
868 unsigned int bios_hdr; 874 unsigned int bios_hdr;
869 unsigned int bios_pll; 875 unsigned int bios_pll;
@@ -1247,10 +1253,13 @@ static int aty128_crtc_to_var(const struct aty128_crtc *crtc,
1247static void aty128_set_crt_enable(struct aty128fb_par *par, int on) 1253static void aty128_set_crt_enable(struct aty128fb_par *par, int on)
1248{ 1254{
1249 if (on) { 1255 if (on) {
1250 aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) | CRT_CRTC_ON); 1256 aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) |
1251 aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) | DAC_PALETTE2_SNOOP_EN)); 1257 CRT_CRTC_ON);
1258 aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) |
1259 DAC_PALETTE2_SNOOP_EN));
1252 } else 1260 } else
1253 aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON); 1261 aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) &
1262 ~CRT_CRTC_ON);
1254} 1263}
1255 1264
1256static void aty128_set_lcd_enable(struct aty128fb_par *par, int on) 1265static void aty128_set_lcd_enable(struct aty128fb_par *par, int on)
@@ -1281,7 +1290,8 @@ static void aty128_set_lcd_enable(struct aty128fb_par *par, int on)
1281 } 1290 }
1282} 1291}
1283 1292
1284static void aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par) 1293static void aty128_set_pll(struct aty128_pll *pll,
1294 const struct aty128fb_par *par)
1285{ 1295{
1286 u32 div3; 1296 u32 div3;
1287 1297
@@ -1366,7 +1376,8 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
1366} 1376}
1367 1377
1368 1378
1369static int aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var) 1379static int aty128_pll_to_var(const struct aty128_pll *pll,
1380 struct fb_var_screeninfo *var)
1370{ 1381{
1371 var->pixclock = 100000000 / pll->vclk; 1382 var->pixclock = 100000000 / pll->vclk;
1372 1383
@@ -1512,7 +1523,8 @@ static int aty128fb_set_par(struct fb_info *info)
1512 * encode/decode the User Defined Part of the Display 1523 * encode/decode the User Defined Part of the Display
1513 */ 1524 */
1514 1525
1515static int aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par) 1526static int aty128_decode_var(struct fb_var_screeninfo *var,
1527 struct aty128fb_par *par)
1516{ 1528{
1517 int err; 1529 int err;
1518 struct aty128_crtc crtc; 1530 struct aty128_crtc crtc;
@@ -1559,7 +1571,8 @@ static int aty128_encode_var(struct fb_var_screeninfo *var,
1559} 1571}
1560 1572
1561 1573
1562static int aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 1574static int aty128fb_check_var(struct fb_var_screeninfo *var,
1575 struct fb_info *info)
1563{ 1576{
1564 struct aty128fb_par par; 1577 struct aty128fb_par par;
1565 int err; 1578 int err;
@@ -1575,7 +1588,8 @@ static int aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
1575/* 1588/*
1576 * Pan or Wrap the Display 1589 * Pan or Wrap the Display
1577 */ 1590 */
1578static int aty128fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb) 1591static int aty128fb_pan_display(struct fb_var_screeninfo *var,
1592 struct fb_info *fb)
1579{ 1593{
1580 struct aty128fb_par *par = fb->par; 1594 struct aty128fb_par *par = fb->par;
1581 u32 xoffset, yoffset; 1595 u32 xoffset, yoffset;
@@ -1594,7 +1608,8 @@ static int aty128fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *f
1594 par->crtc.xoffset = xoffset; 1608 par->crtc.xoffset = xoffset;
1595 par->crtc.yoffset = yoffset; 1609 par->crtc.yoffset = yoffset;
1596 1610
1597 offset = ((yoffset * par->crtc.vxres + xoffset)*(par->crtc.bpp >> 3)) & ~7; 1611 offset = ((yoffset * par->crtc.vxres + xoffset) * (par->crtc.bpp >> 3))
1612 & ~7;
1598 1613
1599 if (par->crtc.bpp == 24) 1614 if (par->crtc.bpp == 24)
1600 offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */ 1615 offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */
@@ -1620,11 +1635,13 @@ static void aty128_st_pal(u_int regno, u_int red, u_int green, u_int blue,
1620 * do mirroring 1635 * do mirroring
1621 */ 1636 */
1622 1637
1623 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL); 1638 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) |
1639 DAC_PALETTE_ACCESS_CNTL);
1624 aty_st_8(PALETTE_INDEX, regno); 1640 aty_st_8(PALETTE_INDEX, regno);
1625 aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue); 1641 aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
1626#endif 1642#endif
1627 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL); 1643 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) &
1644 ~DAC_PALETTE_ACCESS_CNTL);
1628 } 1645 }
1629 1646
1630 aty_st_8(PALETTE_INDEX, regno); 1647 aty_st_8(PALETTE_INDEX, regno);
@@ -1753,7 +1770,8 @@ static int aty128_bl_update_status(struct backlight_device *bd)
1753 aty_st_le32(LVDS_GEN_CNTL, reg); 1770 aty_st_le32(LVDS_GEN_CNTL, reg);
1754 } 1771 }
1755 reg &= ~LVDS_BL_MOD_LEVEL_MASK; 1772 reg &= ~LVDS_BL_MOD_LEVEL_MASK;
1756 reg |= (aty128_bl_get_level_brightness(par, level) << LVDS_BL_MOD_LEVEL_SHIFT); 1773 reg |= (aty128_bl_get_level_brightness(par, level) <<
1774 LVDS_BL_MOD_LEVEL_SHIFT);
1757#ifdef BACKLIGHT_LVDS_OFF 1775#ifdef BACKLIGHT_LVDS_OFF
1758 reg |= LVDS_ON | LVDS_EN; 1776 reg |= LVDS_ON | LVDS_EN;
1759 reg &= ~LVDS_DISPLAY_DIS; 1777 reg &= ~LVDS_DISPLAY_DIS;
@@ -1764,7 +1782,8 @@ static int aty128_bl_update_status(struct backlight_device *bd)
1764#endif 1782#endif
1765 } else { 1783 } else {
1766 reg &= ~LVDS_BL_MOD_LEVEL_MASK; 1784 reg &= ~LVDS_BL_MOD_LEVEL_MASK;
1767 reg |= (aty128_bl_get_level_brightness(par, 0) << LVDS_BL_MOD_LEVEL_SHIFT); 1785 reg |= (aty128_bl_get_level_brightness(par, 0) <<
1786 LVDS_BL_MOD_LEVEL_SHIFT);
1768#ifdef BACKLIGHT_LVDS_OFF 1787#ifdef BACKLIGHT_LVDS_OFF
1769 reg |= LVDS_DISPLAY_DIS; 1788 reg |= LVDS_DISPLAY_DIS;
1770 aty_st_le32(LVDS_GEN_CNTL, reg); 1789 aty_st_le32(LVDS_GEN_CNTL, reg);
@@ -1869,7 +1888,8 @@ static void aty128_early_resume(void *data)
1869} 1888}
1870#endif /* CONFIG_PPC_PMAC */ 1889#endif /* CONFIG_PPC_PMAC */
1871 1890
1872static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) 1891static int __devinit aty128_init(struct pci_dev *pdev,
1892 const struct pci_device_id *ent)
1873{ 1893{
1874 struct fb_info *info = pci_get_drvdata(pdev); 1894 struct fb_info *info = pci_get_drvdata(pdev);
1875 struct aty128fb_par *par = info->par; 1895 struct aty128fb_par *par = info->par;
@@ -1887,7 +1907,8 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
1887 1907
1888 /* range check to make sure */ 1908 /* range check to make sure */
1889 if (ent->driver_data < ARRAY_SIZE(r128_family)) 1909 if (ent->driver_data < ARRAY_SIZE(r128_family))
1890 strlcat(video_card, r128_family[ent->driver_data], sizeof(video_card)); 1910 strlcat(video_card, r128_family[ent->driver_data],
1911 sizeof(video_card));
1891 1912
1892 printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev); 1913 printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
1893 1914
@@ -1911,11 +1932,11 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
1911 /* Indicate sleep capability */ 1932 /* Indicate sleep capability */
1912 if (par->chip_gen == rage_M3) { 1933 if (par->chip_gen == rage_M3) {
1913 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1); 1934 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1);
1914#if 0 /* Disable the early video resume hack for now as it's causing problems, among 1935#if 0 /* Disable the early video resume hack for now as it's causing problems,
1915 * others we now rely on the PCI core restoring the config space for us, which 1936 * among others we now rely on the PCI core restoring the config space
1916 * isn't the case with that hack, and that code path causes various things to 1937 * for us, which isn't the case with that hack, and that code path causes
1917 * be called with interrupts off while they shouldn't. I'm leaving the code in 1938 * various things to be called with interrupts off while they shouldn't.
1918 * as it can be useful for debugging purposes 1939 * I'm leaving the code in as it can be useful for debugging purposes
1919 */ 1940 */
1920 pmac_set_early_video_resume(aty128_early_resume, par); 1941 pmac_set_early_video_resume(aty128_early_resume, par);
1921#endif 1942#endif
@@ -1953,11 +1974,11 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
1953 default_vmode = VMODE_1152_768_60; 1974 default_vmode = VMODE_1152_768_60;
1954 1975
1955 if (default_cmode > 16) 1976 if (default_cmode > 16)
1956 default_cmode = CMODE_32; 1977 default_cmode = CMODE_32;
1957 else if (default_cmode > 8) 1978 else if (default_cmode > 8)
1958 default_cmode = CMODE_16; 1979 default_cmode = CMODE_16;
1959 else 1980 else
1960 default_cmode = CMODE_8; 1981 default_cmode = CMODE_8;
1961 1982
1962 if (mac_vmode_to_var(default_vmode, default_cmode, &var)) 1983 if (mac_vmode_to_var(default_vmode, default_cmode, &var))
1963 var = default_var; 1984 var = default_var;
@@ -2018,7 +2039,8 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
2018 2039
2019#ifdef CONFIG_PCI 2040#ifdef CONFIG_PCI
2020/* register a card ++ajoshi */ 2041/* register a card ++ajoshi */
2021static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 2042static int __devinit aty128_probe(struct pci_dev *pdev,
2043 const struct pci_device_id *ent)
2022{ 2044{
2023 unsigned long fb_addr, reg_addr; 2045 unsigned long fb_addr, reg_addr;
2024 struct aty128fb_par *par; 2046 struct aty128fb_par *par;
@@ -2318,39 +2340,39 @@ static inline void aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
2318 u_int width, u_int height, 2340 u_int width, u_int height,
2319 struct fb_info_aty128 *par) 2341 struct fb_info_aty128 *par)
2320{ 2342{
2321 u32 save_dp_datatype, save_dp_cntl, dstval; 2343 u32 save_dp_datatype, save_dp_cntl, dstval;
2322 2344
2323 if (!width || !height) 2345 if (!width || !height)
2324 return; 2346 return;
2325 2347
2326 dstval = depth_to_dst(par->current_par.crtc.depth); 2348 dstval = depth_to_dst(par->current_par.crtc.depth);
2327 if (dstval == DST_24BPP) { 2349 if (dstval == DST_24BPP) {
2328 srcx *= 3; 2350 srcx *= 3;
2329 dstx *= 3; 2351 dstx *= 3;
2330 width *= 3; 2352 width *= 3;
2331 } else if (dstval == -EINVAL) { 2353 } else if (dstval == -EINVAL) {
2332 printk("aty128fb: invalid depth or RGBA\n"); 2354 printk("aty128fb: invalid depth or RGBA\n");
2333 return; 2355 return;
2334 } 2356 }
2335 2357
2336 wait_for_fifo(2, par); 2358 wait_for_fifo(2, par);
2337 save_dp_datatype = aty_ld_le32(DP_DATATYPE); 2359 save_dp_datatype = aty_ld_le32(DP_DATATYPE);
2338 save_dp_cntl = aty_ld_le32(DP_CNTL); 2360 save_dp_cntl = aty_ld_le32(DP_CNTL);
2339 2361
2340 wait_for_fifo(6, par); 2362 wait_for_fifo(6, par);
2341 aty_st_le32(SRC_Y_X, (srcy << 16) | srcx); 2363 aty_st_le32(SRC_Y_X, (srcy << 16) | srcx);
2342 aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT); 2364 aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT);
2343 aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); 2365 aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
2344 aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR); 2366 aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR);
2345 2367
2346 aty_st_le32(DST_Y_X, (dsty << 16) | dstx); 2368 aty_st_le32(DST_Y_X, (dsty << 16) | dstx);
2347 aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width); 2369 aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);
2348 2370
2349 par->blitter_may_be_busy = 1; 2371 par->blitter_may_be_busy = 1;
2350 2372
2351 wait_for_fifo(2, par); 2373 wait_for_fifo(2, par);
2352 aty_st_le32(DP_DATATYPE, save_dp_datatype); 2374 aty_st_le32(DP_DATATYPE, save_dp_datatype);
2353 aty_st_le32(DP_CNTL, save_dp_cntl); 2375 aty_st_le32(DP_CNTL, save_dp_cntl);
2354} 2376}
2355 2377
2356 2378
@@ -2358,17 +2380,17 @@ static inline void aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
2358 * Text mode accelerated functions 2380 * Text mode accelerated functions
2359 */ 2381 */
2360 2382
2361static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx, 2383static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy,
2362 int height, int width) 2384 int dx, int height, int width)
2363{ 2385{
2364 sx *= fontwidth(p); 2386 sx *= fontwidth(p);
2365 sy *= fontheight(p); 2387 sy *= fontheight(p);
2366 dx *= fontwidth(p); 2388 dx *= fontwidth(p);
2367 dy *= fontheight(p); 2389 dy *= fontheight(p);
2368 width *= fontwidth(p); 2390 width *= fontwidth(p);
2369 height *= fontheight(p); 2391 height *= fontheight(p);
2370 2392
2371 aty128_rectcopy(sx, sy, dx, dy, width, height, 2393 aty128_rectcopy(sx, sy, dx, dy, width, height,
2372 (struct fb_info_aty128 *)p->fb_info); 2394 (struct fb_info_aty128 *)p->fb_info);
2373} 2395}
2374#endif /* 0 */ 2396#endif /* 0 */
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 47118c75a4c0..7ae9d53f2bf1 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -30,7 +30,10 @@
30#include <linux/clk.h> 30#include <linux/clk.h>
31#include <linux/cpufreq.h> 31#include <linux/cpufreq.h>
32#include <linux/console.h> 32#include <linux/console.h>
33#include <linux/spinlock.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/delay.h>
36#include <linux/lcm.h>
34#include <video/da8xx-fb.h> 37#include <video/da8xx-fb.h>
35#include <asm/div64.h> 38#include <asm/div64.h>
36 39
@@ -160,6 +163,13 @@ struct da8xx_fb_par {
160 wait_queue_head_t vsync_wait; 163 wait_queue_head_t vsync_wait;
161 int vsync_flag; 164 int vsync_flag;
162 int vsync_timeout; 165 int vsync_timeout;
166 spinlock_t lock_for_chan_update;
167
168 /*
169 * LCDC has 2 ping pong DMA channels, channel 0
170 * and channel 1.
171 */
172 unsigned int which_dma_channel_done;
163#ifdef CONFIG_CPU_FREQ 173#ifdef CONFIG_CPU_FREQ
164 struct notifier_block freq_transition; 174 struct notifier_block freq_transition;
165 unsigned int lcd_fck_rate; 175 unsigned int lcd_fck_rate;
@@ -260,10 +270,18 @@ static inline void lcd_enable_raster(void)
260{ 270{
261 u32 reg; 271 u32 reg;
262 272
273 /* Put LCDC in reset for several cycles */
274 if (lcd_revision == LCD_VERSION_2)
275 /* Write 1 to reset LCDC */
276 lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
277 mdelay(1);
278
263 /* Bring LCDC out of reset */ 279 /* Bring LCDC out of reset */
264 if (lcd_revision == LCD_VERSION_2) 280 if (lcd_revision == LCD_VERSION_2)
265 lcdc_write(0, LCD_CLK_RESET_REG); 281 lcdc_write(0, LCD_CLK_RESET_REG);
282 mdelay(1);
266 283
284 /* Above reset sequence doesnot reset register context */
267 reg = lcdc_read(LCD_RASTER_CTRL_REG); 285 reg = lcdc_read(LCD_RASTER_CTRL_REG);
268 if (!(reg & LCD_RASTER_ENABLE)) 286 if (!(reg & LCD_RASTER_ENABLE))
269 lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); 287 lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
@@ -277,10 +295,6 @@ static inline void lcd_disable_raster(void)
277 reg = lcdc_read(LCD_RASTER_CTRL_REG); 295 reg = lcdc_read(LCD_RASTER_CTRL_REG);
278 if (reg & LCD_RASTER_ENABLE) 296 if (reg & LCD_RASTER_ENABLE)
279 lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); 297 lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
280
281 if (lcd_revision == LCD_VERSION_2)
282 /* Write 1 to reset LCDC */
283 lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
284} 298}
285 299
286static void lcd_blit(int load_mode, struct da8xx_fb_par *par) 300static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
@@ -344,8 +358,8 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
344 lcd_enable_raster(); 358 lcd_enable_raster();
345} 359}
346 360
347/* Configure the Burst Size of DMA */ 361/* Configure the Burst Size and fifo threhold of DMA */
348static int lcd_cfg_dma(int burst_size) 362static int lcd_cfg_dma(int burst_size, int fifo_th)
349{ 363{
350 u32 reg; 364 u32 reg;
351 365
@@ -369,6 +383,9 @@ static int lcd_cfg_dma(int burst_size)
369 default: 383 default:
370 return -EINVAL; 384 return -EINVAL;
371 } 385 }
386
387 reg |= (fifo_th << 8);
388
372 lcdc_write(reg, LCD_DMA_CTRL_REG); 389 lcdc_write(reg, LCD_DMA_CTRL_REG);
373 390
374 return 0; 391 return 0;
@@ -670,8 +687,8 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
670 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) & 687 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) &
671 ~LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG); 688 ~LCD_INVERT_PIXEL_CLOCK), LCD_RASTER_TIMING_2_REG);
672 689
673 /* Configure the DMA burst size. */ 690 /* Configure the DMA burst size and fifo threshold. */
674 ret = lcd_cfg_dma(cfg->dma_burst_sz); 691 ret = lcd_cfg_dma(cfg->dma_burst_sz, cfg->fifo_th);
675 if (ret < 0) 692 if (ret < 0)
676 return ret; 693 return ret;
677 694
@@ -715,7 +732,6 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
715{ 732{
716 struct da8xx_fb_par *par = arg; 733 struct da8xx_fb_par *par = arg;
717 u32 stat = lcdc_read(LCD_MASKED_STAT_REG); 734 u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
718 u32 reg_int;
719 735
720 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { 736 if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
721 lcd_disable_raster(); 737 lcd_disable_raster();
@@ -732,10 +748,8 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
732 748
733 lcdc_write(stat, LCD_MASKED_STAT_REG); 749 lcdc_write(stat, LCD_MASKED_STAT_REG);
734 750
735 /* Disable PL completion inerrupt */ 751 /* Disable PL completion interrupt */
736 reg_int = lcdc_read(LCD_INT_ENABLE_CLR_REG) | 752 lcdc_write(LCD_V2_PL_INT_ENA, LCD_INT_ENABLE_CLR_REG);
737 (LCD_V2_PL_INT_ENA);
738 lcdc_write(reg_int, LCD_INT_ENABLE_CLR_REG);
739 753
740 /* Setup and start data loading mode */ 754 /* Setup and start data loading mode */
741 lcd_blit(LOAD_DATA, par); 755 lcd_blit(LOAD_DATA, par);
@@ -743,6 +757,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
743 lcdc_write(stat, LCD_MASKED_STAT_REG); 757 lcdc_write(stat, LCD_MASKED_STAT_REG);
744 758
745 if (stat & LCD_END_OF_FRAME0) { 759 if (stat & LCD_END_OF_FRAME0) {
760 par->which_dma_channel_done = 0;
746 lcdc_write(par->dma_start, 761 lcdc_write(par->dma_start,
747 LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); 762 LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
748 lcdc_write(par->dma_end, 763 lcdc_write(par->dma_end,
@@ -752,6 +767,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
752 } 767 }
753 768
754 if (stat & LCD_END_OF_FRAME1) { 769 if (stat & LCD_END_OF_FRAME1) {
770 par->which_dma_channel_done = 1;
755 lcdc_write(par->dma_start, 771 lcdc_write(par->dma_start,
756 LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); 772 LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
757 lcdc_write(par->dma_end, 773 lcdc_write(par->dma_end,
@@ -798,6 +814,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
798 lcdc_write(stat, LCD_STAT_REG); 814 lcdc_write(stat, LCD_STAT_REG);
799 815
800 if (stat & LCD_END_OF_FRAME0) { 816 if (stat & LCD_END_OF_FRAME0) {
817 par->which_dma_channel_done = 0;
801 lcdc_write(par->dma_start, 818 lcdc_write(par->dma_start,
802 LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); 819 LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
803 lcdc_write(par->dma_end, 820 lcdc_write(par->dma_end,
@@ -807,6 +824,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
807 } 824 }
808 825
809 if (stat & LCD_END_OF_FRAME1) { 826 if (stat & LCD_END_OF_FRAME1) {
827 par->which_dma_channel_done = 1;
810 lcdc_write(par->dma_start, 828 lcdc_write(par->dma_start,
811 LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); 829 LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
812 lcdc_write(par->dma_end, 830 lcdc_write(par->dma_end,
@@ -1021,11 +1039,14 @@ static int cfb_blank(int blank, struct fb_info *info)
1021 par->blank = blank; 1039 par->blank = blank;
1022 switch (blank) { 1040 switch (blank) {
1023 case FB_BLANK_UNBLANK: 1041 case FB_BLANK_UNBLANK:
1042 lcd_enable_raster();
1043
1024 if (par->panel_power_ctrl) 1044 if (par->panel_power_ctrl)
1025 par->panel_power_ctrl(1); 1045 par->panel_power_ctrl(1);
1026
1027 lcd_enable_raster();
1028 break; 1046 break;
1047 case FB_BLANK_NORMAL:
1048 case FB_BLANK_VSYNC_SUSPEND:
1049 case FB_BLANK_HSYNC_SUSPEND:
1029 case FB_BLANK_POWERDOWN: 1050 case FB_BLANK_POWERDOWN:
1030 if (par->panel_power_ctrl) 1051 if (par->panel_power_ctrl)
1031 par->panel_power_ctrl(0); 1052 par->panel_power_ctrl(0);
@@ -1052,6 +1073,7 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var,
1052 struct fb_fix_screeninfo *fix = &fbi->fix; 1073 struct fb_fix_screeninfo *fix = &fbi->fix;
1053 unsigned int end; 1074 unsigned int end;
1054 unsigned int start; 1075 unsigned int start;
1076 unsigned long irq_flags;
1055 1077
1056 if (var->xoffset != fbi->var.xoffset || 1078 if (var->xoffset != fbi->var.xoffset ||
1057 var->yoffset != fbi->var.yoffset) { 1079 var->yoffset != fbi->var.yoffset) {
@@ -1069,6 +1091,21 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var,
1069 end = start + fbi->var.yres * fix->line_length - 1; 1091 end = start + fbi->var.yres * fix->line_length - 1;
1070 par->dma_start = start; 1092 par->dma_start = start;
1071 par->dma_end = end; 1093 par->dma_end = end;
1094 spin_lock_irqsave(&par->lock_for_chan_update,
1095 irq_flags);
1096 if (par->which_dma_channel_done == 0) {
1097 lcdc_write(par->dma_start,
1098 LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
1099 lcdc_write(par->dma_end,
1100 LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
1101 } else if (par->which_dma_channel_done == 1) {
1102 lcdc_write(par->dma_start,
1103 LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
1104 lcdc_write(par->dma_end,
1105 LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
1106 }
1107 spin_unlock_irqrestore(&par->lock_for_chan_update,
1108 irq_flags);
1072 } 1109 }
1073 } 1110 }
1074 1111
@@ -1114,6 +1151,7 @@ static int __devinit fb_probe(struct platform_device *device)
1114 struct da8xx_fb_par *par; 1151 struct da8xx_fb_par *par;
1115 resource_size_t len; 1152 resource_size_t len;
1116 int ret, i; 1153 int ret, i;
1154 unsigned long ulcm;
1117 1155
1118 if (fb_pdata == NULL) { 1156 if (fb_pdata == NULL) {
1119 dev_err(&device->dev, "Can not get platform data\n"); 1157 dev_err(&device->dev, "Can not get platform data\n");
@@ -1209,7 +1247,8 @@ static int __devinit fb_probe(struct platform_device *device)
1209 1247
1210 /* allocate frame buffer */ 1248 /* allocate frame buffer */
1211 par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp; 1249 par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp;
1212 par->vram_size = PAGE_ALIGN(par->vram_size/8); 1250 ulcm = lcm((lcdc_info->width * lcd_cfg->bpp)/8, PAGE_SIZE);
1251 par->vram_size = roundup(par->vram_size/8, ulcm);
1213 par->vram_size = par->vram_size * LCD_NUM_BUFFERS; 1252 par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
1214 1253
1215 par->vram_virt = dma_alloc_coherent(NULL, 1254 par->vram_virt = dma_alloc_coherent(NULL,
@@ -1296,6 +1335,8 @@ static int __devinit fb_probe(struct platform_device *device)
1296 /* initialize the vsync wait queue */ 1335 /* initialize the vsync wait queue */
1297 init_waitqueue_head(&par->vsync_wait); 1336 init_waitqueue_head(&par->vsync_wait);
1298 par->vsync_timeout = HZ / 5; 1337 par->vsync_timeout = HZ / 5;
1338 par->which_dma_channel_done = -1;
1339 spin_lock_init(&par->lock_for_chan_update);
1299 1340
1300 /* Register the Frame Buffer */ 1341 /* Register the Frame Buffer */
1301 if (register_framebuffer(da8xx_fb_info) < 0) { 1342 if (register_framebuffer(da8xx_fb_info) < 0) {
@@ -1382,11 +1423,12 @@ static int fb_resume(struct platform_device *dev)
1382 struct da8xx_fb_par *par = info->par; 1423 struct da8xx_fb_par *par = info->par;
1383 1424
1384 console_lock(); 1425 console_lock();
1426 clk_enable(par->lcdc_clk);
1427 lcd_enable_raster();
1428
1385 if (par->panel_power_ctrl) 1429 if (par->panel_power_ctrl)
1386 par->panel_power_ctrl(1); 1430 par->panel_power_ctrl(1);
1387 1431
1388 clk_enable(par->lcdc_clk);
1389 lcd_enable_raster();
1390 fb_set_suspend(info, 0); 1432 fb_set_suspend(info, 0);
1391 console_unlock(); 1433 console_unlock();
1392 1434
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index a268cbf1cbea..68b9b511ce80 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -477,11 +477,11 @@ static __init unsigned int get_fb_size(struct fb_info *info)
477 return size; 477 return size;
478} 478}
479 479
480static int epson1355_width_tab[2][4] __initdata = 480static int epson1355_width_tab[2][4] __devinitdata =
481 { {4, 8, 16, -1}, {9, 12, 16, -1} }; 481 { {4, 8, 16, -1}, {9, 12, 16, -1} };
482static int epson1355_bpp_tab[8] __initdata = { 1, 2, 4, 8, 15, 16 }; 482static int epson1355_bpp_tab[8] __devinitdata = { 1, 2, 4, 8, 15, 16 };
483 483
484static void __init fetch_hw_state(struct fb_info *info, struct epson1355_par *par) 484static void __devinit fetch_hw_state(struct fb_info *info, struct epson1355_par *par)
485{ 485{
486 struct fb_var_screeninfo *var = &info->var; 486 struct fb_var_screeninfo *var = &info->var;
487 struct fb_fix_screeninfo *fix = &info->fix; 487 struct fb_fix_screeninfo *fix = &info->fix;
@@ -601,7 +601,7 @@ static int epson1355fb_remove(struct platform_device *dev)
601 return 0; 601 return 0;
602} 602}
603 603
604int __devinit epson1355fb_probe(struct platform_device *dev) 604static int __devinit epson1355fb_probe(struct platform_device *dev)
605{ 605{
606 struct epson1355_par *default_par; 606 struct epson1355_par *default_par;
607 struct fb_info *info; 607 struct fb_info *info;
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index a36b2d28280e..c6c016a506ce 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -47,7 +47,7 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
47 47
48 exynos_dp_init_hpd(dp); 48 exynos_dp_init_hpd(dp);
49 49
50 udelay(200); 50 usleep_range(200, 210);
51 51
52 while (exynos_dp_get_plug_in_status(dp) != 0) { 52 while (exynos_dp_get_plug_in_status(dp) != 0) {
53 timeout_loop++; 53 timeout_loop++;
@@ -55,7 +55,7 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
55 dev_err(dp->dev, "failed to get hpd plug status\n"); 55 dev_err(dp->dev, "failed to get hpd plug status\n");
56 return -ETIMEDOUT; 56 return -ETIMEDOUT;
57 } 57 }
58 udelay(10); 58 usleep_range(10, 11);
59 } 59 }
60 60
61 return 0; 61 return 0;
@@ -304,7 +304,7 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
304 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | 304 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
305 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0; 305 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
306 exynos_dp_write_bytes_to_dpcd(dp, 306 exynos_dp_write_bytes_to_dpcd(dp,
307 DPCD_ADDR_TRAINING_PATTERN_SET, 307 DPCD_ADDR_TRAINING_LANE0_SET,
308 lane_count, buf); 308 lane_count, buf);
309} 309}
310 310
@@ -336,7 +336,7 @@ static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
336 u8 lane_status; 336 u8 lane_status;
337 337
338 lane_align = link_status[2]; 338 lane_align = link_status[2];
339 if ((lane_align == DPCD_INTERLANE_ALIGN_DONE) == 0) 339 if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
340 return -EINVAL; 340 return -EINVAL;
341 341
342 for (lane = 0; lane < lane_count; lane++) { 342 for (lane = 0; lane < lane_count; lane++) {
@@ -407,6 +407,9 @@ static unsigned int exynos_dp_get_lane_link_training(
407 case 3: 407 case 3:
408 reg = exynos_dp_get_lane3_link_training(dp); 408 reg = exynos_dp_get_lane3_link_training(dp);
409 break; 409 break;
410 default:
411 WARN_ON(1);
412 return 0;
410 } 413 }
411 414
412 return reg; 415 return reg;
@@ -483,7 +486,7 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
483 u8 pre_emphasis; 486 u8 pre_emphasis;
484 u8 training_lane; 487 u8 training_lane;
485 488
486 udelay(100); 489 usleep_range(100, 101);
487 490
488 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 491 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
489 6, link_status); 492 6, link_status);
@@ -501,7 +504,7 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
501 buf[0] = DPCD_SCRAMBLING_DISABLED | 504 buf[0] = DPCD_SCRAMBLING_DISABLED |
502 DPCD_TRAINING_PATTERN_2; 505 DPCD_TRAINING_PATTERN_2;
503 exynos_dp_write_byte_to_dpcd(dp, 506 exynos_dp_write_byte_to_dpcd(dp,
504 DPCD_ADDR_TRAINING_LANE0_SET, 507 DPCD_ADDR_TRAINING_PATTERN_SET,
505 buf[0]); 508 buf[0]);
506 509
507 for (lane = 0; lane < lane_count; lane++) { 510 for (lane = 0; lane < lane_count; lane++) {
@@ -568,7 +571,7 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
568 571
569 u8 adjust_request[2]; 572 u8 adjust_request[2];
570 573
571 udelay(400); 574 usleep_range(400, 401);
572 575
573 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 576 exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
574 6, link_status); 577 6, link_status);
@@ -736,7 +739,7 @@ static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
736 if (retval == 0) 739 if (retval == 0)
737 break; 740 break;
738 741
739 udelay(100); 742 usleep_range(100, 110);
740 } 743 }
741 744
742 return retval; 745 return retval;
@@ -770,7 +773,7 @@ static int exynos_dp_config_video(struct exynos_dp_device *dp,
770 return -ETIMEDOUT; 773 return -ETIMEDOUT;
771 } 774 }
772 775
773 udelay(1); 776 usleep_range(1, 2);
774 } 777 }
775 778
776 /* Set to use the register calculated M/N video */ 779 /* Set to use the register calculated M/N video */
@@ -804,7 +807,7 @@ static int exynos_dp_config_video(struct exynos_dp_device *dp,
804 return -ETIMEDOUT; 807 return -ETIMEDOUT;
805 } 808 }
806 809
807 mdelay(1); 810 usleep_range(1000, 1001);
808 } 811 }
809 812
810 if (retval != 0) 813 if (retval != 0)
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 1e0f998e0c9f..8526e548c385 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -85,10 +85,6 @@ void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
85void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype); 85void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
86void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count); 86void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
87void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count); 87void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
88void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
89void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
90void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
91void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
92void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable); 88void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
93void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, 89void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
94 enum pattern_set pattern); 90 enum pattern_set pattern);
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index bcb0e3ae1e9d..2db5b9aa250a 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -122,7 +122,7 @@ void exynos_dp_reset(struct exynos_dp_device *dp)
122 LS_CLK_DOMAIN_FUNC_EN_N; 122 LS_CLK_DOMAIN_FUNC_EN_N;
123 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 123 writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
124 124
125 udelay(20); 125 usleep_range(20, 30);
126 126
127 exynos_dp_lane_swap(dp, 0); 127 exynos_dp_lane_swap(dp, 0);
128 128
@@ -988,7 +988,7 @@ void exynos_dp_reset_macro(struct exynos_dp_device *dp)
988 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); 988 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
989 989
990 /* 10 us is the minimum reset time. */ 990 /* 10 us is the minimum reset time. */
991 udelay(10); 991 usleep_range(10, 20);
992 992
993 reg &= ~MACRO_RST; 993 reg &= ~MACRO_RST;
994 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); 994 writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 9908e75ae761..4bc2b8a5dd8b 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -154,7 +154,7 @@ static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
154 if (client_drv && client_drv->power_on) 154 if (client_drv && client_drv->power_on)
155 client_drv->power_on(client_dev, 1); 155 client_drv->power_on(client_dev, 1);
156 156
157 exynos_mipi_regulator_disable(dsim); 157 exynos_mipi_regulator_enable(dsim);
158 158
159 /* enable MIPI-DSI PHY. */ 159 /* enable MIPI-DSI PHY. */
160 if (dsim->pd->phy_enable) 160 if (dsim->pd->phy_enable)
diff --git a/drivers/video/exynos/s6e8ax0.h b/drivers/video/exynos/s6e8ax0.h
deleted file mode 100644
index 1f1b270484b0..000000000000
--- a/drivers/video/exynos/s6e8ax0.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/* linux/drivers/video/backlight/s6e8ax0.h
2 *
3 * MIPI-DSI based s6e8ax0 AMOLED LCD Panel definitions.
4 *
5 * Copyright (c) 2011 Samsung Electronics
6 *
7 * Inki Dae, <inki.dae@samsung.com>
8 * Donghwa Lee <dh09.lee@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef _S6E8AX0_H
16#define _S6E8AX0_H
17
18extern void s6e8ax0_init(void);
19
20#endif
21
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
index 04c01faaf772..624ee115f129 100644
--- a/drivers/video/fb_draw.h
+++ b/drivers/video/fb_draw.h
@@ -3,6 +3,7 @@
3 3
4#include <asm/types.h> 4#include <asm/types.h>
5#include <linux/fb.h> 5#include <linux/fb.h>
6#include <linux/bug.h>
6 7
7 /* 8 /*
8 * Compose two values, using a bitmask as decision value 9 * Compose two values, using a bitmask as decision value
@@ -41,7 +42,8 @@ pixel_to_pat( u32 bpp, u32 pixel)
41 case 32: 42 case 32:
42 return 0x0000000100000001ul*pixel; 43 return 0x0000000100000001ul*pixel;
43 default: 44 default:
44 panic("pixel_to_pat(): unsupported pixelformat\n"); 45 WARN(1, "pixel_to_pat(): unsupported pixelformat %d\n", bpp);
46 return 0;
45 } 47 }
46} 48}
47#else 49#else
@@ -66,7 +68,8 @@ pixel_to_pat( u32 bpp, u32 pixel)
66 case 32: 68 case 32:
67 return 0x00000001ul*pixel; 69 return 0x00000001ul*pixel;
68 default: 70 default:
69 panic("pixel_to_pat(): unsupported pixelformat\n"); 71 WARN(1, "pixel_to_pat(): unsupported pixelformat %d\n", bpp);
72 return 0;
70 } 73 }
71} 74}
72#endif 75#endif
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c
index da066c210923..5245f9a71892 100644
--- a/drivers/video/grvga.c
+++ b/drivers/video/grvga.c
@@ -354,7 +354,7 @@ static int __devinit grvga_probe(struct platform_device *dev)
354 */ 354 */
355 if (fb_get_options("grvga", &options)) { 355 if (fb_get_options("grvga", &options)) {
356 retval = -ENODEV; 356 retval = -ENODEV;
357 goto err; 357 goto free_fb;
358 } 358 }
359 359
360 if (!options || !*options) 360 if (!options || !*options)
@@ -370,7 +370,7 @@ static int __devinit grvga_probe(struct platform_device *dev)
370 if (grvga_parse_custom(this_opt, &info->var) < 0) { 370 if (grvga_parse_custom(this_opt, &info->var) < 0) {
371 dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt); 371 dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt);
372 retval = -EINVAL; 372 retval = -EINVAL;
373 goto err1; 373 goto free_fb;
374 } 374 }
375 } else if (!strncmp(this_opt, "addr", 4)) 375 } else if (!strncmp(this_opt, "addr", 4))
376 grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16); 376 grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16);
@@ -387,10 +387,11 @@ static int __devinit grvga_probe(struct platform_device *dev)
387 info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN; 387 info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
388 info->fix.smem_len = grvga_mem_size; 388 info->fix.smem_len = grvga_mem_size;
389 389
390 if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) { 390 if (!devm_request_mem_region(&dev->dev, dev->resource[0].start,
391 resource_size(&dev->resource[0]), "grlib-svgactrl regs")) {
391 dev_err(&dev->dev, "registers already mapped\n"); 392 dev_err(&dev->dev, "registers already mapped\n");
392 retval = -EBUSY; 393 retval = -EBUSY;
393 goto err; 394 goto free_fb;
394 } 395 }
395 396
396 par->regs = of_ioremap(&dev->resource[0], 0, 397 par->regs = of_ioremap(&dev->resource[0], 0,
@@ -400,14 +401,14 @@ static int __devinit grvga_probe(struct platform_device *dev)
400 if (!par->regs) { 401 if (!par->regs) {
401 dev_err(&dev->dev, "failed to map registers\n"); 402 dev_err(&dev->dev, "failed to map registers\n");
402 retval = -ENOMEM; 403 retval = -ENOMEM;
403 goto err1; 404 goto free_fb;
404 } 405 }
405 406
406 retval = fb_alloc_cmap(&info->cmap, 256, 0); 407 retval = fb_alloc_cmap(&info->cmap, 256, 0);
407 if (retval < 0) { 408 if (retval < 0) {
408 dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n"); 409 dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n");
409 retval = -ENOMEM; 410 retval = -ENOMEM;
410 goto err2; 411 goto unmap_regs;
411 } 412 }
412 413
413 if (mode_opt) { 414 if (mode_opt) {
@@ -415,7 +416,7 @@ static int __devinit grvga_probe(struct platform_device *dev)
415 grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8); 416 grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8);
416 if (!retval || retval == 4) { 417 if (!retval || retval == 4) {
417 retval = -EINVAL; 418 retval = -EINVAL;
418 goto err3; 419 goto dealloc_cmap;
419 } 420 }
420 } 421 }
421 422
@@ -427,10 +428,11 @@ static int __devinit grvga_probe(struct platform_device *dev)
427 428
428 physical_start = grvga_fix_addr; 429 physical_start = grvga_fix_addr;
429 430
430 if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) { 431 if (!devm_request_mem_region(&dev->dev, physical_start,
432 grvga_mem_size, dev->name)) {
431 dev_err(&dev->dev, "failed to request memory region\n"); 433 dev_err(&dev->dev, "failed to request memory region\n");
432 retval = -ENOMEM; 434 retval = -ENOMEM;
433 goto err3; 435 goto dealloc_cmap;
434 } 436 }
435 437
436 virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size); 438 virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size);
@@ -438,7 +440,7 @@ static int __devinit grvga_probe(struct platform_device *dev)
438 if (!virtual_start) { 440 if (!virtual_start) {
439 dev_err(&dev->dev, "error mapping framebuffer memory\n"); 441 dev_err(&dev->dev, "error mapping framebuffer memory\n");
440 retval = -ENOMEM; 442 retval = -ENOMEM;
441 goto err4; 443 goto dealloc_cmap;
442 } 444 }
443 } else { /* Allocate frambuffer memory */ 445 } else { /* Allocate frambuffer memory */
444 446
@@ -451,7 +453,7 @@ static int __devinit grvga_probe(struct platform_device *dev)
451 "unable to allocate framebuffer memory (%lu bytes)\n", 453 "unable to allocate framebuffer memory (%lu bytes)\n",
452 grvga_mem_size); 454 grvga_mem_size);
453 retval = -ENOMEM; 455 retval = -ENOMEM;
454 goto err3; 456 goto dealloc_cmap;
455 } 457 }
456 458
457 physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE); 459 physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE);
@@ -484,7 +486,7 @@ static int __devinit grvga_probe(struct platform_device *dev)
484 retval = register_framebuffer(info); 486 retval = register_framebuffer(info);
485 if (retval < 0) { 487 if (retval < 0) {
486 dev_err(&dev->dev, "failed to register framebuffer\n"); 488 dev_err(&dev->dev, "failed to register framebuffer\n");
487 goto err4; 489 goto free_mem;
488 } 490 }
489 491
490 __raw_writel(physical_start, &par->regs->fb_pos); 492 __raw_writel(physical_start, &par->regs->fb_pos);
@@ -493,21 +495,18 @@ static int __devinit grvga_probe(struct platform_device *dev)
493 495
494 return 0; 496 return 0;
495 497
496err4: 498free_mem:
497 dev_set_drvdata(&dev->dev, NULL); 499 dev_set_drvdata(&dev->dev, NULL);
498 if (grvga_fix_addr) { 500 if (grvga_fix_addr)
499 release_mem_region(physical_start, grvga_mem_size);
500 iounmap((void *)virtual_start); 501 iounmap((void *)virtual_start);
501 } else 502 else
502 kfree((void *)virtual_start); 503 kfree((void *)virtual_start);
503err3: 504dealloc_cmap:
504 fb_dealloc_cmap(&info->cmap); 505 fb_dealloc_cmap(&info->cmap);
505err2: 506unmap_regs:
506 of_iounmap(&dev->resource[0], par->regs, 507 of_iounmap(&dev->resource[0], par->regs,
507 resource_size(&dev->resource[0])); 508 resource_size(&dev->resource[0]));
508err1: 509free_fb:
509 release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]));
510err:
511 framebuffer_release(info); 510 framebuffer_release(info);
512 511
513 return retval; 512 return retval;
@@ -524,12 +523,10 @@ static int __devexit grvga_remove(struct platform_device *device)
524 523
525 of_iounmap(&device->resource[0], par->regs, 524 of_iounmap(&device->resource[0], par->regs,
526 resource_size(&device->resource[0])); 525 resource_size(&device->resource[0]));
527 release_mem_region(device->resource[0].start, resource_size(&device->resource[0]));
528 526
529 if (!par->fb_alloced) { 527 if (!par->fb_alloced)
530 release_mem_region(info->fix.smem_start, info->fix.smem_len);
531 iounmap(info->screen_base); 528 iounmap(info->screen_base);
532 } else 529 else
533 kfree((void *)info->screen_base); 530 kfree((void *)info->screen_base);
534 531
535 framebuffer_release(info); 532 framebuffer_release(info);
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index eec0d7b748eb..c89f8a8d36d2 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -269,7 +269,7 @@ struct mx3fb_info {
269 dma_cookie_t cookie; 269 dma_cookie_t cookie;
270 struct scatterlist sg[2]; 270 struct scatterlist sg[2];
271 271
272 u32 sync; /* preserve var->sync flags */ 272 struct fb_var_screeninfo cur_var; /* current var info */
273}; 273};
274 274
275static void mx3fb_dma_done(void *); 275static void mx3fb_dma_done(void *);
@@ -698,9 +698,29 @@ static void mx3fb_dma_done(void *arg)
698 complete(&mx3_fbi->flip_cmpl); 698 complete(&mx3_fbi->flip_cmpl);
699} 699}
700 700
701static bool mx3fb_must_set_par(struct fb_info *fbi)
702{
703 struct mx3fb_info *mx3_fbi = fbi->par;
704 struct fb_var_screeninfo old_var = mx3_fbi->cur_var;
705 struct fb_var_screeninfo new_var = fbi->var;
706
707 if ((fbi->var.activate & FB_ACTIVATE_FORCE) &&
708 (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
709 return true;
710
711 /*
712 * Ignore xoffset and yoffset update,
713 * because pan display handles this case.
714 */
715 old_var.xoffset = new_var.xoffset;
716 old_var.yoffset = new_var.yoffset;
717
718 return !!memcmp(&old_var, &new_var, sizeof(struct fb_var_screeninfo));
719}
720
701static int __set_par(struct fb_info *fbi, bool lock) 721static int __set_par(struct fb_info *fbi, bool lock)
702{ 722{
703 u32 mem_len; 723 u32 mem_len, cur_xoffset, cur_yoffset;
704 struct ipu_di_signal_cfg sig_cfg; 724 struct ipu_di_signal_cfg sig_cfg;
705 enum ipu_panel mode = IPU_PANEL_TFT; 725 enum ipu_panel mode = IPU_PANEL_TFT;
706 struct mx3fb_info *mx3_fbi = fbi->par; 726 struct mx3fb_info *mx3_fbi = fbi->par;
@@ -780,8 +800,25 @@ static int __set_par(struct fb_info *fbi, bool lock)
780 video->out_height = fbi->var.yres; 800 video->out_height = fbi->var.yres;
781 video->out_stride = fbi->var.xres_virtual; 801 video->out_stride = fbi->var.xres_virtual;
782 802
783 if (mx3_fbi->blank == FB_BLANK_UNBLANK) 803 if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
784 sdc_enable_channel(mx3_fbi); 804 sdc_enable_channel(mx3_fbi);
805 /*
806 * sg[0] points to fb smem_start address
807 * and is actually active in controller.
808 */
809 mx3_fbi->cur_var.xoffset = 0;
810 mx3_fbi->cur_var.yoffset = 0;
811 }
812
813 /*
814 * Preserve xoffset and yoffest in case they are
815 * inactive in controller as fb is blanked.
816 */
817 cur_xoffset = mx3_fbi->cur_var.xoffset;
818 cur_yoffset = mx3_fbi->cur_var.yoffset;
819 mx3_fbi->cur_var = fbi->var;
820 mx3_fbi->cur_var.xoffset = cur_xoffset;
821 mx3_fbi->cur_var.yoffset = cur_yoffset;
785 822
786 return 0; 823 return 0;
787} 824}
@@ -802,7 +839,7 @@ static int mx3fb_set_par(struct fb_info *fbi)
802 839
803 mutex_lock(&mx3_fbi->mutex); 840 mutex_lock(&mx3_fbi->mutex);
804 841
805 ret = __set_par(fbi, true); 842 ret = mx3fb_must_set_par(fbi) ? __set_par(fbi, true) : 0;
806 843
807 mutex_unlock(&mx3_fbi->mutex); 844 mutex_unlock(&mx3_fbi->mutex);
808 845
@@ -901,8 +938,8 @@ static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
901 var->grayscale = 0; 938 var->grayscale = 0;
902 939
903 /* Preserve sync flags */ 940 /* Preserve sync flags */
904 var->sync |= mx3_fbi->sync; 941 var->sync |= mx3_fbi->cur_var.sync;
905 mx3_fbi->sync |= var->sync; 942 mx3_fbi->cur_var.sync |= var->sync;
906 943
907 return 0; 944 return 0;
908} 945}
@@ -1043,8 +1080,8 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1043 return -EINVAL; 1080 return -EINVAL;
1044 } 1081 }
1045 1082
1046 if (fbi->var.xoffset == var->xoffset && 1083 if (mx3_fbi->cur_var.xoffset == var->xoffset &&
1047 fbi->var.yoffset == var->yoffset) 1084 mx3_fbi->cur_var.yoffset == var->yoffset)
1048 return 0; /* No change, do nothing */ 1085 return 0; /* No change, do nothing */
1049 1086
1050 y_bottom = var->yoffset; 1087 y_bottom = var->yoffset;
@@ -1127,6 +1164,8 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1127 else 1164 else
1128 fbi->var.vmode &= ~FB_VMODE_YWRAP; 1165 fbi->var.vmode &= ~FB_VMODE_YWRAP;
1129 1166
1167 mx3_fbi->cur_var = fbi->var;
1168
1130 mutex_unlock(&mx3_fbi->mutex); 1169 mutex_unlock(&mx3_fbi->mutex);
1131 1170
1132 dev_dbg(fbi->device, "Update complete\n"); 1171 dev_dbg(fbi->device, "Update complete\n");
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index ad741c3d1ae1..eaeed4340e04 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -487,6 +487,13 @@ static struct omap_video_timings acx_panel_timings = {
487 .vfp = 3, 487 .vfp = 3,
488 .vsw = 3, 488 .vsw = 3,
489 .vbp = 4, 489 .vbp = 4,
490
491 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
492 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
493
494 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
495 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
496 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
490}; 497};
491 498
492static int acx_panel_probe(struct omap_dss_device *dssdev) 499static int acx_panel_probe(struct omap_dss_device *dssdev)
@@ -498,8 +505,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
498 struct backlight_properties props; 505 struct backlight_properties props;
499 506
500 dev_dbg(&dssdev->dev, "%s\n", __func__); 507 dev_dbg(&dssdev->dev, "%s\n", __func__);
501 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 508
502 OMAP_DSS_LCD_IHS;
503 /* FIXME AC bias ? */ 509 /* FIXME AC bias ? */
504 dssdev->panel.timings = acx_panel_timings; 510 dssdev->panel.timings = acx_panel_timings;
505 511
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index e42f9dc22123..bc5af2500eb9 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -40,12 +40,6 @@
40struct panel_config { 40struct panel_config {
41 struct omap_video_timings timings; 41 struct omap_video_timings timings;
42 42
43 int acbi; /* ac-bias pin transitions per interrupt */
44 /* Unit: line clocks */
45 int acb; /* ac-bias pin frequency */
46
47 enum omap_panel_config config;
48
49 int power_on_delay; 43 int power_on_delay;
50 int power_off_delay; 44 int power_off_delay;
51 45
@@ -73,11 +67,13 @@ static struct panel_config generic_dpi_panels[] = {
73 .vsw = 11, 67 .vsw = 11,
74 .vfp = 3, 68 .vfp = 3,
75 .vbp = 2, 69 .vbp = 2,
70
71 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
72 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
73 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
74 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
75 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
76 }, 76 },
77 .acbi = 0x0,
78 .acb = 0x0,
79 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
80 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
81 .power_on_delay = 50, 77 .power_on_delay = 50,
82 .power_off_delay = 100, 78 .power_off_delay = 100,
83 .name = "sharp_lq", 79 .name = "sharp_lq",
@@ -98,11 +94,13 @@ static struct panel_config generic_dpi_panels[] = {
98 .vsw = 1, 94 .vsw = 1,
99 .vfp = 1, 95 .vfp = 1,
100 .vbp = 1, 96 .vbp = 1,
97
98 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
99 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
100 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
101 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
102 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
101 }, 103 },
102 .acbi = 0x0,
103 .acb = 0x28,
104 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
105 OMAP_DSS_LCD_IHS,
106 .power_on_delay = 50, 104 .power_on_delay = 50,
107 .power_off_delay = 100, 105 .power_off_delay = 100,
108 .name = "sharp_ls", 106 .name = "sharp_ls",
@@ -123,12 +121,13 @@ static struct panel_config generic_dpi_panels[] = {
123 .vfp = 4, 121 .vfp = 4,
124 .vsw = 2, 122 .vsw = 2,
125 .vbp = 2, 123 .vbp = 2,
124
125 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
126 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
127 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
128 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
129 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
126 }, 130 },
127 .acbi = 0x0,
128 .acb = 0x0,
129 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
130 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC |
131 OMAP_DSS_LCD_ONOFF,
132 .power_on_delay = 0, 131 .power_on_delay = 0,
133 .power_off_delay = 0, 132 .power_off_delay = 0,
134 .name = "toppoly_tdo35s", 133 .name = "toppoly_tdo35s",
@@ -149,11 +148,13 @@ static struct panel_config generic_dpi_panels[] = {
149 .vfp = 4, 148 .vfp = 4,
150 .vsw = 10, 149 .vsw = 10,
151 .vbp = 12 - 10, 150 .vbp = 12 - 10,
151
152 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
153 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
154 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
155 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
156 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
152 }, 157 },
153 .acbi = 0x0,
154 .acb = 0x0,
155 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
156 OMAP_DSS_LCD_IHS,
157 .power_on_delay = 0, 158 .power_on_delay = 0,
158 .power_off_delay = 0, 159 .power_off_delay = 0,
159 .name = "samsung_lte430wq_f0c", 160 .name = "samsung_lte430wq_f0c",
@@ -174,11 +175,13 @@ static struct panel_config generic_dpi_panels[] = {
174 .vsw = 2, 175 .vsw = 2,
175 .vfp = 4, 176 .vfp = 4,
176 .vbp = 11, 177 .vbp = 11,
178
179 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
180 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
181 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
182 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
183 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
177 }, 184 },
178 .acbi = 0x0,
179 .acb = 0x0,
180 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
181 OMAP_DSS_LCD_IHS,
182 .power_on_delay = 0, 185 .power_on_delay = 0,
183 .power_off_delay = 0, 186 .power_off_delay = 0,
184 .name = "seiko_70wvw1tz3", 187 .name = "seiko_70wvw1tz3",
@@ -199,11 +202,13 @@ static struct panel_config generic_dpi_panels[] = {
199 .vsw = 10, 202 .vsw = 10,
200 .vfp = 2, 203 .vfp = 2,
201 .vbp = 2, 204 .vbp = 2,
205
206 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
207 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
208 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
209 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
210 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
202 }, 211 },
203 .acbi = 0x0,
204 .acb = 0x0,
205 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
206 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
207 .power_on_delay = 0, 212 .power_on_delay = 0,
208 .power_off_delay = 0, 213 .power_off_delay = 0,
209 .name = "powertip_ph480272t", 214 .name = "powertip_ph480272t",
@@ -224,11 +229,13 @@ static struct panel_config generic_dpi_panels[] = {
224 .vsw = 3, 229 .vsw = 3,
225 .vfp = 12, 230 .vfp = 12,
226 .vbp = 25, 231 .vbp = 25,
232
233 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
234 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
235 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
236 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
237 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
227 }, 238 },
228 .acbi = 0x0,
229 .acb = 0x28,
230 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
231 OMAP_DSS_LCD_IHS,
232 .power_on_delay = 0, 239 .power_on_delay = 0,
233 .power_off_delay = 0, 240 .power_off_delay = 0,
234 .name = "innolux_at070tn83", 241 .name = "innolux_at070tn83",
@@ -249,9 +256,13 @@ static struct panel_config generic_dpi_panels[] = {
249 .vsw = 1, 256 .vsw = 1,
250 .vfp = 2, 257 .vfp = 2,
251 .vbp = 7, 258 .vbp = 7,
259
260 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
261 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
262 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
263 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
264 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
252 }, 265 },
253 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
254 OMAP_DSS_LCD_IHS,
255 .name = "nec_nl2432dr22-11b", 266 .name = "nec_nl2432dr22-11b",
256 }, 267 },
257 268
@@ -270,9 +281,13 @@ static struct panel_config generic_dpi_panels[] = {
270 .vsw = 1, 281 .vsw = 1,
271 .vfp = 1, 282 .vfp = 1,
272 .vbp = 1, 283 .vbp = 1,
273 },
274 .config = OMAP_DSS_LCD_TFT,
275 284
285 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
286 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
287 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
288 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
289 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
290 },
276 .name = "h4", 291 .name = "h4",
277 }, 292 },
278 293
@@ -291,10 +306,13 @@ static struct panel_config generic_dpi_panels[] = {
291 .vsw = 10, 306 .vsw = 10,
292 .vfp = 2, 307 .vfp = 2,
293 .vbp = 2, 308 .vbp = 2,
294 },
295 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
296 OMAP_DSS_LCD_IHS,
297 309
310 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
311 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
312 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
313 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
314 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
315 },
298 .name = "apollon", 316 .name = "apollon",
299 }, 317 },
300 /* FocalTech ETM070003DH6 */ 318 /* FocalTech ETM070003DH6 */
@@ -312,9 +330,13 @@ static struct panel_config generic_dpi_panels[] = {
312 .vsw = 3, 330 .vsw = 3,
313 .vfp = 13, 331 .vfp = 13,
314 .vbp = 29, 332 .vbp = 29,
333
334 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
335 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
336 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
337 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
338 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
315 }, 339 },
316 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
317 OMAP_DSS_LCD_IHS,
318 .name = "focaltech_etm070003dh6", 340 .name = "focaltech_etm070003dh6",
319 }, 341 },
320 342
@@ -333,11 +355,13 @@ static struct panel_config generic_dpi_panels[] = {
333 .vsw = 23, 355 .vsw = 23,
334 .vfp = 1, 356 .vfp = 1,
335 .vbp = 1, 357 .vbp = 1,
358
359 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
360 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
361 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
362 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
363 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
336 }, 364 },
337 .acbi = 0x0,
338 .acb = 0x0,
339 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
340 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
341 .power_on_delay = 0, 365 .power_on_delay = 0,
342 .power_off_delay = 0, 366 .power_off_delay = 0,
343 .name = "microtips_umsh_8173md", 367 .name = "microtips_umsh_8173md",
@@ -358,9 +382,13 @@ static struct panel_config generic_dpi_panels[] = {
358 .vsw = 10, 382 .vsw = 10,
359 .vfp = 4, 383 .vfp = 4,
360 .vbp = 2, 384 .vbp = 2,
361 },
362 .config = OMAP_DSS_LCD_TFT,
363 385
386 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
387 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
388 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
389 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
390 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
391 },
364 .name = "ortustech_com43h4m10xtc", 392 .name = "ortustech_com43h4m10xtc",
365 }, 393 },
366 394
@@ -379,11 +407,13 @@ static struct panel_config generic_dpi_panels[] = {
379 .vsw = 10, 407 .vsw = 10,
380 .vfp = 12, 408 .vfp = 12,
381 .vbp = 23, 409 .vbp = 23,
382 },
383 .acb = 0x0,
384 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
385 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
386 410
411 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
412 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
413 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
414 .de_level = OMAPDSS_SIG_ACTIVE_LOW,
415 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
416 },
387 .name = "innolux_at080tn52", 417 .name = "innolux_at080tn52",
388 }, 418 },
389 419
@@ -401,8 +431,13 @@ static struct panel_config generic_dpi_panels[] = {
401 .vsw = 1, 431 .vsw = 1,
402 .vfp = 26, 432 .vfp = 26,
403 .vbp = 1, 433 .vbp = 1,
434
435 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
436 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
437 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
438 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
439 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
404 }, 440 },
405 .config = OMAP_DSS_LCD_TFT,
406 .name = "mitsubishi_aa084sb01", 441 .name = "mitsubishi_aa084sb01",
407 }, 442 },
408 /* EDT ET0500G0DH6 */ 443 /* EDT ET0500G0DH6 */
@@ -419,8 +454,13 @@ static struct panel_config generic_dpi_panels[] = {
419 .vsw = 2, 454 .vsw = 2,
420 .vfp = 35, 455 .vfp = 35,
421 .vbp = 10, 456 .vbp = 10,
457
458 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
459 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
460 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
461 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
462 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
422 }, 463 },
423 .config = OMAP_DSS_LCD_TFT,
424 .name = "edt_et0500g0dh6", 464 .name = "edt_et0500g0dh6",
425 }, 465 },
426 466
@@ -439,9 +479,13 @@ static struct panel_config generic_dpi_panels[] = {
439 .vsw = 2, 479 .vsw = 2,
440 .vfp = 10, 480 .vfp = 10,
441 .vbp = 33, 481 .vbp = 33,
482
483 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
484 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
485 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
486 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
487 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
442 }, 488 },
443 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
444 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
445 .name = "primeview_pd050vl1", 489 .name = "primeview_pd050vl1",
446 }, 490 },
447 491
@@ -460,9 +504,13 @@ static struct panel_config generic_dpi_panels[] = {
460 .vsw = 2, 504 .vsw = 2,
461 .vfp = 10, 505 .vfp = 10,
462 .vbp = 33, 506 .vbp = 33,
507
508 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
509 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
510 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
511 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
512 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
463 }, 513 },
464 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
465 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
466 .name = "primeview_pm070wl4", 514 .name = "primeview_pm070wl4",
467 }, 515 },
468 516
@@ -481,9 +529,13 @@ static struct panel_config generic_dpi_panels[] = {
481 .vsw = 4, 529 .vsw = 4,
482 .vfp = 1, 530 .vfp = 1,
483 .vbp = 23, 531 .vbp = 23,
532
533 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
534 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
535 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
536 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
537 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
484 }, 538 },
485 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
486 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
487 .name = "primeview_pd104slf", 539 .name = "primeview_pd104slf",
488 }, 540 },
489}; 541};
@@ -573,10 +625,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
573 if (!panel_config) 625 if (!panel_config)
574 return -EINVAL; 626 return -EINVAL;
575 627
576 dssdev->panel.config = panel_config->config;
577 dssdev->panel.timings = panel_config->timings; 628 dssdev->panel.timings = panel_config->timings;
578 dssdev->panel.acb = panel_config->acb;
579 dssdev->panel.acbi = panel_config->acbi;
580 629
581 drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); 630 drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
582 if (!drv_data) 631 if (!drv_data)
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 0841cc2b3f77..802807798846 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -40,6 +40,12 @@ static struct omap_video_timings lb035q02_timings = {
40 .vsw = 2, 40 .vsw = 2,
41 .vfp = 4, 41 .vfp = 4,
42 .vbp = 18, 42 .vbp = 18,
43
44 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
45 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
46 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
47 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
48 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
43}; 49};
44 50
45static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) 51static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
@@ -82,8 +88,6 @@ static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
82 struct lb035q02_data *ld; 88 struct lb035q02_data *ld;
83 int r; 89 int r;
84 90
85 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
86 OMAP_DSS_LCD_IHS;
87 dssdev->panel.timings = lb035q02_timings; 91 dssdev->panel.timings = lb035q02_timings;
88 92
89 ld = kzalloc(sizeof(*ld), GFP_KERNEL); 93 ld = kzalloc(sizeof(*ld), GFP_KERNEL);
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 4a34cdc1371b..e6c115373c00 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -473,7 +473,6 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
473 473
474 mutex_init(&ddata->lock); 474 mutex_init(&ddata->lock);
475 475
476 dssdev->panel.config = OMAP_DSS_LCD_TFT;
477 dssdev->panel.timings.x_res = 800; 476 dssdev->panel.timings.x_res = 800;
478 dssdev->panel.timings.y_res = 480; 477 dssdev->panel.timings.y_res = 480;
479 dssdev->ctrl.pixel_size = 16; 478 dssdev->ctrl.pixel_size = 16;
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 8b38b39213f4..b122b0f31c43 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -76,6 +76,12 @@ static struct omap_video_timings nec_8048_panel_timings = {
76 .vfp = 3, 76 .vfp = 3,
77 .vsw = 1, 77 .vsw = 1,
78 .vbp = 4, 78 .vbp = 4,
79
80 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
81 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
82 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
83 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
84 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
79}; 85};
80 86
81static int nec_8048_bl_update_status(struct backlight_device *bl) 87static int nec_8048_bl_update_status(struct backlight_device *bl)
@@ -116,9 +122,6 @@ static int nec_8048_panel_probe(struct omap_dss_device *dssdev)
116 struct backlight_properties props; 122 struct backlight_properties props;
117 int r; 123 int r;
118 124
119 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
120 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_RF |
121 OMAP_DSS_LCD_ONOFF;
122 dssdev->panel.timings = nec_8048_panel_timings; 125 dssdev->panel.timings = nec_8048_panel_timings;
123 126
124 necd = kzalloc(sizeof(*necd), GFP_KERNEL); 127 necd = kzalloc(sizeof(*necd), GFP_KERNEL);
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 98ebdaddab5a..2d35bd388860 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -69,6 +69,12 @@ static struct omap_video_timings pico_ls_timings = {
69 .vsw = 2, 69 .vsw = 2,
70 .vfp = 3, 70 .vfp = 3,
71 .vbp = 14, 71 .vbp = 14,
72
73 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
74 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
75 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
76 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
77 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
72}; 78};
73 79
74static inline struct picodlp_panel_data 80static inline struct picodlp_panel_data
@@ -414,9 +420,6 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
414 struct i2c_client *picodlp_i2c_client; 420 struct i2c_client *picodlp_i2c_client;
415 int r = 0, picodlp_adapter_id; 421 int r = 0, picodlp_adapter_id;
416 422
417 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF |
418 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS;
419 dssdev->panel.acb = 0x0;
420 dssdev->panel.timings = pico_ls_timings; 423 dssdev->panel.timings = pico_ls_timings;
421 424
422 picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL); 425 picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL);
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index ba38b3ad17d6..bd86ba9ccf76 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -44,6 +44,12 @@ static struct omap_video_timings sharp_ls_timings = {
44 .vsw = 1, 44 .vsw = 1,
45 .vfp = 1, 45 .vfp = 1,
46 .vbp = 1, 46 .vbp = 1,
47
48 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
49 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
50 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
51 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
52 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
47}; 53};
48 54
49static int sharp_ls_bl_update_status(struct backlight_device *bl) 55static int sharp_ls_bl_update_status(struct backlight_device *bl)
@@ -86,9 +92,6 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
86 struct sharp_data *sd; 92 struct sharp_data *sd;
87 int r; 93 int r;
88 94
89 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
90 OMAP_DSS_LCD_IHS;
91 dssdev->panel.acb = 0x28;
92 dssdev->panel.timings = sharp_ls_timings; 95 dssdev->panel.timings = sharp_ls_timings;
93 96
94 sd = kzalloc(sizeof(*sd), GFP_KERNEL); 97 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 901576eb5a84..3f5acc7771da 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -882,7 +882,6 @@ static int taal_probe(struct omap_dss_device *dssdev)
882 goto err; 882 goto err;
883 } 883 }
884 884
885 dssdev->panel.config = OMAP_DSS_LCD_TFT;
886 dssdev->panel.timings = panel_config->timings; 885 dssdev->panel.timings = panel_config->timings;
887 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; 886 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
888 887
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index bff306e041ca..40cc0cfa5d17 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -39,6 +39,12 @@ static const struct omap_video_timings tfp410_default_timings = {
39 .vfp = 3, 39 .vfp = 3,
40 .vsw = 4, 40 .vsw = 4,
41 .vbp = 7, 41 .vbp = 7,
42
43 .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
44 .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
45 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
46 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
47 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
42}; 48};
43 49
44struct panel_drv_data { 50struct panel_drv_data {
@@ -95,7 +101,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
95 return -ENOMEM; 101 return -ENOMEM;
96 102
97 dssdev->panel.timings = tfp410_default_timings; 103 dssdev->panel.timings = tfp410_default_timings;
98 dssdev->panel.config = OMAP_DSS_LCD_TFT;
99 104
100 ddata->dssdev = dssdev; 105 ddata->dssdev = dssdev;
101 mutex_init(&ddata->lock); 106 mutex_init(&ddata->lock);
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index 4b6448b3c31f..fa7baa650ae0 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -267,6 +267,12 @@ static const struct omap_video_timings tpo_td043_timings = {
267 .vsw = 1, 267 .vsw = 1,
268 .vfp = 39, 268 .vfp = 39,
269 .vbp = 34, 269 .vbp = 34,
270
271 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
272 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
273 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
274 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
275 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
270}; 276};
271 277
272static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) 278static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
@@ -423,8 +429,6 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
423 return -ENODEV; 429 return -ENODEV;
424 } 430 }
425 431
426 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS |
427 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC;
428 dssdev->panel.timings = tpo_td043_timings; 432 dssdev->panel.timings = tpo_td043_timings;
429 dssdev->ctrl.pixel_size = 24; 433 dssdev->ctrl.pixel_size = 24;
430 434
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 43324e5ed25f..b337a8469fd8 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -52,7 +52,7 @@ config OMAP2_DSS_RFBI
52 DBI is a bus between the host processor and a peripheral, 52 DBI is a bus between the host processor and a peripheral,
53 such as a display or a framebuffer chip. 53 such as a display or a framebuffer chip.
54 54
55 See http://www.mipi.org/ for DBI spesifications. 55 See http://www.mipi.org/ for DBI specifications.
56 56
57config OMAP2_DSS_VENC 57config OMAP2_DSS_VENC
58 bool "VENC support" 58 bool "VENC support"
@@ -92,7 +92,7 @@ config OMAP2_DSS_DSI
92 DSI is a high speed half-duplex serial interface between the host 92 DSI is a high speed half-duplex serial interface between the host
93 processor and a peripheral, such as a display or a framebuffer chip. 93 processor and a peripheral, such as a display or a framebuffer chip.
94 94
95 See http://www.mipi.org/ for DSI spesifications. 95 See http://www.mipi.org/ for DSI specifications.
96 96
97config OMAP2_DSS_MIN_FCK_PER_PCK 97config OMAP2_DSS_MIN_FCK_PER_PCK
98 int "Minimum FCK/PCK ratio (for scaling)" 98 int "Minimum FCK/PCK ratio (for scaling)"
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index ab22cc224f3e..0fefc68372b9 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -104,6 +104,7 @@ struct mgr_priv_data {
104 bool shadow_extra_info_dirty; 104 bool shadow_extra_info_dirty;
105 105
106 struct omap_video_timings timings; 106 struct omap_video_timings timings;
107 struct dss_lcd_mgr_config lcd_config;
107}; 108};
108 109
109static struct { 110static struct {
@@ -137,6 +138,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
137void dss_apply_init(void) 138void dss_apply_init(void)
138{ 139{
139 const int num_ovls = dss_feat_get_num_ovls(); 140 const int num_ovls = dss_feat_get_num_ovls();
141 struct mgr_priv_data *mp;
140 int i; 142 int i;
141 143
142 spin_lock_init(&data_lock); 144 spin_lock_init(&data_lock);
@@ -168,16 +170,35 @@ void dss_apply_init(void)
168 170
169 op->user_info = op->info; 171 op->user_info = op->info;
170 } 172 }
173
174 /*
175 * Initialize some of the lcd_config fields for TV manager, this lets
176 * us prevent checking if the manager is LCD or TV at some places
177 */
178 mp = &dss_data.mgr_priv_data_array[OMAP_DSS_CHANNEL_DIGIT];
179
180 mp->lcd_config.video_port_width = 24;
181 mp->lcd_config.clock_info.lck_div = 1;
182 mp->lcd_config.clock_info.pck_div = 1;
171} 183}
172 184
185/*
186 * A LCD manager's stallmode decides whether it is in manual or auto update. TV
187 * manager is always auto update, stallmode field for TV manager is false by
188 * default
189 */
173static bool ovl_manual_update(struct omap_overlay *ovl) 190static bool ovl_manual_update(struct omap_overlay *ovl)
174{ 191{
175 return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 192 struct mgr_priv_data *mp = get_mgr_priv(ovl->manager);
193
194 return mp->lcd_config.stallmode;
176} 195}
177 196
178static bool mgr_manual_update(struct omap_overlay_manager *mgr) 197static bool mgr_manual_update(struct omap_overlay_manager *mgr)
179{ 198{
180 return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 199 struct mgr_priv_data *mp = get_mgr_priv(mgr);
200
201 return mp->lcd_config.stallmode;
181} 202}
182 203
183static int dss_check_settings_low(struct omap_overlay_manager *mgr, 204static int dss_check_settings_low(struct omap_overlay_manager *mgr,
@@ -214,7 +235,7 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr,
214 ois[ovl->id] = oi; 235 ois[ovl->id] = oi;
215 } 236 }
216 237
217 return dss_mgr_check(mgr, mi, &mp->timings, ois); 238 return dss_mgr_check(mgr, mi, &mp->timings, &mp->lcd_config, ois);
218} 239}
219 240
220/* 241/*
@@ -537,7 +558,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
537{ 558{
538 struct ovl_priv_data *op = get_ovl_priv(ovl); 559 struct ovl_priv_data *op = get_ovl_priv(ovl);
539 struct omap_overlay_info *oi; 560 struct omap_overlay_info *oi;
540 bool ilace, replication; 561 bool replication;
541 struct mgr_priv_data *mp; 562 struct mgr_priv_data *mp;
542 int r; 563 int r;
543 564
@@ -550,11 +571,9 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
550 571
551 mp = get_mgr_priv(ovl->manager); 572 mp = get_mgr_priv(ovl->manager);
552 573
553 replication = dss_use_replication(ovl->manager->device, oi->color_mode); 574 replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
554
555 ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
556 575
557 r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings); 576 r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings);
558 if (r) { 577 if (r) {
559 /* 578 /*
560 * We can't do much here, as this function can be called from 579 * We can't do much here, as this function can be called from
@@ -635,6 +654,24 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
635 654
636 dispc_mgr_set_timings(mgr->id, &mp->timings); 655 dispc_mgr_set_timings(mgr->id, &mp->timings);
637 656
657 /* lcd_config parameters */
658 if (dss_mgr_is_lcd(mgr->id)) {
659 dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode);
660
661 dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode);
662 dispc_mgr_enable_fifohandcheck(mgr->id,
663 mp->lcd_config.fifohandcheck);
664
665 dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info);
666
667 dispc_mgr_set_tft_data_lines(mgr->id,
668 mp->lcd_config.video_port_width);
669
670 dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity);
671
672 dispc_mgr_set_lcd_type_tft(mgr->id);
673 }
674
638 mp->extra_info_dirty = false; 675 mp->extra_info_dirty = false;
639 if (mp->updating) 676 if (mp->updating)
640 mp->shadow_extra_info_dirty = true; 677 mp->shadow_extra_info_dirty = true;
@@ -1294,6 +1331,44 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
1294 mutex_unlock(&apply_lock); 1331 mutex_unlock(&apply_lock);
1295} 1332}
1296 1333
1334static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
1335 const struct dss_lcd_mgr_config *config)
1336{
1337 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1338
1339 mp->lcd_config = *config;
1340 mp->extra_info_dirty = true;
1341}
1342
1343void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
1344 const struct dss_lcd_mgr_config *config)
1345{
1346 unsigned long flags;
1347 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1348
1349 mutex_lock(&apply_lock);
1350
1351 if (mp->enabled) {
1352 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
1353 mgr->name);
1354 goto out;
1355 }
1356
1357 spin_lock_irqsave(&data_lock, flags);
1358
1359 dss_apply_mgr_lcd_config(mgr, config);
1360
1361 dss_write_regs();
1362 dss_set_go_bits();
1363
1364 spin_unlock_irqrestore(&data_lock, flags);
1365
1366 wait_pending_extra_info_updates();
1367
1368out:
1369 mutex_unlock(&apply_lock);
1370}
1371
1297int dss_ovl_set_info(struct omap_overlay *ovl, 1372int dss_ovl_set_info(struct omap_overlay *ovl,
1298 struct omap_overlay_info *info) 1373 struct omap_overlay_info *info)
1299{ 1374{
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 397d4eee11bb..5b289c5f695b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -119,6 +119,97 @@ enum omap_color_component {
119 DISPC_COLOR_COMPONENT_UV = 1 << 1, 119 DISPC_COLOR_COMPONENT_UV = 1 << 1,
120}; 120};
121 121
122enum mgr_reg_fields {
123 DISPC_MGR_FLD_ENABLE,
124 DISPC_MGR_FLD_STNTFT,
125 DISPC_MGR_FLD_GO,
126 DISPC_MGR_FLD_TFTDATALINES,
127 DISPC_MGR_FLD_STALLMODE,
128 DISPC_MGR_FLD_TCKENABLE,
129 DISPC_MGR_FLD_TCKSELECTION,
130 DISPC_MGR_FLD_CPR,
131 DISPC_MGR_FLD_FIFOHANDCHECK,
132 /* used to maintain a count of the above fields */
133 DISPC_MGR_FLD_NUM,
134};
135
136static const struct {
137 const char *name;
138 u32 vsync_irq;
139 u32 framedone_irq;
140 u32 sync_lost_irq;
141 struct reg_field reg_desc[DISPC_MGR_FLD_NUM];
142} mgr_desc[] = {
143 [OMAP_DSS_CHANNEL_LCD] = {
144 .name = "LCD",
145 .vsync_irq = DISPC_IRQ_VSYNC,
146 .framedone_irq = DISPC_IRQ_FRAMEDONE,
147 .sync_lost_irq = DISPC_IRQ_SYNC_LOST,
148 .reg_desc = {
149 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 0, 0 },
150 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL, 3, 3 },
151 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL, 5, 5 },
152 [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL, 9, 8 },
153 [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL, 11, 11 },
154 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG, 10, 10 },
155 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG, 11, 11 },
156 [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG, 15, 15 },
157 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG, 16, 16 },
158 },
159 },
160 [OMAP_DSS_CHANNEL_DIGIT] = {
161 .name = "DIGIT",
162 .vsync_irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN,
163 .framedone_irq = 0,
164 .sync_lost_irq = DISPC_IRQ_SYNC_LOST_DIGIT,
165 .reg_desc = {
166 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 1, 1 },
167 [DISPC_MGR_FLD_STNTFT] = { },
168 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL, 6, 6 },
169 [DISPC_MGR_FLD_TFTDATALINES] = { },
170 [DISPC_MGR_FLD_STALLMODE] = { },
171 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG, 12, 12 },
172 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG, 13, 13 },
173 [DISPC_MGR_FLD_CPR] = { },
174 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG, 16, 16 },
175 },
176 },
177 [OMAP_DSS_CHANNEL_LCD2] = {
178 .name = "LCD2",
179 .vsync_irq = DISPC_IRQ_VSYNC2,
180 .framedone_irq = DISPC_IRQ_FRAMEDONE2,
181 .sync_lost_irq = DISPC_IRQ_SYNC_LOST2,
182 .reg_desc = {
183 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL2, 0, 0 },
184 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL2, 3, 3 },
185 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL2, 5, 5 },
186 [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL2, 9, 8 },
187 [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL2, 11, 11 },
188 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG2, 10, 10 },
189 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG2, 11, 11 },
190 [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG2, 15, 15 },
191 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG2, 16, 16 },
192 },
193 },
194 [OMAP_DSS_CHANNEL_LCD3] = {
195 .name = "LCD3",
196 .vsync_irq = DISPC_IRQ_VSYNC3,
197 .framedone_irq = DISPC_IRQ_FRAMEDONE3,
198 .sync_lost_irq = DISPC_IRQ_SYNC_LOST3,
199 .reg_desc = {
200 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL3, 0, 0 },
201 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL3, 3, 3 },
202 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL3, 5, 5 },
203 [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL3, 9, 8 },
204 [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL3, 11, 11 },
205 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG3, 10, 10 },
206 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG3, 11, 11 },
207 [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG3, 15, 15 },
208 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG3, 16, 16 },
209 },
210 },
211};
212
122static void _omap_dispc_set_irqs(void); 213static void _omap_dispc_set_irqs(void);
123 214
124static inline void dispc_write_reg(const u16 idx, u32 val) 215static inline void dispc_write_reg(const u16 idx, u32 val)
@@ -131,6 +222,18 @@ static inline u32 dispc_read_reg(const u16 idx)
131 return __raw_readl(dispc.base + idx); 222 return __raw_readl(dispc.base + idx);
132} 223}
133 224
225static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
226{
227 const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
228 return REG_GET(rfld.reg, rfld.high, rfld.low);
229}
230
231static void mgr_fld_write(enum omap_channel channel,
232 enum mgr_reg_fields regfld, int val) {
233 const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
234 REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
235}
236
134#define SR(reg) \ 237#define SR(reg) \
135 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) 238 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
136#define RR(reg) \ 239#define RR(reg) \
@@ -153,6 +256,10 @@ static void dispc_save_context(void)
153 SR(CONTROL2); 256 SR(CONTROL2);
154 SR(CONFIG2); 257 SR(CONFIG2);
155 } 258 }
259 if (dss_has_feature(FEAT_MGR_LCD3)) {
260 SR(CONTROL3);
261 SR(CONFIG3);
262 }
156 263
157 for (i = 0; i < dss_feat_get_num_mgrs(); i++) { 264 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
158 SR(DEFAULT_COLOR(i)); 265 SR(DEFAULT_COLOR(i));
@@ -266,6 +373,8 @@ static void dispc_restore_context(void)
266 RR(GLOBAL_ALPHA); 373 RR(GLOBAL_ALPHA);
267 if (dss_has_feature(FEAT_MGR_LCD2)) 374 if (dss_has_feature(FEAT_MGR_LCD2))
268 RR(CONFIG2); 375 RR(CONFIG2);
376 if (dss_has_feature(FEAT_MGR_LCD3))
377 RR(CONFIG3);
269 378
270 for (i = 0; i < dss_feat_get_num_mgrs(); i++) { 379 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
271 RR(DEFAULT_COLOR(i)); 380 RR(DEFAULT_COLOR(i));
@@ -351,6 +460,8 @@ static void dispc_restore_context(void)
351 RR(CONTROL); 460 RR(CONTROL);
352 if (dss_has_feature(FEAT_MGR_LCD2)) 461 if (dss_has_feature(FEAT_MGR_LCD2))
353 RR(CONTROL2); 462 RR(CONTROL2);
463 if (dss_has_feature(FEAT_MGR_LCD3))
464 RR(CONTROL3);
354 /* clear spurious SYNC_LOST_DIGIT interrupts */ 465 /* clear spurious SYNC_LOST_DIGIT interrupts */
355 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 466 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
356 467
@@ -387,101 +498,41 @@ void dispc_runtime_put(void)
387 WARN_ON(r < 0 && r != -ENOSYS); 498 WARN_ON(r < 0 && r != -ENOSYS);
388} 499}
389 500
390static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
391{
392 if (channel == OMAP_DSS_CHANNEL_LCD ||
393 channel == OMAP_DSS_CHANNEL_LCD2)
394 return true;
395 else
396 return false;
397}
398
399u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) 501u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
400{ 502{
401 switch (channel) { 503 return mgr_desc[channel].vsync_irq;
402 case OMAP_DSS_CHANNEL_LCD:
403 return DISPC_IRQ_VSYNC;
404 case OMAP_DSS_CHANNEL_LCD2:
405 return DISPC_IRQ_VSYNC2;
406 case OMAP_DSS_CHANNEL_DIGIT:
407 return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
408 default:
409 BUG();
410 return 0;
411 }
412} 504}
413 505
414u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) 506u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
415{ 507{
416 switch (channel) { 508 return mgr_desc[channel].framedone_irq;
417 case OMAP_DSS_CHANNEL_LCD:
418 return DISPC_IRQ_FRAMEDONE;
419 case OMAP_DSS_CHANNEL_LCD2:
420 return DISPC_IRQ_FRAMEDONE2;
421 case OMAP_DSS_CHANNEL_DIGIT:
422 return 0;
423 default:
424 BUG();
425 return 0;
426 }
427} 509}
428 510
429bool dispc_mgr_go_busy(enum omap_channel channel) 511bool dispc_mgr_go_busy(enum omap_channel channel)
430{ 512{
431 int bit; 513 return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
432
433 if (dispc_mgr_is_lcd(channel))
434 bit = 5; /* GOLCD */
435 else
436 bit = 6; /* GODIGIT */
437
438 if (channel == OMAP_DSS_CHANNEL_LCD2)
439 return REG_GET(DISPC_CONTROL2, bit, bit) == 1;
440 else
441 return REG_GET(DISPC_CONTROL, bit, bit) == 1;
442} 514}
443 515
444void dispc_mgr_go(enum omap_channel channel) 516void dispc_mgr_go(enum omap_channel channel)
445{ 517{
446 int bit;
447 bool enable_bit, go_bit; 518 bool enable_bit, go_bit;
448 519
449 if (dispc_mgr_is_lcd(channel))
450 bit = 0; /* LCDENABLE */
451 else
452 bit = 1; /* DIGITALENABLE */
453
454 /* if the channel is not enabled, we don't need GO */ 520 /* if the channel is not enabled, we don't need GO */
455 if (channel == OMAP_DSS_CHANNEL_LCD2) 521 enable_bit = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE) == 1;
456 enable_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
457 else
458 enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
459 522
460 if (!enable_bit) 523 if (!enable_bit)
461 return; 524 return;
462 525
463 if (dispc_mgr_is_lcd(channel)) 526 go_bit = mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
464 bit = 5; /* GOLCD */
465 else
466 bit = 6; /* GODIGIT */
467
468 if (channel == OMAP_DSS_CHANNEL_LCD2)
469 go_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
470 else
471 go_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
472 527
473 if (go_bit) { 528 if (go_bit) {
474 DSSERR("GO bit not down for channel %d\n", channel); 529 DSSERR("GO bit not down for channel %d\n", channel);
475 return; 530 return;
476 } 531 }
477 532
478 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : 533 DSSDBG("GO %s\n", mgr_desc[channel].name);
479 (channel == OMAP_DSS_CHANNEL_LCD2 ? "LCD2" : "DIGIT"));
480 534
481 if (channel == OMAP_DSS_CHANNEL_LCD2) 535 mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
482 REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit);
483 else
484 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
485} 536}
486 537
487static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) 538static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
@@ -832,6 +883,15 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
832 chan = 0; 883 chan = 0;
833 chan2 = 1; 884 chan2 = 1;
834 break; 885 break;
886 case OMAP_DSS_CHANNEL_LCD3:
887 if (dss_has_feature(FEAT_MGR_LCD3)) {
888 chan = 0;
889 chan2 = 2;
890 } else {
891 BUG();
892 return;
893 }
894 break;
835 default: 895 default:
836 BUG(); 896 BUG();
837 return; 897 return;
@@ -867,7 +927,14 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
867 927
868 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); 928 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
869 929
870 if (dss_has_feature(FEAT_MGR_LCD2)) { 930 if (dss_has_feature(FEAT_MGR_LCD3)) {
931 if (FLD_GET(val, 31, 30) == 0)
932 channel = FLD_GET(val, shift, shift);
933 else if (FLD_GET(val, 31, 30) == 1)
934 channel = OMAP_DSS_CHANNEL_LCD2;
935 else
936 channel = OMAP_DSS_CHANNEL_LCD3;
937 } else if (dss_has_feature(FEAT_MGR_LCD2)) {
871 if (FLD_GET(val, 31, 30) == 0) 938 if (FLD_GET(val, 31, 30) == 0)
872 channel = FLD_GET(val, shift, shift); 939 channel = FLD_GET(val, shift, shift);
873 else 940 else
@@ -922,16 +989,10 @@ void dispc_enable_gamma_table(bool enable)
922 989
923static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) 990static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
924{ 991{
925 u16 reg; 992 if (channel == OMAP_DSS_CHANNEL_DIGIT)
926
927 if (channel == OMAP_DSS_CHANNEL_LCD)
928 reg = DISPC_CONFIG;
929 else if (channel == OMAP_DSS_CHANNEL_LCD2)
930 reg = DISPC_CONFIG2;
931 else
932 return; 993 return;
933 994
934 REG_FLD_MOD(reg, enable, 15, 15); 995 mgr_fld_write(channel, DISPC_MGR_FLD_CPR, enable);
935} 996}
936 997
937static void dispc_mgr_set_cpr_coef(enum omap_channel channel, 998static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
@@ -939,7 +1000,7 @@ static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
939{ 1000{
940 u32 coef_r, coef_g, coef_b; 1001 u32 coef_r, coef_g, coef_b;
941 1002
942 if (!dispc_mgr_is_lcd(channel)) 1003 if (!dss_mgr_is_lcd(channel))
943 return; 1004 return;
944 1005
945 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) | 1006 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) |
@@ -1798,7 +1859,7 @@ static int check_horiz_timing_omap3(enum omap_channel channel,
1798 1859
1799 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; 1860 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
1800 pclk = dispc_mgr_pclk_rate(channel); 1861 pclk = dispc_mgr_pclk_rate(channel);
1801 if (dispc_mgr_is_lcd(channel)) 1862 if (dss_mgr_is_lcd(channel))
1802 lclk = dispc_mgr_lclk_rate(channel); 1863 lclk = dispc_mgr_lclk_rate(channel);
1803 else 1864 else
1804 lclk = dispc_fclk_rate(); 1865 lclk = dispc_fclk_rate();
@@ -2086,8 +2147,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
2086} 2147}
2087 2148
2088int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 2149int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
2089 bool ilace, bool replication, 2150 bool replication, const struct omap_video_timings *mgr_timings)
2090 const struct omap_video_timings *mgr_timings)
2091{ 2151{
2092 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 2152 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
2093 bool five_taps = true; 2153 bool five_taps = true;
@@ -2103,6 +2163,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
2103 u16 out_width, out_height; 2163 u16 out_width, out_height;
2104 enum omap_channel channel; 2164 enum omap_channel channel;
2105 int x_predecim = 1, y_predecim = 1; 2165 int x_predecim = 1, y_predecim = 1;
2166 bool ilace = mgr_timings->interlace;
2106 2167
2107 channel = dispc_ovl_get_channel_out(plane); 2168 channel = dispc_ovl_get_channel_out(plane);
2108 2169
@@ -2254,14 +2315,9 @@ static void dispc_disable_isr(void *data, u32 mask)
2254 2315
2255static void _enable_lcd_out(enum omap_channel channel, bool enable) 2316static void _enable_lcd_out(enum omap_channel channel, bool enable)
2256{ 2317{
2257 if (channel == OMAP_DSS_CHANNEL_LCD2) { 2318 mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
2258 REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0); 2319 /* flush posted write */
2259 /* flush posted write */ 2320 mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2260 dispc_read_reg(DISPC_CONTROL2);
2261 } else {
2262 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
2263 dispc_read_reg(DISPC_CONTROL);
2264 }
2265} 2321}
2266 2322
2267static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable) 2323static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
@@ -2274,12 +2330,9 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
2274 /* When we disable LCD output, we need to wait until frame is done. 2330 /* When we disable LCD output, we need to wait until frame is done.
2275 * Otherwise the DSS is still working, and turning off the clocks 2331 * Otherwise the DSS is still working, and turning off the clocks
2276 * prevents DSS from going to OFF mode */ 2332 * prevents DSS from going to OFF mode */
2277 is_on = channel == OMAP_DSS_CHANNEL_LCD2 ? 2333 is_on = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2278 REG_GET(DISPC_CONTROL2, 0, 0) :
2279 REG_GET(DISPC_CONTROL, 0, 0);
2280 2334
2281 irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 : 2335 irq = mgr_desc[channel].framedone_irq;
2282 DISPC_IRQ_FRAMEDONE;
2283 2336
2284 if (!enable && is_on) { 2337 if (!enable && is_on) {
2285 init_completion(&frame_done_completion); 2338 init_completion(&frame_done_completion);
@@ -2384,21 +2437,12 @@ static void dispc_mgr_enable_digit_out(bool enable)
2384 2437
2385bool dispc_mgr_is_enabled(enum omap_channel channel) 2438bool dispc_mgr_is_enabled(enum omap_channel channel)
2386{ 2439{
2387 if (channel == OMAP_DSS_CHANNEL_LCD) 2440 return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2388 return !!REG_GET(DISPC_CONTROL, 0, 0);
2389 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2390 return !!REG_GET(DISPC_CONTROL, 1, 1);
2391 else if (channel == OMAP_DSS_CHANNEL_LCD2)
2392 return !!REG_GET(DISPC_CONTROL2, 0, 0);
2393 else {
2394 BUG();
2395 return false;
2396 }
2397} 2441}
2398 2442
2399void dispc_mgr_enable(enum omap_channel channel, bool enable) 2443void dispc_mgr_enable(enum omap_channel channel, bool enable)
2400{ 2444{
2401 if (dispc_mgr_is_lcd(channel)) 2445 if (dss_mgr_is_lcd(channel))
2402 dispc_mgr_enable_lcd_out(channel, enable); 2446 dispc_mgr_enable_lcd_out(channel, enable);
2403 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 2447 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2404 dispc_mgr_enable_digit_out(enable); 2448 dispc_mgr_enable_digit_out(enable);
@@ -2432,36 +2476,13 @@ void dispc_pck_free_enable(bool enable)
2432 2476
2433void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable) 2477void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
2434{ 2478{
2435 if (channel == OMAP_DSS_CHANNEL_LCD2) 2479 mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
2436 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
2437 else
2438 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
2439} 2480}
2440 2481
2441 2482
2442void dispc_mgr_set_lcd_display_type(enum omap_channel channel, 2483void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
2443 enum omap_lcd_display_type type)
2444{ 2484{
2445 int mode; 2485 mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, 1);
2446
2447 switch (type) {
2448 case OMAP_DSS_LCD_DISPLAY_STN:
2449 mode = 0;
2450 break;
2451
2452 case OMAP_DSS_LCD_DISPLAY_TFT:
2453 mode = 1;
2454 break;
2455
2456 default:
2457 BUG();
2458 return;
2459 }
2460
2461 if (channel == OMAP_DSS_CHANNEL_LCD2)
2462 REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
2463 else
2464 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
2465} 2486}
2466 2487
2467void dispc_set_loadmode(enum omap_dss_load_mode mode) 2488void dispc_set_loadmode(enum omap_dss_load_mode mode)
@@ -2479,24 +2500,14 @@ static void dispc_mgr_set_trans_key(enum omap_channel ch,
2479 enum omap_dss_trans_key_type type, 2500 enum omap_dss_trans_key_type type,
2480 u32 trans_key) 2501 u32 trans_key)
2481{ 2502{
2482 if (ch == OMAP_DSS_CHANNEL_LCD) 2503 mgr_fld_write(ch, DISPC_MGR_FLD_TCKSELECTION, type);
2483 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
2484 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2485 REG_FLD_MOD(DISPC_CONFIG, type, 13, 13);
2486 else /* OMAP_DSS_CHANNEL_LCD2 */
2487 REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);
2488 2504
2489 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); 2505 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
2490} 2506}
2491 2507
2492static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) 2508static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
2493{ 2509{
2494 if (ch == OMAP_DSS_CHANNEL_LCD) 2510 mgr_fld_write(ch, DISPC_MGR_FLD_TCKENABLE, enable);
2495 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
2496 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2497 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
2498 else /* OMAP_DSS_CHANNEL_LCD2 */
2499 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
2500} 2511}
2501 2512
2502static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, 2513static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
@@ -2547,10 +2558,7 @@ void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2547 return; 2558 return;
2548 } 2559 }
2549 2560
2550 if (channel == OMAP_DSS_CHANNEL_LCD2) 2561 mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code);
2551 REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
2552 else
2553 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
2554} 2562}
2555 2563
2556void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode) 2564void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
@@ -2584,10 +2592,7 @@ void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
2584 2592
2585void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) 2593void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
2586{ 2594{
2587 if (channel == OMAP_DSS_CHANNEL_LCD2) 2595 mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
2588 REG_FLD_MOD(DISPC_CONTROL2, enable, 11, 11);
2589 else
2590 REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11);
2591} 2596}
2592 2597
2593static bool _dispc_mgr_size_ok(u16 width, u16 height) 2598static bool _dispc_mgr_size_ok(u16 width, u16 height)
@@ -2627,7 +2632,7 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
2627 2632
2628 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); 2633 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
2629 2634
2630 if (dispc_mgr_is_lcd(channel)) 2635 if (dss_mgr_is_lcd(channel))
2631 timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, 2636 timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw,
2632 timings->hfp, timings->hbp, 2637 timings->hfp, timings->hbp,
2633 timings->vsw, timings->vfp, 2638 timings->vsw, timings->vfp,
@@ -2637,9 +2642,16 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
2637} 2642}
2638 2643
2639static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, 2644static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
2640 int hfp, int hbp, int vsw, int vfp, int vbp) 2645 int hfp, int hbp, int vsw, int vfp, int vbp,
2646 enum omap_dss_signal_level vsync_level,
2647 enum omap_dss_signal_level hsync_level,
2648 enum omap_dss_signal_edge data_pclk_edge,
2649 enum omap_dss_signal_level de_level,
2650 enum omap_dss_signal_edge sync_pclk_edge)
2651
2641{ 2652{
2642 u32 timing_h, timing_v; 2653 u32 timing_h, timing_v, l;
2654 bool onoff, rf, ipc;
2643 2655
2644 if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { 2656 if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
2645 timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) | 2657 timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
@@ -2657,6 +2669,44 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
2657 2669
2658 dispc_write_reg(DISPC_TIMING_H(channel), timing_h); 2670 dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
2659 dispc_write_reg(DISPC_TIMING_V(channel), timing_v); 2671 dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
2672
2673 switch (data_pclk_edge) {
2674 case OMAPDSS_DRIVE_SIG_RISING_EDGE:
2675 ipc = false;
2676 break;
2677 case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
2678 ipc = true;
2679 break;
2680 case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
2681 default:
2682 BUG();
2683 }
2684
2685 switch (sync_pclk_edge) {
2686 case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
2687 onoff = false;
2688 rf = false;
2689 break;
2690 case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
2691 onoff = true;
2692 rf = false;
2693 break;
2694 case OMAPDSS_DRIVE_SIG_RISING_EDGE:
2695 onoff = true;
2696 rf = true;
2697 break;
2698 default:
2699 BUG();
2700 };
2701
2702 l = dispc_read_reg(DISPC_POL_FREQ(channel));
2703 l |= FLD_VAL(onoff, 17, 17);
2704 l |= FLD_VAL(rf, 16, 16);
2705 l |= FLD_VAL(de_level, 15, 15);
2706 l |= FLD_VAL(ipc, 14, 14);
2707 l |= FLD_VAL(hsync_level, 13, 13);
2708 l |= FLD_VAL(vsync_level, 12, 12);
2709 dispc_write_reg(DISPC_POL_FREQ(channel), l);
2660} 2710}
2661 2711
2662/* change name to mode? */ 2712/* change name to mode? */
@@ -2674,9 +2724,10 @@ void dispc_mgr_set_timings(enum omap_channel channel,
2674 return; 2724 return;
2675 } 2725 }
2676 2726
2677 if (dispc_mgr_is_lcd(channel)) { 2727 if (dss_mgr_is_lcd(channel)) {
2678 _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw, 2728 _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw,
2679 t.vfp, t.vbp); 2729 t.vfp, t.vbp, t.vsync_level, t.hsync_level,
2730 t.data_pclk_edge, t.de_level, t.sync_pclk_edge);
2680 2731
2681 xtot = t.x_res + t.hfp + t.hsw + t.hbp; 2732 xtot = t.x_res + t.hfp + t.hsw + t.hbp;
2682 ytot = t.y_res + t.vfp + t.vsw + t.vbp; 2733 ytot = t.y_res + t.vfp + t.vsw + t.vbp;
@@ -2687,14 +2738,13 @@ void dispc_mgr_set_timings(enum omap_channel channel,
2687 DSSDBG("pck %u\n", timings->pixel_clock); 2738 DSSDBG("pck %u\n", timings->pixel_clock);
2688 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", 2739 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
2689 t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp); 2740 t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp);
2741 DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n",
2742 t.vsync_level, t.hsync_level, t.data_pclk_edge,
2743 t.de_level, t.sync_pclk_edge);
2690 2744
2691 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2745 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
2692 } else { 2746 } else {
2693 enum dss_hdmi_venc_clk_source_select source; 2747 if (t.interlace == true)
2694
2695 source = dss_get_hdmi_venc_clk_source();
2696
2697 if (source == DSS_VENC_TV_CLK)
2698 t.y_res /= 2; 2748 t.y_res /= 2;
2699 } 2749 }
2700 2750
@@ -2780,7 +2830,7 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
2780{ 2830{
2781 unsigned long r; 2831 unsigned long r;
2782 2832
2783 if (dispc_mgr_is_lcd(channel)) { 2833 if (dss_mgr_is_lcd(channel)) {
2784 int pcd; 2834 int pcd;
2785 u32 l; 2835 u32 l;
2786 2836
@@ -2821,12 +2871,32 @@ unsigned long dispc_core_clk_rate(void)
2821 return fclk / lcd; 2871 return fclk / lcd;
2822} 2872}
2823 2873
2824void dispc_dump_clocks(struct seq_file *s) 2874static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
2825{ 2875{
2826 int lcd, pcd; 2876 int lcd, pcd;
2877 enum omap_dss_clk_source lcd_clk_src;
2878
2879 seq_printf(s, "- %s -\n", mgr_desc[channel].name);
2880
2881 lcd_clk_src = dss_get_lcd_clk_source(channel);
2882
2883 seq_printf(s, "%s clk source = %s (%s)\n", mgr_desc[channel].name,
2884 dss_get_generic_clk_source_name(lcd_clk_src),
2885 dss_feat_get_clk_source_name(lcd_clk_src));
2886
2887 dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd);
2888
2889 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2890 dispc_mgr_lclk_rate(channel), lcd);
2891 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2892 dispc_mgr_pclk_rate(channel), pcd);
2893}
2894
2895void dispc_dump_clocks(struct seq_file *s)
2896{
2897 int lcd;
2827 u32 l; 2898 u32 l;
2828 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); 2899 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2829 enum omap_dss_clk_source lcd_clk_src;
2830 2900
2831 if (dispc_runtime_get()) 2901 if (dispc_runtime_get())
2832 return; 2902 return;
@@ -2847,36 +2917,13 @@ void dispc_dump_clocks(struct seq_file *s)
2847 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2917 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2848 (dispc_fclk_rate()/lcd), lcd); 2918 (dispc_fclk_rate()/lcd), lcd);
2849 } 2919 }
2850 seq_printf(s, "- LCD1 -\n");
2851
2852 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
2853
2854 seq_printf(s, "lcd1_clk source = %s (%s)\n",
2855 dss_get_generic_clk_source_name(lcd_clk_src),
2856 dss_feat_get_clk_source_name(lcd_clk_src));
2857
2858 dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2859
2860 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2861 dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd);
2862 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2863 dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd);
2864 if (dss_has_feature(FEAT_MGR_LCD2)) {
2865 seq_printf(s, "- LCD2 -\n");
2866
2867 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
2868 2920
2869 seq_printf(s, "lcd2_clk source = %s (%s)\n", 2921 dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD);
2870 dss_get_generic_clk_source_name(lcd_clk_src),
2871 dss_feat_get_clk_source_name(lcd_clk_src));
2872 2922
2873 dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); 2923 if (dss_has_feature(FEAT_MGR_LCD2))
2874 2924 dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD2);
2875 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2925 if (dss_has_feature(FEAT_MGR_LCD3))
2876 dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd); 2926 dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3);
2877 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2878 dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
2879 }
2880 2927
2881 dispc_runtime_put(); 2928 dispc_runtime_put();
2882} 2929}
@@ -2929,6 +2976,12 @@ void dispc_dump_irqs(struct seq_file *s)
2929 PIS(ACBIAS_COUNT_STAT2); 2976 PIS(ACBIAS_COUNT_STAT2);
2930 PIS(SYNC_LOST2); 2977 PIS(SYNC_LOST2);
2931 } 2978 }
2979 if (dss_has_feature(FEAT_MGR_LCD3)) {
2980 PIS(FRAMEDONE3);
2981 PIS(VSYNC3);
2982 PIS(ACBIAS_COUNT_STAT3);
2983 PIS(SYNC_LOST3);
2984 }
2932#undef PIS 2985#undef PIS
2933} 2986}
2934#endif 2987#endif
@@ -2940,6 +2993,7 @@ static void dispc_dump_regs(struct seq_file *s)
2940 [OMAP_DSS_CHANNEL_LCD] = "LCD", 2993 [OMAP_DSS_CHANNEL_LCD] = "LCD",
2941 [OMAP_DSS_CHANNEL_DIGIT] = "TV", 2994 [OMAP_DSS_CHANNEL_DIGIT] = "TV",
2942 [OMAP_DSS_CHANNEL_LCD2] = "LCD2", 2995 [OMAP_DSS_CHANNEL_LCD2] = "LCD2",
2996 [OMAP_DSS_CHANNEL_LCD3] = "LCD3",
2943 }; 2997 };
2944 const char *ovl_names[] = { 2998 const char *ovl_names[] = {
2945 [OMAP_DSS_GFX] = "GFX", 2999 [OMAP_DSS_GFX] = "GFX",
@@ -2972,6 +3026,10 @@ static void dispc_dump_regs(struct seq_file *s)
2972 DUMPREG(DISPC_CONTROL2); 3026 DUMPREG(DISPC_CONTROL2);
2973 DUMPREG(DISPC_CONFIG2); 3027 DUMPREG(DISPC_CONFIG2);
2974 } 3028 }
3029 if (dss_has_feature(FEAT_MGR_LCD3)) {
3030 DUMPREG(DISPC_CONTROL3);
3031 DUMPREG(DISPC_CONFIG3);
3032 }
2975 3033
2976#undef DUMPREG 3034#undef DUMPREG
2977 3035
@@ -3093,41 +3151,8 @@ static void dispc_dump_regs(struct seq_file *s)
3093#undef DUMPREG 3151#undef DUMPREG
3094} 3152}
3095 3153
3096static void _dispc_mgr_set_pol_freq(enum omap_channel channel, bool onoff,
3097 bool rf, bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi,
3098 u8 acb)
3099{
3100 u32 l = 0;
3101
3102 DSSDBG("onoff %d rf %d ieo %d ipc %d ihs %d ivs %d acbi %d acb %d\n",
3103 onoff, rf, ieo, ipc, ihs, ivs, acbi, acb);
3104
3105 l |= FLD_VAL(onoff, 17, 17);
3106 l |= FLD_VAL(rf, 16, 16);
3107 l |= FLD_VAL(ieo, 15, 15);
3108 l |= FLD_VAL(ipc, 14, 14);
3109 l |= FLD_VAL(ihs, 13, 13);
3110 l |= FLD_VAL(ivs, 12, 12);
3111 l |= FLD_VAL(acbi, 11, 8);
3112 l |= FLD_VAL(acb, 7, 0);
3113
3114 dispc_write_reg(DISPC_POL_FREQ(channel), l);
3115}
3116
3117void dispc_mgr_set_pol_freq(enum omap_channel channel,
3118 enum omap_panel_config config, u8 acbi, u8 acb)
3119{
3120 _dispc_mgr_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0,
3121 (config & OMAP_DSS_LCD_RF) != 0,
3122 (config & OMAP_DSS_LCD_IEO) != 0,
3123 (config & OMAP_DSS_LCD_IPC) != 0,
3124 (config & OMAP_DSS_LCD_IHS) != 0,
3125 (config & OMAP_DSS_LCD_IVS) != 0,
3126 acbi, acb);
3127}
3128
3129/* with fck as input clock rate, find dispc dividers that produce req_pck */ 3154/* with fck as input clock rate, find dispc dividers that produce req_pck */
3130void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 3155void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck,
3131 struct dispc_clock_info *cinfo) 3156 struct dispc_clock_info *cinfo)
3132{ 3157{
3133 u16 pcd_min, pcd_max; 3158 u16 pcd_min, pcd_max;
@@ -3138,9 +3163,6 @@ void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
3138 pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD); 3163 pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
3139 pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD); 3164 pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
3140 3165
3141 if (!is_tft)
3142 pcd_min = 3;
3143
3144 best_pck = 0; 3166 best_pck = 0;
3145 best_ld = 0; 3167 best_ld = 0;
3146 best_pd = 0; 3168 best_pd = 0;
@@ -3192,15 +3214,13 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
3192 return 0; 3214 return 0;
3193} 3215}
3194 3216
3195int dispc_mgr_set_clock_div(enum omap_channel channel, 3217void dispc_mgr_set_clock_div(enum omap_channel channel,
3196 struct dispc_clock_info *cinfo) 3218 struct dispc_clock_info *cinfo)
3197{ 3219{
3198 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); 3220 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
3199 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); 3221 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
3200 3222
3201 dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div); 3223 dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
3202
3203 return 0;
3204} 3224}
3205 3225
3206int dispc_mgr_get_clock_div(enum omap_channel channel, 3226int dispc_mgr_get_clock_div(enum omap_channel channel,
@@ -3354,6 +3374,8 @@ static void print_irq_status(u32 status)
3354 PIS(SYNC_LOST_DIGIT); 3374 PIS(SYNC_LOST_DIGIT);
3355 if (dss_has_feature(FEAT_MGR_LCD2)) 3375 if (dss_has_feature(FEAT_MGR_LCD2))
3356 PIS(SYNC_LOST2); 3376 PIS(SYNC_LOST2);
3377 if (dss_has_feature(FEAT_MGR_LCD3))
3378 PIS(SYNC_LOST3);
3357#undef PIS 3379#undef PIS
3358 3380
3359 printk("\n"); 3381 printk("\n");
@@ -3450,12 +3472,6 @@ static void dispc_error_worker(struct work_struct *work)
3450 DISPC_IRQ_VID3_FIFO_UNDERFLOW, 3472 DISPC_IRQ_VID3_FIFO_UNDERFLOW,
3451 }; 3473 };
3452 3474
3453 static const unsigned sync_lost_bits[] = {
3454 DISPC_IRQ_SYNC_LOST,
3455 DISPC_IRQ_SYNC_LOST_DIGIT,
3456 DISPC_IRQ_SYNC_LOST2,
3457 };
3458
3459 spin_lock_irqsave(&dispc.irq_lock, flags); 3475 spin_lock_irqsave(&dispc.irq_lock, flags);
3460 errors = dispc.error_irqs; 3476 errors = dispc.error_irqs;
3461 dispc.error_irqs = 0; 3477 dispc.error_irqs = 0;
@@ -3484,7 +3500,7 @@ static void dispc_error_worker(struct work_struct *work)
3484 unsigned bit; 3500 unsigned bit;
3485 3501
3486 mgr = omap_dss_get_overlay_manager(i); 3502 mgr = omap_dss_get_overlay_manager(i);
3487 bit = sync_lost_bits[i]; 3503 bit = mgr_desc[i].sync_lost_irq;
3488 3504
3489 if (bit & errors) { 3505 if (bit & errors) {
3490 struct omap_dss_device *dssdev = mgr->device; 3506 struct omap_dss_device *dssdev = mgr->device;
@@ -3603,6 +3619,8 @@ static void _omap_dispc_initialize_irq(void)
3603 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 3619 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
3604 if (dss_has_feature(FEAT_MGR_LCD2)) 3620 if (dss_has_feature(FEAT_MGR_LCD2))
3605 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; 3621 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
3622 if (dss_has_feature(FEAT_MGR_LCD3))
3623 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
3606 if (dss_feat_get_num_ovls() > 3) 3624 if (dss_feat_get_num_ovls() > 3)
3607 dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW; 3625 dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
3608 3626
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index f278080e1063..92d8a9be86fc 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -36,6 +36,8 @@
36#define DISPC_CONTROL2 0x0238 36#define DISPC_CONTROL2 0x0238
37#define DISPC_CONFIG2 0x0620 37#define DISPC_CONFIG2 0x0620
38#define DISPC_DIVISOR 0x0804 38#define DISPC_DIVISOR 0x0804
39#define DISPC_CONTROL3 0x0848
40#define DISPC_CONFIG3 0x084C
39 41
40/* DISPC overlay registers */ 42/* DISPC overlay registers */
41#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \ 43#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
@@ -118,6 +120,8 @@ static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel)
118 return 0x0050; 120 return 0x0050;
119 case OMAP_DSS_CHANNEL_LCD2: 121 case OMAP_DSS_CHANNEL_LCD2:
120 return 0x03AC; 122 return 0x03AC;
123 case OMAP_DSS_CHANNEL_LCD3:
124 return 0x0814;
121 default: 125 default:
122 BUG(); 126 BUG();
123 return 0; 127 return 0;
@@ -133,6 +137,8 @@ static inline u16 DISPC_TRANS_COLOR(enum omap_channel channel)
133 return 0x0058; 137 return 0x0058;
134 case OMAP_DSS_CHANNEL_LCD2: 138 case OMAP_DSS_CHANNEL_LCD2:
135 return 0x03B0; 139 return 0x03B0;
140 case OMAP_DSS_CHANNEL_LCD3:
141 return 0x0818;
136 default: 142 default:
137 BUG(); 143 BUG();
138 return 0; 144 return 0;
@@ -149,6 +155,8 @@ static inline u16 DISPC_TIMING_H(enum omap_channel channel)
149 return 0; 155 return 0;
150 case OMAP_DSS_CHANNEL_LCD2: 156 case OMAP_DSS_CHANNEL_LCD2:
151 return 0x0400; 157 return 0x0400;
158 case OMAP_DSS_CHANNEL_LCD3:
159 return 0x0840;
152 default: 160 default:
153 BUG(); 161 BUG();
154 return 0; 162 return 0;
@@ -165,6 +173,8 @@ static inline u16 DISPC_TIMING_V(enum omap_channel channel)
165 return 0; 173 return 0;
166 case OMAP_DSS_CHANNEL_LCD2: 174 case OMAP_DSS_CHANNEL_LCD2:
167 return 0x0404; 175 return 0x0404;
176 case OMAP_DSS_CHANNEL_LCD3:
177 return 0x0844;
168 default: 178 default:
169 BUG(); 179 BUG();
170 return 0; 180 return 0;
@@ -181,6 +191,8 @@ static inline u16 DISPC_POL_FREQ(enum omap_channel channel)
181 return 0; 191 return 0;
182 case OMAP_DSS_CHANNEL_LCD2: 192 case OMAP_DSS_CHANNEL_LCD2:
183 return 0x0408; 193 return 0x0408;
194 case OMAP_DSS_CHANNEL_LCD3:
195 return 0x083C;
184 default: 196 default:
185 BUG(); 197 BUG();
186 return 0; 198 return 0;
@@ -197,6 +209,8 @@ static inline u16 DISPC_DIVISORo(enum omap_channel channel)
197 return 0; 209 return 0;
198 case OMAP_DSS_CHANNEL_LCD2: 210 case OMAP_DSS_CHANNEL_LCD2:
199 return 0x040C; 211 return 0x040C;
212 case OMAP_DSS_CHANNEL_LCD3:
213 return 0x0838;
200 default: 214 default:
201 BUG(); 215 BUG();
202 return 0; 216 return 0;
@@ -213,6 +227,8 @@ static inline u16 DISPC_SIZE_MGR(enum omap_channel channel)
213 return 0x0078; 227 return 0x0078;
214 case OMAP_DSS_CHANNEL_LCD2: 228 case OMAP_DSS_CHANNEL_LCD2:
215 return 0x03CC; 229 return 0x03CC;
230 case OMAP_DSS_CHANNEL_LCD3:
231 return 0x0834;
216 default: 232 default:
217 BUG(); 233 BUG();
218 return 0; 234 return 0;
@@ -229,6 +245,8 @@ static inline u16 DISPC_DATA_CYCLE1(enum omap_channel channel)
229 return 0; 245 return 0;
230 case OMAP_DSS_CHANNEL_LCD2: 246 case OMAP_DSS_CHANNEL_LCD2:
231 return 0x03C0; 247 return 0x03C0;
248 case OMAP_DSS_CHANNEL_LCD3:
249 return 0x0828;
232 default: 250 default:
233 BUG(); 251 BUG();
234 return 0; 252 return 0;
@@ -245,6 +263,8 @@ static inline u16 DISPC_DATA_CYCLE2(enum omap_channel channel)
245 return 0; 263 return 0;
246 case OMAP_DSS_CHANNEL_LCD2: 264 case OMAP_DSS_CHANNEL_LCD2:
247 return 0x03C4; 265 return 0x03C4;
266 case OMAP_DSS_CHANNEL_LCD3:
267 return 0x082C;
248 default: 268 default:
249 BUG(); 269 BUG();
250 return 0; 270 return 0;
@@ -261,6 +281,8 @@ static inline u16 DISPC_DATA_CYCLE3(enum omap_channel channel)
261 return 0; 281 return 0;
262 case OMAP_DSS_CHANNEL_LCD2: 282 case OMAP_DSS_CHANNEL_LCD2:
263 return 0x03C8; 283 return 0x03C8;
284 case OMAP_DSS_CHANNEL_LCD3:
285 return 0x0830;
264 default: 286 default:
265 BUG(); 287 BUG();
266 return 0; 288 return 0;
@@ -277,6 +299,8 @@ static inline u16 DISPC_CPR_COEF_R(enum omap_channel channel)
277 return 0; 299 return 0;
278 case OMAP_DSS_CHANNEL_LCD2: 300 case OMAP_DSS_CHANNEL_LCD2:
279 return 0x03BC; 301 return 0x03BC;
302 case OMAP_DSS_CHANNEL_LCD3:
303 return 0x0824;
280 default: 304 default:
281 BUG(); 305 BUG();
282 return 0; 306 return 0;
@@ -293,6 +317,8 @@ static inline u16 DISPC_CPR_COEF_G(enum omap_channel channel)
293 return 0; 317 return 0;
294 case OMAP_DSS_CHANNEL_LCD2: 318 case OMAP_DSS_CHANNEL_LCD2:
295 return 0x03B8; 319 return 0x03B8;
320 case OMAP_DSS_CHANNEL_LCD3:
321 return 0x0820;
296 default: 322 default:
297 BUG(); 323 BUG();
298 return 0; 324 return 0;
@@ -309,6 +335,8 @@ static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel)
309 return 0; 335 return 0;
310 case OMAP_DSS_CHANNEL_LCD2: 336 case OMAP_DSS_CHANNEL_LCD2:
311 return 0x03B4; 337 return 0x03B4;
338 case OMAP_DSS_CHANNEL_LCD3:
339 return 0x081C;
312 default: 340 default:
313 BUG(); 341 BUG();
314 return 0; 342 return 0;
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 249010630370..5bd957e85505 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -116,7 +116,7 @@ static ssize_t display_timings_store(struct device *dev,
116 struct device_attribute *attr, const char *buf, size_t size) 116 struct device_attribute *attr, const char *buf, size_t size)
117{ 117{
118 struct omap_dss_device *dssdev = to_dss_device(dev); 118 struct omap_dss_device *dssdev = to_dss_device(dev);
119 struct omap_video_timings t; 119 struct omap_video_timings t = dssdev->panel.timings;
120 int r, found; 120 int r, found;
121 121
122 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings) 122 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
@@ -316,44 +316,6 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
316} 316}
317EXPORT_SYMBOL(omapdss_default_get_timings); 317EXPORT_SYMBOL(omapdss_default_get_timings);
318 318
319/* Checks if replication logic should be used. Only use for active matrix,
320 * when overlay is in RGB12U or RGB16 mode, and LCD interface is
321 * 18bpp or 24bpp */
322bool dss_use_replication(struct omap_dss_device *dssdev,
323 enum omap_color_mode mode)
324{
325 int bpp;
326
327 if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
328 return false;
329
330 if (dssdev->type == OMAP_DISPLAY_TYPE_DPI &&
331 (dssdev->panel.config & OMAP_DSS_LCD_TFT) == 0)
332 return false;
333
334 switch (dssdev->type) {
335 case OMAP_DISPLAY_TYPE_DPI:
336 bpp = dssdev->phy.dpi.data_lines;
337 break;
338 case OMAP_DISPLAY_TYPE_HDMI:
339 case OMAP_DISPLAY_TYPE_VENC:
340 case OMAP_DISPLAY_TYPE_SDI:
341 bpp = 24;
342 break;
343 case OMAP_DISPLAY_TYPE_DBI:
344 bpp = dssdev->ctrl.pixel_size;
345 break;
346 case OMAP_DISPLAY_TYPE_DSI:
347 bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
348 break;
349 default:
350 BUG();
351 return false;
352 }
353
354 return bpp > 16;
355}
356
357void dss_init_device(struct platform_device *pdev, 319void dss_init_device(struct platform_device *pdev,
358 struct omap_dss_device *dssdev) 320 struct omap_dss_device *dssdev)
359{ 321{
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 8c2056c9537b..3266be23fc0d 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -38,6 +38,8 @@
38static struct { 38static struct {
39 struct regulator *vdds_dsi_reg; 39 struct regulator *vdds_dsi_reg;
40 struct platform_device *dsidev; 40 struct platform_device *dsidev;
41
42 struct dss_lcd_mgr_config mgr_config;
41} dpi; 43} dpi;
42 44
43static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) 45static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -64,7 +66,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
64 return false; 66 return false;
65} 67}
66 68
67static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, 69static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
68 unsigned long pck_req, unsigned long *fck, int *lck_div, 70 unsigned long pck_req, unsigned long *fck, int *lck_div,
69 int *pck_div) 71 int *pck_div)
70{ 72{
@@ -72,8 +74,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
72 struct dispc_clock_info dispc_cinfo; 74 struct dispc_clock_info dispc_cinfo;
73 int r; 75 int r;
74 76
75 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req, 77 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, pck_req, &dsi_cinfo,
76 &dsi_cinfo, &dispc_cinfo); 78 &dispc_cinfo);
77 if (r) 79 if (r)
78 return r; 80 return r;
79 81
@@ -83,11 +85,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
83 85
84 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); 86 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
85 87
86 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 88 dpi.mgr_config.clock_info = dispc_cinfo;
87 if (r) {
88 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
89 return r;
90 }
91 89
92 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 90 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
93 *lck_div = dispc_cinfo.lck_div; 91 *lck_div = dispc_cinfo.lck_div;
@@ -96,7 +94,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
96 return 0; 94 return 0;
97} 95}
98 96
99static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft, 97static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
100 unsigned long pck_req, unsigned long *fck, int *lck_div, 98 unsigned long pck_req, unsigned long *fck, int *lck_div,
101 int *pck_div) 99 int *pck_div)
102{ 100{
@@ -104,7 +102,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
104 struct dispc_clock_info dispc_cinfo; 102 struct dispc_clock_info dispc_cinfo;
105 int r; 103 int r;
106 104
107 r = dss_calc_clock_div(is_tft, pck_req, &dss_cinfo, &dispc_cinfo); 105 r = dss_calc_clock_div(pck_req, &dss_cinfo, &dispc_cinfo);
108 if (r) 106 if (r)
109 return r; 107 return r;
110 108
@@ -112,9 +110,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
112 if (r) 110 if (r)
113 return r; 111 return r;
114 112
115 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 113 dpi.mgr_config.clock_info = dispc_cinfo;
116 if (r)
117 return r;
118 114
119 *fck = dss_cinfo.fck; 115 *fck = dss_cinfo.fck;
120 *lck_div = dispc_cinfo.lck_div; 116 *lck_div = dispc_cinfo.lck_div;
@@ -129,20 +125,14 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
129 int lck_div = 0, pck_div = 0; 125 int lck_div = 0, pck_div = 0;
130 unsigned long fck = 0; 126 unsigned long fck = 0;
131 unsigned long pck; 127 unsigned long pck;
132 bool is_tft;
133 int r = 0; 128 int r = 0;
134 129
135 dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
136 dssdev->panel.acbi, dssdev->panel.acb);
137
138 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
139
140 if (dpi_use_dsi_pll(dssdev)) 130 if (dpi_use_dsi_pll(dssdev))
141 r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000, 131 r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
142 &fck, &lck_div, &pck_div); 132 &lck_div, &pck_div);
143 else 133 else
144 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000, 134 r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck,
145 &fck, &lck_div, &pck_div); 135 &lck_div, &pck_div);
146 if (r) 136 if (r)
147 return r; 137 return r;
148 138
@@ -161,19 +151,18 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
161 return 0; 151 return 0;
162} 152}
163 153
164static void dpi_basic_init(struct omap_dss_device *dssdev) 154static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
165{ 155{
166 bool is_tft; 156 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
157
158 dpi.mgr_config.stallmode = false;
159 dpi.mgr_config.fifohandcheck = false;
167 160
168 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 161 dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines;
169 162
170 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS); 163 dpi.mgr_config.lcden_sig_polarity = 0;
171 dispc_mgr_enable_stallmode(dssdev->manager->id, false);
172 164
173 dispc_mgr_set_lcd_display_type(dssdev->manager->id, is_tft ? 165 dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
174 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
175 dispc_mgr_set_tft_data_lines(dssdev->manager->id,
176 dssdev->phy.dpi.data_lines);
177} 166}
178 167
179int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) 168int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
@@ -206,8 +195,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
206 if (r) 195 if (r)
207 goto err_get_dispc; 196 goto err_get_dispc;
208 197
209 dpi_basic_init(dssdev);
210
211 if (dpi_use_dsi_pll(dssdev)) { 198 if (dpi_use_dsi_pll(dssdev)) {
212 r = dsi_runtime_get(dpi.dsidev); 199 r = dsi_runtime_get(dpi.dsidev);
213 if (r) 200 if (r)
@@ -222,6 +209,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
222 if (r) 209 if (r)
223 goto err_set_mode; 210 goto err_set_mode;
224 211
212 dpi_config_lcd_manager(dssdev);
213
225 mdelay(2); 214 mdelay(2);
226 215
227 r = dss_mgr_enable(dssdev->manager); 216 r = dss_mgr_enable(dssdev->manager);
@@ -292,7 +281,6 @@ EXPORT_SYMBOL(dpi_set_timings);
292int dpi_check_timings(struct omap_dss_device *dssdev, 281int dpi_check_timings(struct omap_dss_device *dssdev,
293 struct omap_video_timings *timings) 282 struct omap_video_timings *timings)
294{ 283{
295 bool is_tft;
296 int r; 284 int r;
297 int lck_div, pck_div; 285 int lck_div, pck_div;
298 unsigned long fck; 286 unsigned long fck;
@@ -305,11 +293,9 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
305 if (timings->pixel_clock == 0) 293 if (timings->pixel_clock == 0)
306 return -EINVAL; 294 return -EINVAL;
307 295
308 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
309
310 if (dpi_use_dsi_pll(dssdev)) { 296 if (dpi_use_dsi_pll(dssdev)) {
311 struct dsi_clock_info dsi_cinfo; 297 struct dsi_clock_info dsi_cinfo;
312 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, 298 r = dsi_pll_calc_clock_div_pck(dpi.dsidev,
313 timings->pixel_clock * 1000, 299 timings->pixel_clock * 1000,
314 &dsi_cinfo, &dispc_cinfo); 300 &dsi_cinfo, &dispc_cinfo);
315 301
@@ -319,7 +305,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
319 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 305 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
320 } else { 306 } else {
321 struct dss_clock_info dss_cinfo; 307 struct dss_clock_info dss_cinfo;
322 r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000, 308 r = dss_calc_clock_div(timings->pixel_clock * 1000,
323 &dss_cinfo, &dispc_cinfo); 309 &dss_cinfo, &dispc_cinfo);
324 310
325 if (r) 311 if (r)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 14ce8cc079e3..b07e8864f82f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -331,6 +331,8 @@ struct dsi_data {
331 unsigned num_lanes_used; 331 unsigned num_lanes_used;
332 332
333 unsigned scp_clk_refcount; 333 unsigned scp_clk_refcount;
334
335 struct dss_lcd_mgr_config mgr_config;
334}; 336};
335 337
336struct dsi_packet_sent_handler_data { 338struct dsi_packet_sent_handler_data {
@@ -1085,9 +1087,9 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1085 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1087 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1086 1088
1087 if (enable) 1089 if (enable)
1088 clk_enable(dsi->sys_clk); 1090 clk_prepare_enable(dsi->sys_clk);
1089 else 1091 else
1090 clk_disable(dsi->sys_clk); 1092 clk_disable_unprepare(dsi->sys_clk);
1091 1093
1092 if (enable && dsi->pll_locked) { 1094 if (enable && dsi->pll_locked) {
1093 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) 1095 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
@@ -1316,7 +1318,7 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev,
1316 return 0; 1318 return 0;
1317} 1319}
1318 1320
1319int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, 1321int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
1320 unsigned long req_pck, struct dsi_clock_info *dsi_cinfo, 1322 unsigned long req_pck, struct dsi_clock_info *dsi_cinfo,
1321 struct dispc_clock_info *dispc_cinfo) 1323 struct dispc_clock_info *dispc_cinfo)
1322{ 1324{
@@ -1335,8 +1337,8 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
1335 dsi->cache_cinfo.clkin == dss_sys_clk) { 1337 dsi->cache_cinfo.clkin == dss_sys_clk) {
1336 DSSDBG("DSI clock info found from cache\n"); 1338 DSSDBG("DSI clock info found from cache\n");
1337 *dsi_cinfo = dsi->cache_cinfo; 1339 *dsi_cinfo = dsi->cache_cinfo;
1338 dispc_find_clk_divs(is_tft, req_pck, 1340 dispc_find_clk_divs(req_pck, dsi_cinfo->dsi_pll_hsdiv_dispc_clk,
1339 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); 1341 dispc_cinfo);
1340 return 0; 1342 return 0;
1341 } 1343 }
1342 1344
@@ -1402,7 +1404,7 @@ retry:
1402 1404
1403 match = 1; 1405 match = 1;
1404 1406
1405 dispc_find_clk_divs(is_tft, req_pck, 1407 dispc_find_clk_divs(req_pck,
1406 cur.dsi_pll_hsdiv_dispc_clk, 1408 cur.dsi_pll_hsdiv_dispc_clk,
1407 &cur_dispc); 1409 &cur_dispc);
1408 1410
@@ -3631,17 +3633,14 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
3631static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) 3633static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
3632{ 3634{
3633 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3635 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3634 int de_pol = dssdev->panel.dsi_vm_data.vp_de_pol;
3635 int hsync_pol = dssdev->panel.dsi_vm_data.vp_hsync_pol;
3636 int vsync_pol = dssdev->panel.dsi_vm_data.vp_vsync_pol;
3637 bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end; 3636 bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end;
3638 bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end; 3637 bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
3639 u32 r; 3638 u32 r;
3640 3639
3641 r = dsi_read_reg(dsidev, DSI_CTRL); 3640 r = dsi_read_reg(dsidev, DSI_CTRL);
3642 r = FLD_MOD(r, de_pol, 9, 9); /* VP_DE_POL */ 3641 r = FLD_MOD(r, 1, 9, 9); /* VP_DE_POL */
3643 r = FLD_MOD(r, hsync_pol, 10, 10); /* VP_HSYNC_POL */ 3642 r = FLD_MOD(r, 1, 10, 10); /* VP_HSYNC_POL */
3644 r = FLD_MOD(r, vsync_pol, 11, 11); /* VP_VSYNC_POL */ 3643 r = FLD_MOD(r, 1, 11, 11); /* VP_VSYNC_POL */
3645 r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */ 3644 r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */
3646 r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */ 3645 r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */
3647 r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */ 3646 r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */
@@ -4340,52 +4339,101 @@ EXPORT_SYMBOL(omap_dsi_update);
4340 4339
4341/* Display funcs */ 4340/* Display funcs */
4342 4341
4342static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
4343{
4344 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4345 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4346 struct dispc_clock_info dispc_cinfo;
4347 int r;
4348 unsigned long long fck;
4349
4350 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
4351
4352 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
4353 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
4354
4355 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
4356 if (r) {
4357 DSSERR("Failed to calc dispc clocks\n");
4358 return r;
4359 }
4360
4361 dsi->mgr_config.clock_info = dispc_cinfo;
4362
4363 return 0;
4364}
4365
4343static int dsi_display_init_dispc(struct omap_dss_device *dssdev) 4366static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4344{ 4367{
4368 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4369 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4370 struct omap_video_timings timings;
4345 int r; 4371 int r;
4372 u32 irq = 0;
4346 4373
4347 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { 4374 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
4348 u16 dw, dh; 4375 u16 dw, dh;
4349 u32 irq;
4350 struct omap_video_timings timings = {
4351 .hsw = 1,
4352 .hfp = 1,
4353 .hbp = 1,
4354 .vsw = 1,
4355 .vfp = 0,
4356 .vbp = 0,
4357 };
4358 4376
4359 dssdev->driver->get_resolution(dssdev, &dw, &dh); 4377 dssdev->driver->get_resolution(dssdev, &dw, &dh);
4378
4360 timings.x_res = dw; 4379 timings.x_res = dw;
4361 timings.y_res = dh; 4380 timings.y_res = dh;
4381 timings.hsw = 1;
4382 timings.hfp = 1;
4383 timings.hbp = 1;
4384 timings.vsw = 1;
4385 timings.vfp = 0;
4386 timings.vbp = 0;
4362 4387
4363 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? 4388 irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
4364 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4365 4389
4366 r = omap_dispc_register_isr(dsi_framedone_irq_callback, 4390 r = omap_dispc_register_isr(dsi_framedone_irq_callback,
4367 (void *) dssdev, irq); 4391 (void *) dssdev, irq);
4368 if (r) { 4392 if (r) {
4369 DSSERR("can't get FRAMEDONE irq\n"); 4393 DSSERR("can't get FRAMEDONE irq\n");
4370 return r; 4394 goto err;
4371 } 4395 }
4372 4396
4373 dispc_mgr_enable_stallmode(dssdev->manager->id, true); 4397 dsi->mgr_config.stallmode = true;
4374 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); 4398 dsi->mgr_config.fifohandcheck = true;
4375
4376 dss_mgr_set_timings(dssdev->manager, &timings);
4377 } else { 4399 } else {
4378 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 4400 timings = dssdev->panel.timings;
4379 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0);
4380 4401
4381 dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); 4402 dsi->mgr_config.stallmode = false;
4403 dsi->mgr_config.fifohandcheck = false;
4382 } 4404 }
4383 4405
4384 dispc_mgr_set_lcd_display_type(dssdev->manager->id, 4406 /*
4385 OMAP_DSS_LCD_DISPLAY_TFT); 4407 * override interlace, logic level and edge related parameters in
4386 dispc_mgr_set_tft_data_lines(dssdev->manager->id, 4408 * omap_video_timings with default values
4387 dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)); 4409 */
4410 timings.interlace = false;
4411 timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
4412 timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
4413 timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
4414 timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
4415 timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
4416
4417 dss_mgr_set_timings(dssdev->manager, &timings);
4418
4419 r = dsi_configure_dispc_clocks(dssdev);
4420 if (r)
4421 goto err1;
4422
4423 dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
4424 dsi->mgr_config.video_port_width =
4425 dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
4426 dsi->mgr_config.lcden_sig_polarity = 0;
4427
4428 dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
4429
4388 return 0; 4430 return 0;
4431err1:
4432 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE)
4433 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4434 (void *) dssdev, irq);
4435err:
4436 return r;
4389} 4437}
4390 4438
4391static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) 4439static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
@@ -4393,8 +4441,7 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
4393 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { 4441 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
4394 u32 irq; 4442 u32 irq;
4395 4443
4396 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? 4444 irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
4397 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4398 4445
4399 omap_dispc_unregister_isr(dsi_framedone_irq_callback, 4446 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4400 (void *) dssdev, irq); 4447 (void *) dssdev, irq);
@@ -4426,33 +4473,6 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
4426 return 0; 4473 return 0;
4427} 4474}
4428 4475
4429static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
4430{
4431 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4432 struct dispc_clock_info dispc_cinfo;
4433 int r;
4434 unsigned long long fck;
4435
4436 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
4437
4438 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
4439 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
4440
4441 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
4442 if (r) {
4443 DSSERR("Failed to calc dispc clocks\n");
4444 return r;
4445 }
4446
4447 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
4448 if (r) {
4449 DSSERR("Failed to set dispc clocks\n");
4450 return r;
4451 }
4452
4453 return 0;
4454}
4455
4456static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4476static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4457{ 4477{
4458 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4478 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4474,10 +4494,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4474 4494
4475 DSSDBG("PLL OK\n"); 4495 DSSDBG("PLL OK\n");
4476 4496
4477 r = dsi_configure_dispc_clocks(dssdev);
4478 if (r)
4479 goto err2;
4480
4481 r = dsi_cio_init(dssdev); 4497 r = dsi_cio_init(dssdev);
4482 if (r) 4498 if (r)
4483 goto err2; 4499 goto err2;
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index d2b57197b292..04b4586113e3 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -388,7 +388,8 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
388 dsi_wait_pll_hsdiv_dispc_active(dsidev); 388 dsi_wait_pll_hsdiv_dispc_active(dsidev);
389 break; 389 break;
390 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 390 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
391 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2); 391 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
392 channel != OMAP_DSS_CHANNEL_LCD3);
392 b = 1; 393 b = 1;
393 dsidev = dsi_get_dsidev_from_id(1); 394 dsidev = dsi_get_dsidev_from_id(1);
394 dsi_wait_pll_hsdiv_dispc_active(dsidev); 395 dsi_wait_pll_hsdiv_dispc_active(dsidev);
@@ -398,10 +399,12 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
398 return; 399 return;
399 } 400 }
400 401
401 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; 402 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
403 (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
402 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */ 404 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
403 405
404 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; 406 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
407 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
405 dss.lcd_clk_source[ix] = clk_src; 408 dss.lcd_clk_source[ix] = clk_src;
406} 409}
407 410
@@ -418,7 +421,8 @@ enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
418enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) 421enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
419{ 422{
420 if (dss_has_feature(FEAT_LCD_CLK_SRC)) { 423 if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
421 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; 424 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
425 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
422 return dss.lcd_clk_source[ix]; 426 return dss.lcd_clk_source[ix];
423 } else { 427 } else {
424 /* LCD_CLK source is the same as DISPC_FCLK source for 428 /* LCD_CLK source is the same as DISPC_FCLK source for
@@ -502,8 +506,7 @@ unsigned long dss_get_dpll4_rate(void)
502 return 0; 506 return 0;
503} 507}
504 508
505int dss_calc_clock_div(bool is_tft, unsigned long req_pck, 509int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
506 struct dss_clock_info *dss_cinfo,
507 struct dispc_clock_info *dispc_cinfo) 510 struct dispc_clock_info *dispc_cinfo)
508{ 511{
509 unsigned long prate; 512 unsigned long prate;
@@ -551,7 +554,7 @@ retry:
551 fck = clk_get_rate(dss.dss_clk); 554 fck = clk_get_rate(dss.dss_clk);
552 fck_div = 1; 555 fck_div = 1;
553 556
554 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 557 dispc_find_clk_divs(req_pck, fck, &cur_dispc);
555 match = 1; 558 match = 1;
556 559
557 best_dss.fck = fck; 560 best_dss.fck = fck;
@@ -581,7 +584,7 @@ retry:
581 584
582 match = 1; 585 match = 1;
583 586
584 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 587 dispc_find_clk_divs(req_pck, fck, &cur_dispc);
585 588
586 if (abs(cur_dispc.pck - req_pck) < 589 if (abs(cur_dispc.pck - req_pck) <
587 abs(best_dispc.pck - req_pck)) { 590 abs(best_dispc.pck - req_pck)) {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index dd1092ceaeef..f67afe76f217 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -152,6 +152,25 @@ struct dsi_clock_info {
152 u16 lp_clk_div; 152 u16 lp_clk_div;
153}; 153};
154 154
155struct reg_field {
156 u16 reg;
157 u8 high;
158 u8 low;
159};
160
161struct dss_lcd_mgr_config {
162 enum dss_io_pad_mode io_pad_mode;
163
164 bool stallmode;
165 bool fifohandcheck;
166
167 struct dispc_clock_info clock_info;
168
169 int video_port_width;
170
171 int lcden_sig_polarity;
172};
173
155struct seq_file; 174struct seq_file;
156struct platform_device; 175struct platform_device;
157 176
@@ -188,6 +207,8 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
188int dss_mgr_unset_device(struct omap_overlay_manager *mgr); 207int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
189void dss_mgr_set_timings(struct omap_overlay_manager *mgr, 208void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
190 struct omap_video_timings *timings); 209 struct omap_video_timings *timings);
210void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
211 const struct dss_lcd_mgr_config *config);
191const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); 212const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
192 213
193bool dss_ovl_is_enabled(struct omap_overlay *ovl); 214bool dss_ovl_is_enabled(struct omap_overlay *ovl);
@@ -210,8 +231,6 @@ void dss_init_device(struct platform_device *pdev,
210 struct omap_dss_device *dssdev); 231 struct omap_dss_device *dssdev);
211void dss_uninit_device(struct platform_device *pdev, 232void dss_uninit_device(struct platform_device *pdev,
212 struct omap_dss_device *dssdev); 233 struct omap_dss_device *dssdev);
213bool dss_use_replication(struct omap_dss_device *dssdev,
214 enum omap_color_mode mode);
215 234
216/* manager */ 235/* manager */
217int dss_init_overlay_managers(struct platform_device *pdev); 236int dss_init_overlay_managers(struct platform_device *pdev);
@@ -223,8 +242,18 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
223int dss_mgr_check(struct omap_overlay_manager *mgr, 242int dss_mgr_check(struct omap_overlay_manager *mgr,
224 struct omap_overlay_manager_info *info, 243 struct omap_overlay_manager_info *info,
225 const struct omap_video_timings *mgr_timings, 244 const struct omap_video_timings *mgr_timings,
245 const struct dss_lcd_mgr_config *config,
226 struct omap_overlay_info **overlay_infos); 246 struct omap_overlay_info **overlay_infos);
227 247
248static inline bool dss_mgr_is_lcd(enum omap_channel id)
249{
250 if (id == OMAP_DSS_CHANNEL_LCD || id == OMAP_DSS_CHANNEL_LCD2 ||
251 id == OMAP_DSS_CHANNEL_LCD3)
252 return true;
253 else
254 return false;
255}
256
228/* overlay */ 257/* overlay */
229void dss_init_overlays(struct platform_device *pdev); 258void dss_init_overlays(struct platform_device *pdev);
230void dss_uninit_overlays(struct platform_device *pdev); 259void dss_uninit_overlays(struct platform_device *pdev);
@@ -234,6 +263,8 @@ int dss_ovl_simple_check(struct omap_overlay *ovl,
234 const struct omap_overlay_info *info); 263 const struct omap_overlay_info *info);
235int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, 264int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
236 const struct omap_video_timings *mgr_timings); 265 const struct omap_video_timings *mgr_timings);
266bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
267 enum omap_color_mode mode);
237 268
238/* DSS */ 269/* DSS */
239int dss_init_platform_driver(void) __init; 270int dss_init_platform_driver(void) __init;
@@ -268,8 +299,7 @@ unsigned long dss_get_dpll4_rate(void);
268int dss_calc_clock_rates(struct dss_clock_info *cinfo); 299int dss_calc_clock_rates(struct dss_clock_info *cinfo);
269int dss_set_clock_div(struct dss_clock_info *cinfo); 300int dss_set_clock_div(struct dss_clock_info *cinfo);
270int dss_get_clock_div(struct dss_clock_info *cinfo); 301int dss_get_clock_div(struct dss_clock_info *cinfo);
271int dss_calc_clock_div(bool is_tft, unsigned long req_pck, 302int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
272 struct dss_clock_info *dss_cinfo,
273 struct dispc_clock_info *dispc_cinfo); 303 struct dispc_clock_info *dispc_cinfo);
274 304
275/* SDI */ 305/* SDI */
@@ -296,7 +326,7 @@ u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
296unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); 326unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
297int dsi_pll_set_clock_div(struct platform_device *dsidev, 327int dsi_pll_set_clock_div(struct platform_device *dsidev,
298 struct dsi_clock_info *cinfo); 328 struct dsi_clock_info *cinfo);
299int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, 329int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
300 unsigned long req_pck, struct dsi_clock_info *cinfo, 330 unsigned long req_pck, struct dsi_clock_info *cinfo,
301 struct dispc_clock_info *dispc_cinfo); 331 struct dispc_clock_info *dispc_cinfo);
302int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, 332int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
@@ -330,7 +360,7 @@ static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
330 return -ENODEV; 360 return -ENODEV;
331} 361}
332static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, 362static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
333 bool is_tft, unsigned long req_pck, 363 unsigned long req_pck,
334 struct dsi_clock_info *dsi_cinfo, 364 struct dsi_clock_info *dsi_cinfo,
335 struct dispc_clock_info *dispc_cinfo) 365 struct dispc_clock_info *dispc_cinfo)
336{ 366{
@@ -387,7 +417,7 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode);
387bool dispc_mgr_timings_ok(enum omap_channel channel, 417bool dispc_mgr_timings_ok(enum omap_channel channel,
388 const struct omap_video_timings *timings); 418 const struct omap_video_timings *timings);
389unsigned long dispc_fclk_rate(void); 419unsigned long dispc_fclk_rate(void);
390void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 420void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck,
391 struct dispc_clock_info *cinfo); 421 struct dispc_clock_info *cinfo);
392int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 422int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
393 struct dispc_clock_info *cinfo); 423 struct dispc_clock_info *cinfo);
@@ -398,8 +428,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
398 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, 428 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
399 bool manual_update); 429 bool manual_update);
400int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 430int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
401 bool ilace, bool replication, 431 bool replication, const struct omap_video_timings *mgr_timings);
402 const struct omap_video_timings *mgr_timings);
403int dispc_ovl_enable(enum omap_plane plane, bool enable); 432int dispc_ovl_enable(enum omap_plane plane, bool enable);
404void dispc_ovl_set_channel_out(enum omap_plane plane, 433void dispc_ovl_set_channel_out(enum omap_plane plane,
405 enum omap_channel channel); 434 enum omap_channel channel);
@@ -415,16 +444,13 @@ bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
415void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode); 444void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
416void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable); 445void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
417void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); 446void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
418void dispc_mgr_set_lcd_display_type(enum omap_channel channel, 447void dispc_mgr_set_lcd_type_tft(enum omap_channel channel);
419 enum omap_lcd_display_type type);
420void dispc_mgr_set_timings(enum omap_channel channel, 448void dispc_mgr_set_timings(enum omap_channel channel,
421 struct omap_video_timings *timings); 449 struct omap_video_timings *timings);
422void dispc_mgr_set_pol_freq(enum omap_channel channel,
423 enum omap_panel_config config, u8 acbi, u8 acb);
424unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); 450unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
425unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); 451unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
426unsigned long dispc_core_clk_rate(void); 452unsigned long dispc_core_clk_rate(void);
427int dispc_mgr_set_clock_div(enum omap_channel channel, 453void dispc_mgr_set_clock_div(enum omap_channel channel,
428 struct dispc_clock_info *cinfo); 454 struct dispc_clock_info *cinfo);
429int dispc_mgr_get_clock_div(enum omap_channel channel, 455int dispc_mgr_get_clock_div(enum omap_channel channel,
430 struct dispc_clock_info *cinfo); 456 struct dispc_clock_info *cinfo);
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index bdf469f080e7..996ffcbfed58 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -24,9 +24,9 @@
24#include "ti_hdmi.h" 24#include "ti_hdmi.h"
25#endif 25#endif
26 26
27#define MAX_DSS_MANAGERS 3 27#define MAX_DSS_MANAGERS 4
28#define MAX_DSS_OVERLAYS 4 28#define MAX_DSS_OVERLAYS 4
29#define MAX_DSS_LCD_MANAGERS 2 29#define MAX_DSS_LCD_MANAGERS 3
30#define MAX_NUM_DSI 2 30#define MAX_NUM_DSI 2
31 31
32/* DSS has feature id */ 32/* DSS has feature id */
@@ -36,6 +36,7 @@ enum dss_feat_id {
36 FEAT_PCKFREEENABLE, 36 FEAT_PCKFREEENABLE,
37 FEAT_FUNCGATED, 37 FEAT_FUNCGATED,
38 FEAT_MGR_LCD2, 38 FEAT_MGR_LCD2,
39 FEAT_MGR_LCD3,
39 FEAT_LINEBUFFERSPLIT, 40 FEAT_LINEBUFFERSPLIT,
40 FEAT_ROWREPEATENABLE, 41 FEAT_ROWREPEATENABLE,
41 FEAT_RESIZECONF, 42 FEAT_RESIZECONF,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 26a2430a7028..060216fdc578 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -78,43 +78,214 @@ static struct {
78 */ 78 */
79 79
80static const struct hdmi_config cea_timings[] = { 80static const struct hdmi_config cea_timings[] = {
81{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, 81 {
82{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, 82 { 640, 480, 25200, 96, 16, 48, 2, 10, 33,
83{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, 83 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
84{ {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} }, 84 false, },
85{ {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} }, 85 { 1, HDMI_HDMI },
86{ {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} }, 86 },
87{ {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} }, 87 {
88{ {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} }, 88 { 720, 480, 27027, 62, 16, 60, 6, 9, 30,
89{ {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} }, 89 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
90{ {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} }, 90 false, },
91{ {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} }, 91 { 2, HDMI_HDMI },
92{ {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} }, 92 },
93{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, 93 {
94{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, 94 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
95{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, 95 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
96 false, },
97 { 4, HDMI_HDMI },
98 },
99 {
100 { 1920, 540, 74250, 44, 88, 148, 5, 2, 15,
101 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
102 true, },
103 { 5, HDMI_HDMI },
104 },
105 {
106 { 1440, 240, 27027, 124, 38, 114, 3, 4, 15,
107 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
108 true, },
109 { 6, HDMI_HDMI },
110 },
111 {
112 { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36,
113 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
114 false, },
115 { 16, HDMI_HDMI },
116 },
117 {
118 { 720, 576, 27000, 64, 12, 68, 5, 5, 39,
119 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
120 false, },
121 { 17, HDMI_HDMI },
122 },
123 {
124 { 1280, 720, 74250, 40, 440, 220, 5, 5, 20,
125 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
126 false, },
127 { 19, HDMI_HDMI },
128 },
129 {
130 { 1920, 540, 74250, 44, 528, 148, 5, 2, 15,
131 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
132 true, },
133 { 20, HDMI_HDMI },
134 },
135 {
136 { 1440, 288, 27000, 126, 24, 138, 3, 2, 19,
137 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
138 true, },
139 { 21, HDMI_HDMI },
140 },
141 {
142 { 1440, 576, 54000, 128, 24, 136, 5, 5, 39,
143 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
144 false, },
145 { 29, HDMI_HDMI },
146 },
147 {
148 { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36,
149 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
150 false, },
151 { 31, HDMI_HDMI },
152 },
153 {
154 { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36,
155 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
156 false, },
157 { 32, HDMI_HDMI },
158 },
159 {
160 { 2880, 480, 108108, 248, 64, 240, 6, 9, 30,
161 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
162 false, },
163 { 35, HDMI_HDMI },
164 },
165 {
166 { 2880, 576, 108000, 256, 48, 272, 5, 5, 39,
167 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
168 false, },
169 { 37, HDMI_HDMI },
170 },
96}; 171};
172
97static const struct hdmi_config vesa_timings[] = { 173static const struct hdmi_config vesa_timings[] = {
98/* VESA From Here */ 174/* VESA From Here */
99{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, 175 {
100{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, 176 { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
101{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} }, 177 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
102{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} }, 178 false, },
103{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} }, 179 { 4, HDMI_DVI },
104{ {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} }, 180 },
105{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} }, 181 {
106{ {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} }, 182 { 800, 600, 40000, 128, 40, 88, 4, 1, 23,
107{ {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} }, 183 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
108{ {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} }, 184 false, },
109{ {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} }, 185 { 9, HDMI_DVI },
110{ {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} }, 186 },
111{ {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} }, 187 {
112{ {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} }, 188 { 848, 480, 33750, 112, 16, 112, 8, 6, 23,
113{ {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} }, 189 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
114{ {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} }, 190 false, },
115{ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} }, 191 { 0xE, HDMI_DVI },
116{ {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} }, 192 },
117{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } 193 {
194 { 1280, 768, 79500, 128, 64, 192, 7, 3, 20,
195 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
196 false, },
197 { 0x17, HDMI_DVI },
198 },
199 {
200 { 1280, 800, 83500, 128, 72, 200, 6, 3, 22,
201 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
202 false, },
203 { 0x1C, HDMI_DVI },
204 },
205 {
206 { 1360, 768, 85500, 112, 64, 256, 6, 3, 18,
207 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
208 false, },
209 { 0x27, HDMI_DVI },
210 },
211 {
212 { 1280, 960, 108000, 112, 96, 312, 3, 1, 36,
213 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
214 false, },
215 { 0x20, HDMI_DVI },
216 },
217 {
218 { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38,
219 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
220 false, },
221 { 0x23, HDMI_DVI },
222 },
223 {
224 { 1024, 768, 65000, 136, 24, 160, 6, 3, 29,
225 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
226 false, },
227 { 0x10, HDMI_DVI },
228 },
229 {
230 { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32,
231 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
232 false, },
233 { 0x2A, HDMI_DVI },
234 },
235 {
236 { 1440, 900, 106500, 152, 80, 232, 6, 3, 25,
237 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
238 false, },
239 { 0x2F, HDMI_DVI },
240 },
241 {
242 { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30,
243 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
244 false, },
245 { 0x3A, HDMI_DVI },
246 },
247 {
248 { 1366, 768, 85500, 143, 70, 213, 3, 3, 24,
249 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
250 false, },
251 { 0x51, HDMI_DVI },
252 },
253 {
254 { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36,
255 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
256 false, },
257 { 0x52, HDMI_DVI },
258 },
259 {
260 { 1280, 768, 68250, 32, 48, 80, 7, 3, 12,
261 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
262 false, },
263 { 0x16, HDMI_DVI },
264 },
265 {
266 { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23,
267 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
268 false, },
269 { 0x29, HDMI_DVI },
270 },
271 {
272 { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21,
273 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
274 false, },
275 { 0x39, HDMI_DVI },
276 },
277 {
278 { 1280, 800, 79500, 32, 48, 80, 6, 3, 14,
279 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
280 false, },
281 { 0x1B, HDMI_DVI },
282 },
283 {
284 { 1280, 720, 74250, 40, 110, 220, 5, 5, 20,
285 OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
286 false, },
287 { 0x55, HDMI_DVI },
288 },
118}; 289};
119 290
120static int hdmi_runtime_get(void) 291static int hdmi_runtime_get(void)
@@ -179,7 +350,7 @@ static const struct hdmi_config *hdmi_get_timings(void)
179} 350}
180 351
181static bool hdmi_timings_compare(struct omap_video_timings *timing1, 352static bool hdmi_timings_compare(struct omap_video_timings *timing1,
182 const struct hdmi_video_timings *timing2) 353 const struct omap_video_timings *timing2)
183{ 354{
184 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; 355 int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
185 356
@@ -758,6 +929,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
758 hdmi.ip_data.core_av_offset = HDMI_CORE_AV; 929 hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
759 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 930 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
760 hdmi.ip_data.phy_offset = HDMI_PHY; 931 hdmi.ip_data.phy_offset = HDMI_PHY;
932 mutex_init(&hdmi.ip_data.lock);
761 933
762 hdmi_panel_init(); 934 hdmi_panel_init();
763 935
@@ -785,7 +957,7 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
785 957
786static int hdmi_runtime_suspend(struct device *dev) 958static int hdmi_runtime_suspend(struct device *dev)
787{ 959{
788 clk_disable(hdmi.sys_clk); 960 clk_disable_unprepare(hdmi.sys_clk);
789 961
790 dispc_runtime_put(); 962 dispc_runtime_put();
791 963
@@ -800,7 +972,7 @@ static int hdmi_runtime_resume(struct device *dev)
800 if (r < 0) 972 if (r < 0)
801 return r; 973 return r;
802 974
803 clk_enable(hdmi.sys_clk); 975 clk_prepare_enable(hdmi.sys_clk);
804 976
805 return 0; 977 return 0;
806} 978}
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 1179e3c4b1c7..e10844faadf9 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -43,10 +43,11 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev)
43{ 43{
44 DSSDBG("ENTER hdmi_panel_probe\n"); 44 DSSDBG("ENTER hdmi_panel_probe\n");
45 45
46 dssdev->panel.config = OMAP_DSS_LCD_TFT | 46 dssdev->panel.timings = (struct omap_video_timings)
47 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; 47 { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
48 48 OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
49 dssdev->panel.timings = (struct omap_video_timings){640, 480, 25175, 96, 16, 48, 2 , 11, 31}; 49 false,
50 };
50 51
51 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", 52 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
52 dssdev->panel.timings.x_res, 53 dssdev->panel.timings.x_res,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 0cbcde4c688a..53710fadc82d 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -500,16 +500,12 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
500 if (r) 500 if (r)
501 return r; 501 return r;
502 502
503 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 503 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
504 irq = DISPC_IRQ_EVSYNC_ODD; 504 irq = DISPC_IRQ_EVSYNC_ODD;
505 } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) { 505 else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI)
506 irq = DISPC_IRQ_EVSYNC_EVEN; 506 irq = DISPC_IRQ_EVSYNC_EVEN;
507 } else { 507 else
508 if (mgr->id == OMAP_DSS_CHANNEL_LCD) 508 irq = dispc_mgr_get_vsync_irq(mgr->id);
509 irq = DISPC_IRQ_VSYNC;
510 else
511 irq = DISPC_IRQ_VSYNC2;
512 }
513 509
514 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 510 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
515 511
@@ -545,6 +541,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
545 mgr->name = "lcd2"; 541 mgr->name = "lcd2";
546 mgr->id = OMAP_DSS_CHANNEL_LCD2; 542 mgr->id = OMAP_DSS_CHANNEL_LCD2;
547 break; 543 break;
544 case 3:
545 mgr->name = "lcd3";
546 mgr->id = OMAP_DSS_CHANNEL_LCD3;
547 break;
548 } 548 }
549 549
550 mgr->set_device = &dss_mgr_set_device; 550 mgr->set_device = &dss_mgr_set_device;
@@ -665,9 +665,40 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
665 return 0; 665 return 0;
666} 666}
667 667
668static int dss_mgr_check_lcd_config(struct omap_overlay_manager *mgr,
669 const struct dss_lcd_mgr_config *config)
670{
671 struct dispc_clock_info cinfo = config->clock_info;
672 int dl = config->video_port_width;
673 bool stallmode = config->stallmode;
674 bool fifohandcheck = config->fifohandcheck;
675
676 if (cinfo.lck_div < 1 || cinfo.lck_div > 255)
677 return -EINVAL;
678
679 if (cinfo.pck_div < 1 || cinfo.pck_div > 255)
680 return -EINVAL;
681
682 if (dl != 12 && dl != 16 && dl != 18 && dl != 24)
683 return -EINVAL;
684
685 /* fifohandcheck should be used only with stallmode */
686 if (stallmode == false && fifohandcheck == true)
687 return -EINVAL;
688
689 /*
690 * io pad mode can be only checked by using dssdev connected to the
691 * manager. Ignore checking these for now, add checks when manager
692 * is capable of holding information related to the connected interface
693 */
694
695 return 0;
696}
697
668int dss_mgr_check(struct omap_overlay_manager *mgr, 698int dss_mgr_check(struct omap_overlay_manager *mgr,
669 struct omap_overlay_manager_info *info, 699 struct omap_overlay_manager_info *info,
670 const struct omap_video_timings *mgr_timings, 700 const struct omap_video_timings *mgr_timings,
701 const struct dss_lcd_mgr_config *lcd_config,
671 struct omap_overlay_info **overlay_infos) 702 struct omap_overlay_info **overlay_infos)
672{ 703{
673 struct omap_overlay *ovl; 704 struct omap_overlay *ovl;
@@ -683,6 +714,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
683 if (r) 714 if (r)
684 return r; 715 return r;
685 716
717 r = dss_mgr_check_lcd_config(mgr, lcd_config);
718 if (r)
719 return r;
720
686 list_for_each_entry(ovl, &mgr->overlays, list) { 721 list_for_each_entry(ovl, &mgr->overlays, list) {
687 struct omap_overlay_info *oi; 722 struct omap_overlay_info *oi;
688 int r; 723 int r;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index b0ba60f88dd2..952c6fad9a81 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -528,14 +528,24 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
528 struct omap_overlay_manager *lcd_mgr; 528 struct omap_overlay_manager *lcd_mgr;
529 struct omap_overlay_manager *tv_mgr; 529 struct omap_overlay_manager *tv_mgr;
530 struct omap_overlay_manager *lcd2_mgr = NULL; 530 struct omap_overlay_manager *lcd2_mgr = NULL;
531 struct omap_overlay_manager *lcd3_mgr = NULL;
531 struct omap_overlay_manager *mgr = NULL; 532 struct omap_overlay_manager *mgr = NULL;
532 533
533 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); 534 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
534 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); 535 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
536 if (dss_has_feature(FEAT_MGR_LCD3))
537 lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
535 if (dss_has_feature(FEAT_MGR_LCD2)) 538 if (dss_has_feature(FEAT_MGR_LCD2))
536 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2); 539 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
537 540
538 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { 541 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
542 if (!lcd3_mgr->device || force) {
543 if (lcd3_mgr->device)
544 lcd3_mgr->unset_device(lcd3_mgr);
545 lcd3_mgr->set_device(lcd3_mgr, dssdev);
546 mgr = lcd3_mgr;
547 }
548 } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
539 if (!lcd2_mgr->device || force) { 549 if (!lcd2_mgr->device || force) {
540 if (lcd2_mgr->device) 550 if (lcd2_mgr->device)
541 lcd2_mgr->unset_device(lcd2_mgr); 551 lcd2_mgr->unset_device(lcd2_mgr);
@@ -677,3 +687,16 @@ int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
677 687
678 return 0; 688 return 0;
679} 689}
690
691/*
692 * Checks if replication logic should be used. Only use when overlay is in
693 * RGB12U or RGB16 mode, and video port width interface is 18bpp or 24bpp
694 */
695bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
696 enum omap_color_mode mode)
697{
698 if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
699 return false;
700
701 return config.video_port_width > 16;
702}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 7985fa12b9b4..7c087424b634 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -300,10 +300,11 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
300} 300}
301EXPORT_SYMBOL(omap_rfbi_write_pixels); 301EXPORT_SYMBOL(omap_rfbi_write_pixels);
302 302
303static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, 303static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
304 u16 height, void (*callback)(void *data), void *data) 304 u16 height, void (*callback)(void *data), void *data)
305{ 305{
306 u32 l; 306 u32 l;
307 int r;
307 struct omap_video_timings timings = { 308 struct omap_video_timings timings = {
308 .hsw = 1, 309 .hsw = 1,
309 .hfp = 1, 310 .hfp = 1,
@@ -322,7 +323,9 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
322 323
323 dss_mgr_set_timings(dssdev->manager, &timings); 324 dss_mgr_set_timings(dssdev->manager, &timings);
324 325
325 dispc_mgr_enable(dssdev->manager->id, true); 326 r = dss_mgr_enable(dssdev->manager);
327 if (r)
328 return r;
326 329
327 rfbi.framedone_callback = callback; 330 rfbi.framedone_callback = callback;
328 rfbi.framedone_callback_data = data; 331 rfbi.framedone_callback_data = data;
@@ -335,6 +338,8 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
335 l = FLD_MOD(l, 1, 4, 4); /* ITE */ 338 l = FLD_MOD(l, 1, 4, 4); /* ITE */
336 339
337 rfbi_write_reg(RFBI_CONTROL, l); 340 rfbi_write_reg(RFBI_CONTROL, l);
341
342 return 0;
338} 343}
339 344
340static void framedone_callback(void *data, u32 mask) 345static void framedone_callback(void *data, u32 mask)
@@ -814,8 +819,11 @@ int omap_rfbi_update(struct omap_dss_device *dssdev,
814 u16 x, u16 y, u16 w, u16 h, 819 u16 x, u16 y, u16 w, u16 h,
815 void (*callback)(void *), void *data) 820 void (*callback)(void *), void *data)
816{ 821{
817 rfbi_transfer_area(dssdev, w, h, callback, data); 822 int r;
818 return 0; 823
824 r = rfbi_transfer_area(dssdev, w, h, callback, data);
825
826 return r;
819} 827}
820EXPORT_SYMBOL(omap_rfbi_update); 828EXPORT_SYMBOL(omap_rfbi_update);
821 829
@@ -859,6 +867,22 @@ static void rfbi_dump_regs(struct seq_file *s)
859#undef DUMPREG 867#undef DUMPREG
860} 868}
861 869
870static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
871{
872 struct dss_lcd_mgr_config mgr_config;
873
874 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
875
876 mgr_config.stallmode = true;
877 /* Do we need fifohandcheck for RFBI? */
878 mgr_config.fifohandcheck = false;
879
880 mgr_config.video_port_width = dssdev->ctrl.pixel_size;
881 mgr_config.lcden_sig_polarity = 0;
882
883 dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
884}
885
862int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 886int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
863{ 887{
864 int r; 888 int r;
@@ -885,13 +909,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
885 goto err1; 909 goto err1;
886 } 910 }
887 911
888 dispc_mgr_set_lcd_display_type(dssdev->manager->id, 912 rfbi_config_lcd_manager(dssdev);
889 OMAP_DSS_LCD_DISPLAY_TFT);
890
891 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI);
892 dispc_mgr_enable_stallmode(dssdev->manager->id, true);
893
894 dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
895 913
896 rfbi_configure(dssdev->phy.rfbi.channel, 914 rfbi_configure(dssdev->phy.rfbi.channel,
897 dssdev->ctrl.pixel_size, 915 dssdev->ctrl.pixel_size,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3a43dc2a9b46..5d31699fbd3c 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -32,19 +32,21 @@
32static struct { 32static struct {
33 bool update_enabled; 33 bool update_enabled;
34 struct regulator *vdds_sdi_reg; 34 struct regulator *vdds_sdi_reg;
35} sdi;
36 35
37static void sdi_basic_init(struct omap_dss_device *dssdev) 36 struct dss_lcd_mgr_config mgr_config;
37} sdi;
38 38
39static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
39{ 40{
40 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS); 41 sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
41 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 42
43 sdi.mgr_config.stallmode = false;
44 sdi.mgr_config.fifohandcheck = false;
42 45
43 dispc_mgr_set_lcd_display_type(dssdev->manager->id, 46 sdi.mgr_config.video_port_width = 24;
44 OMAP_DSS_LCD_DISPLAY_TFT); 47 sdi.mgr_config.lcden_sig_polarity = 1;
45 48
46 dispc_mgr_set_tft_data_lines(dssdev->manager->id, 24); 49 dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
47 dispc_lcd_enable_signal_polarity(1);
48} 50}
49 51
50int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) 52int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
@@ -52,8 +54,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
52 struct omap_video_timings *t = &dssdev->panel.timings; 54 struct omap_video_timings *t = &dssdev->panel.timings;
53 struct dss_clock_info dss_cinfo; 55 struct dss_clock_info dss_cinfo;
54 struct dispc_clock_info dispc_cinfo; 56 struct dispc_clock_info dispc_cinfo;
55 u16 lck_div, pck_div;
56 unsigned long fck;
57 unsigned long pck; 57 unsigned long pck;
58 int r; 58 int r;
59 59
@@ -76,24 +76,17 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
76 if (r) 76 if (r)
77 goto err_get_dispc; 77 goto err_get_dispc;
78 78
79 sdi_basic_init(dssdev);
80
81 /* 15.5.9.1.2 */ 79 /* 15.5.9.1.2 */
82 dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF; 80 dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
83 81 dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
84 dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
85 dssdev->panel.acbi, dssdev->panel.acb);
86 82
87 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 83 r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
88 &dss_cinfo, &dispc_cinfo);
89 if (r) 84 if (r)
90 goto err_calc_clock_div; 85 goto err_calc_clock_div;
91 86
92 fck = dss_cinfo.fck; 87 sdi.mgr_config.clock_info = dispc_cinfo;
93 lck_div = dispc_cinfo.lck_div;
94 pck_div = dispc_cinfo.pck_div;
95 88
96 pck = fck / lck_div / pck_div / 1000; 89 pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
97 90
98 if (pck != t->pixel_clock) { 91 if (pck != t->pixel_clock) {
99 DSSWARN("Could not find exact pixel clock. Requested %d kHz, " 92 DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
@@ -110,9 +103,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
110 if (r) 103 if (r)
111 goto err_set_dss_clock_div; 104 goto err_set_dss_clock_div;
112 105
113 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); 106 sdi_config_lcd_manager(dssdev);
114 if (r)
115 goto err_set_dispc_clock_div;
116 107
117 dss_sdi_init(dssdev->phy.sdi.datapairs); 108 dss_sdi_init(dssdev->phy.sdi.datapairs);
118 r = dss_sdi_enable(); 109 r = dss_sdi_enable();
@@ -129,7 +120,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
129err_mgr_enable: 120err_mgr_enable:
130 dss_sdi_disable(); 121 dss_sdi_disable();
131err_sdi_enable: 122err_sdi_enable:
132err_set_dispc_clock_div:
133err_set_dss_clock_div: 123err_set_dss_clock_div:
134err_calc_clock_div: 124err_calc_clock_div:
135 dispc_runtime_put(); 125 dispc_runtime_put();
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index e734cb444bc7..b046c208cb97 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -42,30 +42,13 @@ enum hdmi_clk_refsel {
42 HDMI_REFSEL_SYSCLK = 3 42 HDMI_REFSEL_SYSCLK = 3
43}; 43};
44 44
45/* HDMI timing structure */
46struct hdmi_video_timings {
47 u16 x_res;
48 u16 y_res;
49 /* Unit: KHz */
50 u32 pixel_clock;
51 u16 hsw;
52 u16 hfp;
53 u16 hbp;
54 u16 vsw;
55 u16 vfp;
56 u16 vbp;
57 bool vsync_pol;
58 bool hsync_pol;
59 bool interlace;
60};
61
62struct hdmi_cm { 45struct hdmi_cm {
63 int code; 46 int code;
64 int mode; 47 int mode;
65}; 48};
66 49
67struct hdmi_config { 50struct hdmi_config {
68 struct hdmi_video_timings timings; 51 struct omap_video_timings timings;
69 struct hdmi_cm cm; 52 struct hdmi_cm cm;
70}; 53};
71 54
@@ -177,7 +160,7 @@ struct hdmi_ip_data {
177 160
178 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ 161 /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
179 int hpd_gpio; 162 int hpd_gpio;
180 bool phy_tx_enabled; 163 struct mutex lock;
181}; 164};
182int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); 165int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
183void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); 166void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 4dae1b291079..c23b85a20cdc 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -157,6 +157,10 @@ static int hdmi_pll_init(struct hdmi_ip_data *ip_data)
157/* PHY_PWR_CMD */ 157/* PHY_PWR_CMD */
158static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val) 158static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val)
159{ 159{
160 /* Return if already the state */
161 if (REG_GET(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, 5, 4) == val)
162 return 0;
163
160 /* Command for power control of HDMI PHY */ 164 /* Command for power control of HDMI PHY */
161 REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6); 165 REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6);
162 166
@@ -231,21 +235,13 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
231 235
232static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data) 236static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
233{ 237{
234 unsigned long flags;
235 bool hpd; 238 bool hpd;
236 int r; 239 int r;
237 /* this should be in ti_hdmi_4xxx_ip private data */
238 static DEFINE_SPINLOCK(phy_tx_lock);
239 240
240 spin_lock_irqsave(&phy_tx_lock, flags); 241 mutex_lock(&ip_data->lock);
241 242
242 hpd = gpio_get_value(ip_data->hpd_gpio); 243 hpd = gpio_get_value(ip_data->hpd_gpio);
243 244
244 if (hpd == ip_data->phy_tx_enabled) {
245 spin_unlock_irqrestore(&phy_tx_lock, flags);
246 return 0;
247 }
248
249 if (hpd) 245 if (hpd)
250 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); 246 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
251 else 247 else
@@ -257,9 +253,8 @@ static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
257 goto err; 253 goto err;
258 } 254 }
259 255
260 ip_data->phy_tx_enabled = hpd;
261err: 256err:
262 spin_unlock_irqrestore(&phy_tx_lock, flags); 257 mutex_unlock(&ip_data->lock);
263 return r; 258 return r;
264} 259}
265 260
@@ -327,7 +322,6 @@ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
327 free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data); 322 free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
328 323
329 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); 324 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
330 ip_data->phy_tx_enabled = false;
331} 325}
332 326
333static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) 327static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
@@ -747,11 +741,15 @@ static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
747static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) 741static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data)
748{ 742{
749 u32 r; 743 u32 r;
744 bool vsync_pol, hsync_pol;
750 pr_debug("Enter hdmi_wp_video_config_interface\n"); 745 pr_debug("Enter hdmi_wp_video_config_interface\n");
751 746
747 vsync_pol = ip_data->cfg.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
748 hsync_pol = ip_data->cfg.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
749
752 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); 750 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
753 r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7); 751 r = FLD_MOD(r, vsync_pol, 7, 7);
754 r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6); 752 r = FLD_MOD(r, hsync_pol, 6, 6);
755 r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); 753 r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3);
756 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ 754 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */
757 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); 755 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3907c8b6ecbc..3a220877461a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -272,6 +272,8 @@ const struct omap_video_timings omap_dss_pal_timings = {
272 .vsw = 5, 272 .vsw = 5,
273 .vfp = 5, 273 .vfp = 5,
274 .vbp = 41, 274 .vbp = 41,
275
276 .interlace = true,
275}; 277};
276EXPORT_SYMBOL(omap_dss_pal_timings); 278EXPORT_SYMBOL(omap_dss_pal_timings);
277 279
@@ -285,6 +287,8 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
285 .vsw = 6, 287 .vsw = 6,
286 .vfp = 6, 288 .vfp = 6,
287 .vbp = 31, 289 .vbp = 31,
290
291 .interlace = true,
288}; 292};
289EXPORT_SYMBOL(omap_dss_ntsc_timings); 293EXPORT_SYMBOL(omap_dss_ntsc_timings);
290 294
@@ -930,7 +934,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
930static int venc_runtime_suspend(struct device *dev) 934static int venc_runtime_suspend(struct device *dev)
931{ 935{
932 if (venc.tv_dac_clk) 936 if (venc.tv_dac_clk)
933 clk_disable(venc.tv_dac_clk); 937 clk_disable_unprepare(venc.tv_dac_clk);
934 938
935 dispc_runtime_put(); 939 dispc_runtime_put();
936 940
@@ -946,7 +950,7 @@ static int venc_runtime_resume(struct device *dev)
946 return r; 950 return r;
947 951
948 if (venc.tv_dac_clk) 952 if (venc.tv_dac_clk)
949 clk_enable(venc.tv_dac_clk); 953 clk_prepare_enable(venc.tv_dac_clk);
950 954
951 return 0; 955 return 0;
952} 956}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 3450ea0966c9..08ec1a7103f2 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -733,6 +733,12 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
733 var->lower_margin = timings.vfp; 733 var->lower_margin = timings.vfp;
734 var->hsync_len = timings.hsw; 734 var->hsync_len = timings.hsw;
735 var->vsync_len = timings.vsw; 735 var->vsync_len = timings.vsw;
736 var->sync |= timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH ?
737 FB_SYNC_HOR_HIGH_ACT : 0;
738 var->sync |= timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH ?
739 FB_SYNC_VERT_HIGH_ACT : 0;
740 var->vmode = timings.interlace ?
741 FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
736 } else { 742 } else {
737 var->pixclock = 0; 743 var->pixclock = 0;
738 var->left_margin = 0; 744 var->left_margin = 0;
@@ -741,12 +747,10 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
741 var->lower_margin = 0; 747 var->lower_margin = 0;
742 var->hsync_len = 0; 748 var->hsync_len = 0;
743 var->vsync_len = 0; 749 var->vsync_len = 0;
750 var->sync = 0;
751 var->vmode = FB_VMODE_NONINTERLACED;
744 } 752 }
745 753
746 /* TODO: get these from panel->config */
747 var->vmode = FB_VMODE_NONINTERLACED;
748 var->sync = 0;
749
750 return 0; 754 return 0;
751} 755}
752 756
@@ -1993,6 +1997,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1993} 1997}
1994 1998
1995static int omapfb_mode_to_timings(const char *mode_str, 1999static int omapfb_mode_to_timings(const char *mode_str,
2000 struct omap_dss_device *display,
1996 struct omap_video_timings *timings, u8 *bpp) 2001 struct omap_video_timings *timings, u8 *bpp)
1997{ 2002{
1998 struct fb_info *fbi; 2003 struct fb_info *fbi;
@@ -2046,6 +2051,14 @@ static int omapfb_mode_to_timings(const char *mode_str,
2046 goto err; 2051 goto err;
2047 } 2052 }
2048 2053
2054 if (display->driver->get_timings) {
2055 display->driver->get_timings(display, timings);
2056 } else {
2057 timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
2058 timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
2059 timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
2060 }
2061
2049 timings->pixel_clock = PICOS2KHZ(var->pixclock); 2062 timings->pixel_clock = PICOS2KHZ(var->pixclock);
2050 timings->hbp = var->left_margin; 2063 timings->hbp = var->left_margin;
2051 timings->hfp = var->right_margin; 2064 timings->hfp = var->right_margin;
@@ -2055,6 +2068,13 @@ static int omapfb_mode_to_timings(const char *mode_str,
2055 timings->vsw = var->vsync_len; 2068 timings->vsw = var->vsync_len;
2056 timings->x_res = var->xres; 2069 timings->x_res = var->xres;
2057 timings->y_res = var->yres; 2070 timings->y_res = var->yres;
2071 timings->hsync_level = var->sync & FB_SYNC_HOR_HIGH_ACT ?
2072 OMAPDSS_SIG_ACTIVE_HIGH :
2073 OMAPDSS_SIG_ACTIVE_LOW;
2074 timings->vsync_level = var->sync & FB_SYNC_VERT_HIGH_ACT ?
2075 OMAPDSS_SIG_ACTIVE_HIGH :
2076 OMAPDSS_SIG_ACTIVE_LOW;
2077 timings->interlace = var->vmode & FB_VMODE_INTERLACED;
2058 2078
2059 switch (var->bits_per_pixel) { 2079 switch (var->bits_per_pixel) {
2060 case 16: 2080 case 16:
@@ -2085,7 +2105,7 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2085 struct omap_video_timings timings, temp_timings; 2105 struct omap_video_timings timings, temp_timings;
2086 struct omapfb_display_data *d; 2106 struct omapfb_display_data *d;
2087 2107
2088 r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2108 r = omapfb_mode_to_timings(mode_str, display, &timings, &bpp);
2089 if (r) 2109 if (r)
2090 return r; 2110 return r;
2091 2111
@@ -2178,8 +2198,17 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2178} 2198}
2179 2199
2180static void fb_videomode_to_omap_timings(struct fb_videomode *m, 2200static void fb_videomode_to_omap_timings(struct fb_videomode *m,
2201 struct omap_dss_device *display,
2181 struct omap_video_timings *t) 2202 struct omap_video_timings *t)
2182{ 2203{
2204 if (display->driver->get_timings) {
2205 display->driver->get_timings(display, t);
2206 } else {
2207 t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
2208 t->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
2209 t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
2210 }
2211
2183 t->x_res = m->xres; 2212 t->x_res = m->xres;
2184 t->y_res = m->yres; 2213 t->y_res = m->yres;
2185 t->pixel_clock = PICOS2KHZ(m->pixclock); 2214 t->pixel_clock = PICOS2KHZ(m->pixclock);
@@ -2189,6 +2218,13 @@ static void fb_videomode_to_omap_timings(struct fb_videomode *m,
2189 t->vsw = m->vsync_len; 2218 t->vsw = m->vsync_len;
2190 t->vfp = m->lower_margin; 2219 t->vfp = m->lower_margin;
2191 t->vbp = m->upper_margin; 2220 t->vbp = m->upper_margin;
2221 t->hsync_level = m->sync & FB_SYNC_HOR_HIGH_ACT ?
2222 OMAPDSS_SIG_ACTIVE_HIGH :
2223 OMAPDSS_SIG_ACTIVE_LOW;
2224 t->vsync_level = m->sync & FB_SYNC_VERT_HIGH_ACT ?
2225 OMAPDSS_SIG_ACTIVE_HIGH :
2226 OMAPDSS_SIG_ACTIVE_LOW;
2227 t->interlace = m->vmode & FB_VMODE_INTERLACED;
2192} 2228}
2193 2229
2194static int omapfb_find_best_mode(struct omap_dss_device *display, 2230static int omapfb_find_best_mode(struct omap_dss_device *display,
@@ -2231,7 +2267,7 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
2231 if (m->xres == 2880 || m->xres == 1440) 2267 if (m->xres == 2880 || m->xres == 1440)
2232 continue; 2268 continue;
2233 2269
2234 fb_videomode_to_omap_timings(m, &t); 2270 fb_videomode_to_omap_timings(m, display, &t);
2235 2271
2236 r = display->driver->check_timings(display, &t); 2272 r = display->driver->check_timings(display, &t);
2237 if (r == 0 && best_xres < m->xres) { 2273 if (r == 0 && best_xres < m->xres) {
@@ -2245,7 +2281,8 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
2245 goto err2; 2281 goto err2;
2246 } 2282 }
2247 2283
2248 fb_videomode_to_omap_timings(&specs->modedb[best_idx], timings); 2284 fb_videomode_to_omap_timings(&specs->modedb[best_idx], display,
2285 timings);
2249 2286
2250 r = 0; 2287 r = 0;
2251 2288
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 2c80246b18b8..1d007366b917 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -84,7 +84,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
84 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", 84 "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
85 "S3 Virge/GX2", "S3 Virge/GX2+", "", 85 "S3 Virge/GX2", "S3 Virge/GX2+", "",
86 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X", 86 "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X",
87 "S3 Trio3D"}; 87 "S3 Trio3D", "S3 Virge/MX"};
88 88
89#define CHIP_UNKNOWN 0x00 89#define CHIP_UNKNOWN 0x00
90#define CHIP_732_TRIO32 0x01 90#define CHIP_732_TRIO32 0x01
@@ -105,6 +105,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
105#define CHIP_362_TRIO3D_2X 0x11 105#define CHIP_362_TRIO3D_2X 0x11
106#define CHIP_368_TRIO3D_2X 0x12 106#define CHIP_368_TRIO3D_2X 0x12
107#define CHIP_365_TRIO3D 0x13 107#define CHIP_365_TRIO3D 0x13
108#define CHIP_260_VIRGE_MX 0x14
108 109
109#define CHIP_XXX_TRIO 0x80 110#define CHIP_XXX_TRIO 0x80
110#define CHIP_XXX_TRIO64V2_DXGX 0x81 111#define CHIP_XXX_TRIO64V2_DXGX 0x81
@@ -280,7 +281,8 @@ static int __devinit s3fb_setup_ddc_bus(struct fb_info *info)
280 */ 281 */
281/* vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */ 282/* vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */
282 if (par->chip == CHIP_357_VIRGE_GX2 || 283 if (par->chip == CHIP_357_VIRGE_GX2 ||
283 par->chip == CHIP_359_VIRGE_GX2P) 284 par->chip == CHIP_359_VIRGE_GX2P ||
285 par->chip == CHIP_260_VIRGE_MX)
284 svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03); 286 svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03);
285 else 287 else
286 svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03); 288 svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03);
@@ -487,7 +489,8 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
487 par->chip == CHIP_359_VIRGE_GX2P || 489 par->chip == CHIP_359_VIRGE_GX2P ||
488 par->chip == CHIP_360_TRIO3D_1X || 490 par->chip == CHIP_360_TRIO3D_1X ||
489 par->chip == CHIP_362_TRIO3D_2X || 491 par->chip == CHIP_362_TRIO3D_2X ||
490 par->chip == CHIP_368_TRIO3D_2X) { 492 par->chip == CHIP_368_TRIO3D_2X ||
493 par->chip == CHIP_260_VIRGE_MX) {
491 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ 494 vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */
492 vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */ 495 vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */
493 } else 496 } else
@@ -690,7 +693,8 @@ static int s3fb_set_par(struct fb_info *info)
690 par->chip != CHIP_359_VIRGE_GX2P && 693 par->chip != CHIP_359_VIRGE_GX2P &&
691 par->chip != CHIP_360_TRIO3D_1X && 694 par->chip != CHIP_360_TRIO3D_1X &&
692 par->chip != CHIP_362_TRIO3D_2X && 695 par->chip != CHIP_362_TRIO3D_2X &&
693 par->chip != CHIP_368_TRIO3D_2X) { 696 par->chip != CHIP_368_TRIO3D_2X &&
697 par->chip != CHIP_260_VIRGE_MX) {
694 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */ 698 vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */
695 vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */ 699 vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */
696 vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */ 700 vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */
@@ -739,7 +743,8 @@ static int s3fb_set_par(struct fb_info *info)
739 par->chip == CHIP_368_TRIO3D_2X || 743 par->chip == CHIP_368_TRIO3D_2X ||
740 par->chip == CHIP_365_TRIO3D || 744 par->chip == CHIP_365_TRIO3D ||
741 par->chip == CHIP_375_VIRGE_DX || 745 par->chip == CHIP_375_VIRGE_DX ||
742 par->chip == CHIP_385_VIRGE_GX) { 746 par->chip == CHIP_385_VIRGE_GX ||
747 par->chip == CHIP_260_VIRGE_MX) {
743 dbytes = info->var.xres * ((bpp+7)/8); 748 dbytes = info->var.xres * ((bpp+7)/8);
744 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8); 749 vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8);
745 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); 750 vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80);
@@ -751,7 +756,8 @@ static int s3fb_set_par(struct fb_info *info)
751 par->chip == CHIP_359_VIRGE_GX2P || 756 par->chip == CHIP_359_VIRGE_GX2P ||
752 par->chip == CHIP_360_TRIO3D_1X || 757 par->chip == CHIP_360_TRIO3D_1X ||
753 par->chip == CHIP_362_TRIO3D_2X || 758 par->chip == CHIP_362_TRIO3D_2X ||
754 par->chip == CHIP_368_TRIO3D_2X) 759 par->chip == CHIP_368_TRIO3D_2X ||
760 par->chip == CHIP_260_VIRGE_MX)
755 vga_wcrt(par->state.vgabase, 0x34, 0x00); 761 vga_wcrt(par->state.vgabase, 0x34, 0x00);
756 else /* enable Data Transfer Position Control (DTPC) */ 762 else /* enable Data Transfer Position Control (DTPC) */
757 vga_wcrt(par->state.vgabase, 0x34, 0x10); 763 vga_wcrt(par->state.vgabase, 0x34, 0x10);
@@ -807,7 +813,8 @@ static int s3fb_set_par(struct fb_info *info)
807 par->chip == CHIP_359_VIRGE_GX2P || 813 par->chip == CHIP_359_VIRGE_GX2P ||
808 par->chip == CHIP_360_TRIO3D_1X || 814 par->chip == CHIP_360_TRIO3D_1X ||
809 par->chip == CHIP_362_TRIO3D_2X || 815 par->chip == CHIP_362_TRIO3D_2X ||
810 par->chip == CHIP_368_TRIO3D_2X) 816 par->chip == CHIP_368_TRIO3D_2X ||
817 par->chip == CHIP_260_VIRGE_MX)
811 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); 818 svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0);
812 else { 819 else {
813 svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0); 820 svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0);
@@ -837,7 +844,8 @@ static int s3fb_set_par(struct fb_info *info)
837 par->chip != CHIP_359_VIRGE_GX2P && 844 par->chip != CHIP_359_VIRGE_GX2P &&
838 par->chip != CHIP_360_TRIO3D_1X && 845 par->chip != CHIP_360_TRIO3D_1X &&
839 par->chip != CHIP_362_TRIO3D_2X && 846 par->chip != CHIP_362_TRIO3D_2X &&
840 par->chip != CHIP_368_TRIO3D_2X) 847 par->chip != CHIP_368_TRIO3D_2X &&
848 par->chip != CHIP_260_VIRGE_MX)
841 hmul = 2; 849 hmul = 2;
842 } 850 }
843 break; 851 break;
@@ -864,7 +872,8 @@ static int s3fb_set_par(struct fb_info *info)
864 par->chip != CHIP_359_VIRGE_GX2P && 872 par->chip != CHIP_359_VIRGE_GX2P &&
865 par->chip != CHIP_360_TRIO3D_1X && 873 par->chip != CHIP_360_TRIO3D_1X &&
866 par->chip != CHIP_362_TRIO3D_2X && 874 par->chip != CHIP_362_TRIO3D_2X &&
867 par->chip != CHIP_368_TRIO3D_2X) 875 par->chip != CHIP_368_TRIO3D_2X &&
876 par->chip != CHIP_260_VIRGE_MX)
868 hmul = 2; 877 hmul = 2;
869 } 878 }
870 break; 879 break;
@@ -1208,7 +1217,8 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1208 break; 1217 break;
1209 } 1218 }
1210 } else if (par->chip == CHIP_357_VIRGE_GX2 || 1219 } else if (par->chip == CHIP_357_VIRGE_GX2 ||
1211 par->chip == CHIP_359_VIRGE_GX2P) { 1220 par->chip == CHIP_359_VIRGE_GX2P ||
1221 par->chip == CHIP_260_VIRGE_MX) {
1212 switch ((regval & 0xC0) >> 6) { 1222 switch ((regval & 0xC0) >> 6) {
1213 case 1: /* 4MB */ 1223 case 1: /* 4MB */
1214 info->screen_size = 4 << 20; 1224 info->screen_size = 4 << 20;
@@ -1515,6 +1525,7 @@ static struct pci_device_id s3_devices[] __devinitdata = {
1515 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, 1525 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
1516 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, 1526 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X},
1517 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D}, 1527 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D},
1528 {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8C01), .driver_data = CHIP_260_VIRGE_MX},
1518 1529
1519 {0, 0, 0, 0, 0, 0, 0} 1530 {0, 0, 0, 0, 0, 0, 0}
1520}; 1531};
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 4c6b84488561..3951fdae5f68 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -127,8 +127,7 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
127 sh_mipi_dsi_enable(mipi, false); 127 sh_mipi_dsi_enable(mipi, false);
128} 128}
129 129
130static int __init sh_mipi_setup(struct sh_mipi *mipi, 130static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
131 struct sh_mipi_dsi_info *pdata)
132{ 131{
133 void __iomem *base = mipi->base; 132 void __iomem *base = mipi->base;
134 struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; 133 struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan;
@@ -551,7 +550,7 @@ efindslot:
551 return ret; 550 return ret;
552} 551}
553 552
554static int __exit sh_mipi_remove(struct platform_device *pdev) 553static int __devexit sh_mipi_remove(struct platform_device *pdev)
555{ 554{
556 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 555 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
557 struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 556 struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -592,7 +591,7 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
592} 591}
593 592
594static struct platform_driver sh_mipi_driver = { 593static struct platform_driver sh_mipi_driver = {
595 .remove = __exit_p(sh_mipi_remove), 594 .remove = __devexit_p(sh_mipi_remove),
596 .shutdown = sh_mipi_shutdown, 595 .shutdown = sh_mipi_shutdown,
597 .driver = { 596 .driver = {
598 .name = "sh-mipi-dsi", 597 .name = "sh-mipi-dsi",
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index e672698bd820..699487c287b2 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -12,6 +12,7 @@
12#include <linux/backlight.h> 12#include <linux/backlight.h>
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/console.h> 14#include <linux/console.h>
15#include <linux/ctype.h>
15#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/gpio.h> 18#include <linux/gpio.h>
@@ -32,12 +33,176 @@
32 33
33#include "sh_mobile_lcdcfb.h" 34#include "sh_mobile_lcdcfb.h"
34 35
36/* ----------------------------------------------------------------------------
37 * Overlay register definitions
38 */
39
40#define LDBCR 0xb00
41#define LDBCR_UPC(n) (1 << ((n) + 16))
42#define LDBCR_UPF(n) (1 << ((n) + 8))
43#define LDBCR_UPD(n) (1 << ((n) + 0))
44#define LDBnBSIFR(n) (0xb20 + (n) * 0x20 + 0x00)
45#define LDBBSIFR_EN (1 << 31)
46#define LDBBSIFR_VS (1 << 29)
47#define LDBBSIFR_BRSEL (1 << 28)
48#define LDBBSIFR_MX (1 << 27)
49#define LDBBSIFR_MY (1 << 26)
50#define LDBBSIFR_CV3 (3 << 24)
51#define LDBBSIFR_CV2 (2 << 24)
52#define LDBBSIFR_CV1 (1 << 24)
53#define LDBBSIFR_CV0 (0 << 24)
54#define LDBBSIFR_CV_MASK (3 << 24)
55#define LDBBSIFR_LAY_MASK (0xff << 16)
56#define LDBBSIFR_LAY_SHIFT 16
57#define LDBBSIFR_ROP3_MASK (0xff << 16)
58#define LDBBSIFR_ROP3_SHIFT 16
59#define LDBBSIFR_AL_PL8 (3 << 14)
60#define LDBBSIFR_AL_PL1 (2 << 14)
61#define LDBBSIFR_AL_PK (1 << 14)
62#define LDBBSIFR_AL_1 (0 << 14)
63#define LDBBSIFR_AL_MASK (3 << 14)
64#define LDBBSIFR_SWPL (1 << 10)
65#define LDBBSIFR_SWPW (1 << 9)
66#define LDBBSIFR_SWPB (1 << 8)
67#define LDBBSIFR_RY (1 << 7)
68#define LDBBSIFR_CHRR_420 (2 << 0)
69#define LDBBSIFR_CHRR_422 (1 << 0)
70#define LDBBSIFR_CHRR_444 (0 << 0)
71#define LDBBSIFR_RPKF_ARGB32 (0x00 << 0)
72#define LDBBSIFR_RPKF_RGB16 (0x03 << 0)
73#define LDBBSIFR_RPKF_RGB24 (0x0b << 0)
74#define LDBBSIFR_RPKF_MASK (0x1f << 0)
75#define LDBnBSSZR(n) (0xb20 + (n) * 0x20 + 0x04)
76#define LDBBSSZR_BVSS_MASK (0xfff << 16)
77#define LDBBSSZR_BVSS_SHIFT 16
78#define LDBBSSZR_BHSS_MASK (0xfff << 0)
79#define LDBBSSZR_BHSS_SHIFT 0
80#define LDBnBLOCR(n) (0xb20 + (n) * 0x20 + 0x08)
81#define LDBBLOCR_CVLC_MASK (0xfff << 16)
82#define LDBBLOCR_CVLC_SHIFT 16
83#define LDBBLOCR_CHLC_MASK (0xfff << 0)
84#define LDBBLOCR_CHLC_SHIFT 0
85#define LDBnBSMWR(n) (0xb20 + (n) * 0x20 + 0x0c)
86#define LDBBSMWR_BSMWA_MASK (0xffff << 16)
87#define LDBBSMWR_BSMWA_SHIFT 16
88#define LDBBSMWR_BSMW_MASK (0xffff << 0)
89#define LDBBSMWR_BSMW_SHIFT 0
90#define LDBnBSAYR(n) (0xb20 + (n) * 0x20 + 0x10)
91#define LDBBSAYR_FG1A_MASK (0xff << 24)
92#define LDBBSAYR_FG1A_SHIFT 24
93#define LDBBSAYR_FG1R_MASK (0xff << 16)
94#define LDBBSAYR_FG1R_SHIFT 16
95#define LDBBSAYR_FG1G_MASK (0xff << 8)
96#define LDBBSAYR_FG1G_SHIFT 8
97#define LDBBSAYR_FG1B_MASK (0xff << 0)
98#define LDBBSAYR_FG1B_SHIFT 0
99#define LDBnBSACR(n) (0xb20 + (n) * 0x20 + 0x14)
100#define LDBBSACR_FG2A_MASK (0xff << 24)
101#define LDBBSACR_FG2A_SHIFT 24
102#define LDBBSACR_FG2R_MASK (0xff << 16)
103#define LDBBSACR_FG2R_SHIFT 16
104#define LDBBSACR_FG2G_MASK (0xff << 8)
105#define LDBBSACR_FG2G_SHIFT 8
106#define LDBBSACR_FG2B_MASK (0xff << 0)
107#define LDBBSACR_FG2B_SHIFT 0
108#define LDBnBSAAR(n) (0xb20 + (n) * 0x20 + 0x18)
109#define LDBBSAAR_AP_MASK (0xff << 24)
110#define LDBBSAAR_AP_SHIFT 24
111#define LDBBSAAR_R_MASK (0xff << 16)
112#define LDBBSAAR_R_SHIFT 16
113#define LDBBSAAR_GY_MASK (0xff << 8)
114#define LDBBSAAR_GY_SHIFT 8
115#define LDBBSAAR_B_MASK (0xff << 0)
116#define LDBBSAAR_B_SHIFT 0
117#define LDBnBPPCR(n) (0xb20 + (n) * 0x20 + 0x1c)
118#define LDBBPPCR_AP_MASK (0xff << 24)
119#define LDBBPPCR_AP_SHIFT 24
120#define LDBBPPCR_R_MASK (0xff << 16)
121#define LDBBPPCR_R_SHIFT 16
122#define LDBBPPCR_GY_MASK (0xff << 8)
123#define LDBBPPCR_GY_SHIFT 8
124#define LDBBPPCR_B_MASK (0xff << 0)
125#define LDBBPPCR_B_SHIFT 0
126#define LDBnBBGCL(n) (0xb10 + (n) * 0x04)
127#define LDBBBGCL_BGA_MASK (0xff << 24)
128#define LDBBBGCL_BGA_SHIFT 24
129#define LDBBBGCL_BGR_MASK (0xff << 16)
130#define LDBBBGCL_BGR_SHIFT 16
131#define LDBBBGCL_BGG_MASK (0xff << 8)
132#define LDBBBGCL_BGG_SHIFT 8
133#define LDBBBGCL_BGB_MASK (0xff << 0)
134#define LDBBBGCL_BGB_SHIFT 0
135
35#define SIDE_B_OFFSET 0x1000 136#define SIDE_B_OFFSET 0x1000
36#define MIRROR_OFFSET 0x2000 137#define MIRROR_OFFSET 0x2000
37 138
38#define MAX_XRES 1920 139#define MAX_XRES 1920
39#define MAX_YRES 1080 140#define MAX_YRES 1080
40 141
142enum sh_mobile_lcdc_overlay_mode {
143 LCDC_OVERLAY_BLEND,
144 LCDC_OVERLAY_ROP3,
145};
146
147/*
148 * struct sh_mobile_lcdc_overlay - LCDC display overlay
149 *
150 * @channel: LCDC channel this overlay belongs to
151 * @cfg: Overlay configuration
152 * @info: Frame buffer device
153 * @index: Overlay index (0-3)
154 * @base: Overlay registers base address
155 * @enabled: True if the overlay is enabled
156 * @mode: Overlay blending mode (alpha blend or ROP3)
157 * @alpha: Global alpha blending value (0-255, for alpha blending mode)
158 * @rop3: Raster operation (for ROP3 mode)
159 * @fb_mem: Frame buffer virtual memory address
160 * @fb_size: Frame buffer size in bytes
161 * @dma_handle: Frame buffer DMA address
162 * @base_addr_y: Overlay base address (RGB or luma component)
163 * @base_addr_c: Overlay base address (chroma component)
164 * @pan_y_offset: Panning linear offset in bytes (luma component)
165 * @format: Current pixelf format
166 * @xres: Horizontal visible resolution
167 * @xres_virtual: Horizontal total resolution
168 * @yres: Vertical visible resolution
169 * @yres_virtual: Vertical total resolution
170 * @pitch: Overlay line pitch
171 * @pos_x: Horizontal overlay position
172 * @pos_y: Vertical overlay position
173 */
174struct sh_mobile_lcdc_overlay {
175 struct sh_mobile_lcdc_chan *channel;
176
177 const struct sh_mobile_lcdc_overlay_cfg *cfg;
178 struct fb_info *info;
179
180 unsigned int index;
181 unsigned long base;
182
183 bool enabled;
184 enum sh_mobile_lcdc_overlay_mode mode;
185 unsigned int alpha;
186 unsigned int rop3;
187
188 void *fb_mem;
189 unsigned long fb_size;
190
191 dma_addr_t dma_handle;
192 unsigned long base_addr_y;
193 unsigned long base_addr_c;
194 unsigned long pan_y_offset;
195
196 const struct sh_mobile_lcdc_format_info *format;
197 unsigned int xres;
198 unsigned int xres_virtual;
199 unsigned int yres;
200 unsigned int yres_virtual;
201 unsigned int pitch;
202 int pos_x;
203 int pos_y;
204};
205
41struct sh_mobile_lcdc_priv { 206struct sh_mobile_lcdc_priv {
42 void __iomem *base; 207 void __iomem *base;
43 int irq; 208 int irq;
@@ -45,7 +210,10 @@ struct sh_mobile_lcdc_priv {
45 struct device *dev; 210 struct device *dev;
46 struct clk *dot_clk; 211 struct clk *dot_clk;
47 unsigned long lddckr; 212 unsigned long lddckr;
213
48 struct sh_mobile_lcdc_chan ch[2]; 214 struct sh_mobile_lcdc_chan ch[2];
215 struct sh_mobile_lcdc_overlay overlays[4];
216
49 struct notifier_block notifier; 217 struct notifier_block notifier;
50 int started; 218 int started;
51 int forced_fourcc; /* 2 channel LCDC must share fourcc setting */ 219 int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
@@ -141,6 +309,13 @@ static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
141 return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]); 309 return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]);
142} 310}
143 311
312static void lcdc_write_overlay(struct sh_mobile_lcdc_overlay *ovl,
313 int reg, unsigned long data)
314{
315 iowrite32(data, ovl->channel->lcdc->base + reg);
316 iowrite32(data, ovl->channel->lcdc->base + reg + SIDE_B_OFFSET);
317}
318
144static void lcdc_write(struct sh_mobile_lcdc_priv *priv, 319static void lcdc_write(struct sh_mobile_lcdc_priv *priv,
145 unsigned long reg_offs, unsigned long data) 320 unsigned long reg_offs, unsigned long data)
146{ 321{
@@ -384,8 +559,8 @@ sh_mobile_lcdc_must_reconfigure(struct sh_mobile_lcdc_chan *ch,
384 return true; 559 return true;
385} 560}
386 561
387static int sh_mobile_check_var(struct fb_var_screeninfo *var, 562static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
388 struct fb_info *info); 563 struct fb_info *info);
389 564
390static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch, 565static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
391 enum sh_mobile_lcdc_entity_event event, 566 enum sh_mobile_lcdc_entity_event event,
@@ -439,7 +614,7 @@ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
439 fb_videomode_to_var(&var, mode); 614 fb_videomode_to_var(&var, mode);
440 var.bits_per_pixel = info->var.bits_per_pixel; 615 var.bits_per_pixel = info->var.bits_per_pixel;
441 var.grayscale = info->var.grayscale; 616 var.grayscale = info->var.grayscale;
442 ret = sh_mobile_check_var(&var, info); 617 ret = sh_mobile_lcdc_check_var(&var, info);
443 break; 618 break;
444 } 619 }
445 620
@@ -585,7 +760,7 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
585 return IRQ_HANDLED; 760 return IRQ_HANDLED;
586} 761}
587 762
588static int sh_mobile_wait_for_vsync(struct sh_mobile_lcdc_chan *ch) 763static int sh_mobile_lcdc_wait_for_vsync(struct sh_mobile_lcdc_chan *ch)
589{ 764{
590 unsigned long ldintr; 765 unsigned long ldintr;
591 int ret; 766 int ret;
@@ -685,8 +860,98 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
685 lcdc_write_chan(ch, LDHAJR, tmp); 860 lcdc_write_chan(ch, LDHAJR, tmp);
686} 861}
687 862
863static void sh_mobile_lcdc_overlay_setup(struct sh_mobile_lcdc_overlay *ovl)
864{
865 u32 format = 0;
866
867 if (!ovl->enabled) {
868 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index));
869 lcdc_write_overlay(ovl, LDBnBSIFR(ovl->index), 0);
870 lcdc_write(ovl->channel->lcdc, LDBCR,
871 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index));
872 return;
873 }
874
875 ovl->base_addr_y = ovl->dma_handle;
876 ovl->base_addr_c = ovl->dma_handle
877 + ovl->xres_virtual * ovl->yres_virtual;
878
879 switch (ovl->mode) {
880 case LCDC_OVERLAY_BLEND:
881 format = LDBBSIFR_EN | (ovl->alpha << LDBBSIFR_LAY_SHIFT);
882 break;
883
884 case LCDC_OVERLAY_ROP3:
885 format = LDBBSIFR_EN | LDBBSIFR_BRSEL
886 | (ovl->rop3 << LDBBSIFR_ROP3_SHIFT);
887 break;
888 }
889
890 switch (ovl->format->fourcc) {
891 case V4L2_PIX_FMT_RGB565:
892 case V4L2_PIX_FMT_NV21:
893 case V4L2_PIX_FMT_NV61:
894 case V4L2_PIX_FMT_NV42:
895 format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW;
896 break;
897 case V4L2_PIX_FMT_BGR24:
898 case V4L2_PIX_FMT_NV12:
899 case V4L2_PIX_FMT_NV16:
900 case V4L2_PIX_FMT_NV24:
901 format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB;
902 break;
903 case V4L2_PIX_FMT_BGR32:
904 default:
905 format |= LDBBSIFR_SWPL;
906 break;
907 }
908
909 switch (ovl->format->fourcc) {
910 case V4L2_PIX_FMT_RGB565:
911 format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16;
912 break;
913 case V4L2_PIX_FMT_BGR24:
914 format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24;
915 break;
916 case V4L2_PIX_FMT_BGR32:
917 format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
918 break;
919 case V4L2_PIX_FMT_NV12:
920 case V4L2_PIX_FMT_NV21:
921 format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420;
922 break;
923 case V4L2_PIX_FMT_NV16:
924 case V4L2_PIX_FMT_NV61:
925 format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_422;
926 break;
927 case V4L2_PIX_FMT_NV24:
928 case V4L2_PIX_FMT_NV42:
929 format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_444;
930 break;
931 }
932
933 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index));
934
935 lcdc_write_overlay(ovl, LDBnBSIFR(ovl->index), format);
936
937 lcdc_write_overlay(ovl, LDBnBSSZR(ovl->index),
938 (ovl->yres << LDBBSSZR_BVSS_SHIFT) |
939 (ovl->xres << LDBBSSZR_BHSS_SHIFT));
940 lcdc_write_overlay(ovl, LDBnBLOCR(ovl->index),
941 (ovl->pos_y << LDBBLOCR_CVLC_SHIFT) |
942 (ovl->pos_x << LDBBLOCR_CHLC_SHIFT));
943 lcdc_write_overlay(ovl, LDBnBSMWR(ovl->index),
944 ovl->pitch << LDBBSMWR_BSMW_SHIFT);
945
946 lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y);
947 lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c);
948
949 lcdc_write(ovl->channel->lcdc, LDBCR,
950 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index));
951}
952
688/* 953/*
689 * __sh_mobile_lcdc_start - Configure and tart the LCDC 954 * __sh_mobile_lcdc_start - Configure and start the LCDC
690 * @priv: LCDC device 955 * @priv: LCDC device
691 * 956 *
692 * Configure all enabled channels and start the LCDC device. All external 957 * Configure all enabled channels and start the LCDC device. All external
@@ -839,27 +1104,25 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
839 /* Compute frame buffer base address and pitch for each channel. */ 1104 /* Compute frame buffer base address and pitch for each channel. */
840 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 1105 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
841 int pixelformat; 1106 int pixelformat;
842 void *meram; 1107 void *cache;
843 1108
844 ch = &priv->ch[k]; 1109 ch = &priv->ch[k];
845 if (!ch->enabled) 1110 if (!ch->enabled)
846 continue; 1111 continue;
847 1112
848 ch->base_addr_y = ch->dma_handle; 1113 ch->base_addr_y = ch->dma_handle;
849 ch->base_addr_c = ch->base_addr_y + ch->xres * ch->yres_virtual; 1114 ch->base_addr_c = ch->dma_handle
1115 + ch->xres_virtual * ch->yres_virtual;
850 ch->line_size = ch->pitch; 1116 ch->line_size = ch->pitch;
851 1117
852 /* Enable MERAM if possible. */ 1118 /* Enable MERAM if possible. */
853 if (mdev == NULL || mdev->ops == NULL || 1119 if (mdev == NULL || ch->cfg->meram_cfg == NULL)
854 ch->cfg->meram_cfg == NULL)
855 continue; 1120 continue;
856 1121
857 /* we need to de-init configured ICBs before we can 1122 /* Free the allocated MERAM cache. */
858 * re-initialize them. 1123 if (ch->cache) {
859 */ 1124 sh_mobile_meram_cache_free(mdev, ch->cache);
860 if (ch->meram) { 1125 ch->cache = NULL;
861 mdev->ops->meram_unregister(mdev, ch->meram);
862 ch->meram = NULL;
863 } 1126 }
864 1127
865 switch (ch->format->fourcc) { 1128 switch (ch->format->fourcc) {
@@ -881,17 +1144,22 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
881 break; 1144 break;
882 } 1145 }
883 1146
884 meram = mdev->ops->meram_register(mdev, ch->cfg->meram_cfg, 1147 cache = sh_mobile_meram_cache_alloc(mdev, ch->cfg->meram_cfg,
885 ch->pitch, ch->yres, pixelformat, 1148 ch->pitch, ch->yres, pixelformat,
886 &ch->line_size); 1149 &ch->line_size);
887 if (!IS_ERR(meram)) { 1150 if (!IS_ERR(cache)) {
888 mdev->ops->meram_update(mdev, meram, 1151 sh_mobile_meram_cache_update(mdev, cache,
889 ch->base_addr_y, ch->base_addr_c, 1152 ch->base_addr_y, ch->base_addr_c,
890 &ch->base_addr_y, &ch->base_addr_c); 1153 &ch->base_addr_y, &ch->base_addr_c);
891 ch->meram = meram; 1154 ch->cache = cache;
892 } 1155 }
893 } 1156 }
894 1157
1158 for (k = 0; k < ARRAY_SIZE(priv->overlays); ++k) {
1159 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[k];
1160 sh_mobile_lcdc_overlay_setup(ovl);
1161 }
1162
895 /* Start the LCDC. */ 1163 /* Start the LCDC. */
896 __sh_mobile_lcdc_start(priv); 1164 __sh_mobile_lcdc_start(priv);
897 1165
@@ -953,12 +1221,10 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
953 1221
954 sh_mobile_lcdc_display_off(ch); 1222 sh_mobile_lcdc_display_off(ch);
955 1223
956 /* disable the meram */ 1224 /* Free the MERAM cache. */
957 if (ch->meram) { 1225 if (ch->cache) {
958 struct sh_mobile_meram_info *mdev; 1226 sh_mobile_meram_cache_free(priv->meram_dev, ch->cache);
959 mdev = priv->meram_dev; 1227 ch->cache = 0;
960 mdev->ops->meram_unregister(mdev, ch->meram);
961 ch->meram = 0;
962 } 1228 }
963 1229
964 } 1230 }
@@ -975,8 +1241,511 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
975 sh_mobile_lcdc_clk_off(priv); 1241 sh_mobile_lcdc_clk_off(priv);
976} 1242}
977 1243
1244static int __sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
1245 struct fb_info *info)
1246{
1247 if (var->xres > MAX_XRES || var->yres > MAX_YRES)
1248 return -EINVAL;
1249
1250 /* Make sure the virtual resolution is at least as big as the visible
1251 * resolution.
1252 */
1253 if (var->xres_virtual < var->xres)
1254 var->xres_virtual = var->xres;
1255 if (var->yres_virtual < var->yres)
1256 var->yres_virtual = var->yres;
1257
1258 if (sh_mobile_format_is_fourcc(var)) {
1259 const struct sh_mobile_lcdc_format_info *format;
1260
1261 format = sh_mobile_format_info(var->grayscale);
1262 if (format == NULL)
1263 return -EINVAL;
1264 var->bits_per_pixel = format->bpp;
1265
1266 /* Default to RGB and JPEG color-spaces for RGB and YUV formats
1267 * respectively.
1268 */
1269 if (!format->yuv)
1270 var->colorspace = V4L2_COLORSPACE_SRGB;
1271 else if (var->colorspace != V4L2_COLORSPACE_REC709)
1272 var->colorspace = V4L2_COLORSPACE_JPEG;
1273 } else {
1274 if (var->bits_per_pixel <= 16) { /* RGB 565 */
1275 var->bits_per_pixel = 16;
1276 var->red.offset = 11;
1277 var->red.length = 5;
1278 var->green.offset = 5;
1279 var->green.length = 6;
1280 var->blue.offset = 0;
1281 var->blue.length = 5;
1282 var->transp.offset = 0;
1283 var->transp.length = 0;
1284 } else if (var->bits_per_pixel <= 24) { /* RGB 888 */
1285 var->bits_per_pixel = 24;
1286 var->red.offset = 16;
1287 var->red.length = 8;
1288 var->green.offset = 8;
1289 var->green.length = 8;
1290 var->blue.offset = 0;
1291 var->blue.length = 8;
1292 var->transp.offset = 0;
1293 var->transp.length = 0;
1294 } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */
1295 var->bits_per_pixel = 32;
1296 var->red.offset = 16;
1297 var->red.length = 8;
1298 var->green.offset = 8;
1299 var->green.length = 8;
1300 var->blue.offset = 0;
1301 var->blue.length = 8;
1302 var->transp.offset = 24;
1303 var->transp.length = 8;
1304 } else
1305 return -EINVAL;
1306
1307 var->red.msb_right = 0;
1308 var->green.msb_right = 0;
1309 var->blue.msb_right = 0;
1310 var->transp.msb_right = 0;
1311 }
1312
1313 /* Make sure we don't exceed our allocated memory. */
1314 if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
1315 info->fix.smem_len)
1316 return -EINVAL;
1317
1318 return 0;
1319}
1320
978/* ----------------------------------------------------------------------------- 1321/* -----------------------------------------------------------------------------
979 * Frame buffer operations 1322 * Frame buffer operations - Overlays
1323 */
1324
1325static ssize_t
1326overlay_alpha_show(struct device *dev, struct device_attribute *attr, char *buf)
1327{
1328 struct fb_info *info = dev_get_drvdata(dev);
1329 struct sh_mobile_lcdc_overlay *ovl = info->par;
1330
1331 return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->alpha);
1332}
1333
1334static ssize_t
1335overlay_alpha_store(struct device *dev, struct device_attribute *attr,
1336 const char *buf, size_t count)
1337{
1338 struct fb_info *info = dev_get_drvdata(dev);
1339 struct sh_mobile_lcdc_overlay *ovl = info->par;
1340 unsigned int alpha;
1341 char *endp;
1342
1343 alpha = simple_strtoul(buf, &endp, 10);
1344 if (isspace(*endp))
1345 endp++;
1346
1347 if (endp - buf != count)
1348 return -EINVAL;
1349
1350 if (alpha > 255)
1351 return -EINVAL;
1352
1353 if (ovl->alpha != alpha) {
1354 ovl->alpha = alpha;
1355
1356 if (ovl->mode == LCDC_OVERLAY_BLEND && ovl->enabled)
1357 sh_mobile_lcdc_overlay_setup(ovl);
1358 }
1359
1360 return count;
1361}
1362
1363static ssize_t
1364overlay_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
1365{
1366 struct fb_info *info = dev_get_drvdata(dev);
1367 struct sh_mobile_lcdc_overlay *ovl = info->par;
1368
1369 return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->mode);
1370}
1371
1372static ssize_t
1373overlay_mode_store(struct device *dev, struct device_attribute *attr,
1374 const char *buf, size_t count)
1375{
1376 struct fb_info *info = dev_get_drvdata(dev);
1377 struct sh_mobile_lcdc_overlay *ovl = info->par;
1378 unsigned int mode;
1379 char *endp;
1380
1381 mode = simple_strtoul(buf, &endp, 10);
1382 if (isspace(*endp))
1383 endp++;
1384
1385 if (endp - buf != count)
1386 return -EINVAL;
1387
1388 if (mode != LCDC_OVERLAY_BLEND && mode != LCDC_OVERLAY_ROP3)
1389 return -EINVAL;
1390
1391 if (ovl->mode != mode) {
1392 ovl->mode = mode;
1393
1394 if (ovl->enabled)
1395 sh_mobile_lcdc_overlay_setup(ovl);
1396 }
1397
1398 return count;
1399}
1400
1401static ssize_t
1402overlay_position_show(struct device *dev, struct device_attribute *attr,
1403 char *buf)
1404{
1405 struct fb_info *info = dev_get_drvdata(dev);
1406 struct sh_mobile_lcdc_overlay *ovl = info->par;
1407
1408 return scnprintf(buf, PAGE_SIZE, "%d,%d\n", ovl->pos_x, ovl->pos_y);
1409}
1410
1411static ssize_t
1412overlay_position_store(struct device *dev, struct device_attribute *attr,
1413 const char *buf, size_t count)
1414{
1415 struct fb_info *info = dev_get_drvdata(dev);
1416 struct sh_mobile_lcdc_overlay *ovl = info->par;
1417 char *endp;
1418 int pos_x;
1419 int pos_y;
1420
1421 pos_x = simple_strtol(buf, &endp, 10);
1422 if (*endp != ',')
1423 return -EINVAL;
1424
1425 pos_y = simple_strtol(endp + 1, &endp, 10);
1426 if (isspace(*endp))
1427 endp++;
1428
1429 if (endp - buf != count)
1430 return -EINVAL;
1431
1432 if (ovl->pos_x != pos_x || ovl->pos_y != pos_y) {
1433 ovl->pos_x = pos_x;
1434 ovl->pos_y = pos_y;
1435
1436 if (ovl->enabled)
1437 sh_mobile_lcdc_overlay_setup(ovl);
1438 }
1439
1440 return count;
1441}
1442
1443static ssize_t
1444overlay_rop3_show(struct device *dev, struct device_attribute *attr, char *buf)
1445{
1446 struct fb_info *info = dev_get_drvdata(dev);
1447 struct sh_mobile_lcdc_overlay *ovl = info->par;
1448
1449 return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->rop3);
1450}
1451
1452static ssize_t
1453overlay_rop3_store(struct device *dev, struct device_attribute *attr,
1454 const char *buf, size_t count)
1455{
1456 struct fb_info *info = dev_get_drvdata(dev);
1457 struct sh_mobile_lcdc_overlay *ovl = info->par;
1458 unsigned int rop3;
1459 char *endp;
1460
1461 rop3 = !!simple_strtoul(buf, &endp, 10);
1462 if (isspace(*endp))
1463 endp++;
1464
1465 if (endp - buf != count)
1466 return -EINVAL;
1467
1468 if (rop3 > 255)
1469 return -EINVAL;
1470
1471 if (ovl->rop3 != rop3) {
1472 ovl->rop3 = rop3;
1473
1474 if (ovl->mode == LCDC_OVERLAY_ROP3 && ovl->enabled)
1475 sh_mobile_lcdc_overlay_setup(ovl);
1476 }
1477
1478 return count;
1479}
1480
1481static const struct device_attribute overlay_sysfs_attrs[] = {
1482 __ATTR(ovl_alpha, S_IRUGO|S_IWUSR,
1483 overlay_alpha_show, overlay_alpha_store),
1484 __ATTR(ovl_mode, S_IRUGO|S_IWUSR,
1485 overlay_mode_show, overlay_mode_store),
1486 __ATTR(ovl_position, S_IRUGO|S_IWUSR,
1487 overlay_position_show, overlay_position_store),
1488 __ATTR(ovl_rop3, S_IRUGO|S_IWUSR,
1489 overlay_rop3_show, overlay_rop3_store),
1490};
1491
1492static const struct fb_fix_screeninfo sh_mobile_lcdc_overlay_fix = {
1493 .id = "SH Mobile LCDC",
1494 .type = FB_TYPE_PACKED_PIXELS,
1495 .visual = FB_VISUAL_TRUECOLOR,
1496 .accel = FB_ACCEL_NONE,
1497 .xpanstep = 1,
1498 .ypanstep = 1,
1499 .ywrapstep = 0,
1500 .capabilities = FB_CAP_FOURCC,
1501};
1502
1503static int sh_mobile_lcdc_overlay_pan(struct fb_var_screeninfo *var,
1504 struct fb_info *info)
1505{
1506 struct sh_mobile_lcdc_overlay *ovl = info->par;
1507 unsigned long base_addr_y;
1508 unsigned long base_addr_c;
1509 unsigned long y_offset;
1510 unsigned long c_offset;
1511
1512 if (!ovl->format->yuv) {
1513 y_offset = (var->yoffset * ovl->xres_virtual + var->xoffset)
1514 * ovl->format->bpp / 8;
1515 c_offset = 0;
1516 } else {
1517 unsigned int xsub = ovl->format->bpp < 24 ? 2 : 1;
1518 unsigned int ysub = ovl->format->bpp < 16 ? 2 : 1;
1519
1520 y_offset = var->yoffset * ovl->xres_virtual + var->xoffset;
1521 c_offset = var->yoffset / ysub * ovl->xres_virtual * 2 / xsub
1522 + var->xoffset * 2 / xsub;
1523 }
1524
1525 /* If the Y offset hasn't changed, the C offset hasn't either. There's
1526 * nothing to do in that case.
1527 */
1528 if (y_offset == ovl->pan_y_offset)
1529 return 0;
1530
1531 /* Set the source address for the next refresh */
1532 base_addr_y = ovl->dma_handle + y_offset;
1533 base_addr_c = ovl->dma_handle + ovl->xres_virtual * ovl->yres_virtual
1534 + c_offset;
1535
1536 ovl->base_addr_y = base_addr_y;
1537 ovl->base_addr_c = base_addr_c;
1538 ovl->pan_y_offset = y_offset;
1539
1540 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index));
1541
1542 lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y);
1543 lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c);
1544
1545 lcdc_write(ovl->channel->lcdc, LDBCR,
1546 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index));
1547
1548 return 0;
1549}
1550
1551static int sh_mobile_lcdc_overlay_ioctl(struct fb_info *info, unsigned int cmd,
1552 unsigned long arg)
1553{
1554 struct sh_mobile_lcdc_overlay *ovl = info->par;
1555
1556 switch (cmd) {
1557 case FBIO_WAITFORVSYNC:
1558 return sh_mobile_lcdc_wait_for_vsync(ovl->channel);
1559
1560 default:
1561 return -ENOIOCTLCMD;
1562 }
1563}
1564
1565static int sh_mobile_lcdc_overlay_check_var(struct fb_var_screeninfo *var,
1566 struct fb_info *info)
1567{
1568 return __sh_mobile_lcdc_check_var(var, info);
1569}
1570
1571static int sh_mobile_lcdc_overlay_set_par(struct fb_info *info)
1572{
1573 struct sh_mobile_lcdc_overlay *ovl = info->par;
1574
1575 ovl->format =
1576 sh_mobile_format_info(sh_mobile_format_fourcc(&info->var));
1577
1578 ovl->xres = info->var.xres;
1579 ovl->xres_virtual = info->var.xres_virtual;
1580 ovl->yres = info->var.yres;
1581 ovl->yres_virtual = info->var.yres_virtual;
1582
1583 if (ovl->format->yuv)
1584 ovl->pitch = info->var.xres_virtual;
1585 else
1586 ovl->pitch = info->var.xres_virtual * ovl->format->bpp / 8;
1587
1588 sh_mobile_lcdc_overlay_setup(ovl);
1589
1590 info->fix.line_length = ovl->pitch;
1591
1592 if (sh_mobile_format_is_fourcc(&info->var)) {
1593 info->fix.type = FB_TYPE_FOURCC;
1594 info->fix.visual = FB_VISUAL_FOURCC;
1595 } else {
1596 info->fix.type = FB_TYPE_PACKED_PIXELS;
1597 info->fix.visual = FB_VISUAL_TRUECOLOR;
1598 }
1599
1600 return 0;
1601}
1602
1603/* Overlay blanking. Disable the overlay when blanked. */
1604static int sh_mobile_lcdc_overlay_blank(int blank, struct fb_info *info)
1605{
1606 struct sh_mobile_lcdc_overlay *ovl = info->par;
1607
1608 ovl->enabled = !blank;
1609 sh_mobile_lcdc_overlay_setup(ovl);
1610
1611 /* Prevent the backlight from receiving a blanking event by returning
1612 * a non-zero value.
1613 */
1614 return 1;
1615}
1616
1617static struct fb_ops sh_mobile_lcdc_overlay_ops = {
1618 .owner = THIS_MODULE,
1619 .fb_read = fb_sys_read,
1620 .fb_write = fb_sys_write,
1621 .fb_fillrect = sys_fillrect,
1622 .fb_copyarea = sys_copyarea,
1623 .fb_imageblit = sys_imageblit,
1624 .fb_blank = sh_mobile_lcdc_overlay_blank,
1625 .fb_pan_display = sh_mobile_lcdc_overlay_pan,
1626 .fb_ioctl = sh_mobile_lcdc_overlay_ioctl,
1627 .fb_check_var = sh_mobile_lcdc_overlay_check_var,
1628 .fb_set_par = sh_mobile_lcdc_overlay_set_par,
1629};
1630
1631static void
1632sh_mobile_lcdc_overlay_fb_unregister(struct sh_mobile_lcdc_overlay *ovl)
1633{
1634 struct fb_info *info = ovl->info;
1635
1636 if (info == NULL || info->dev == NULL)
1637 return;
1638
1639 unregister_framebuffer(ovl->info);
1640}
1641
1642static int __devinit
1643sh_mobile_lcdc_overlay_fb_register(struct sh_mobile_lcdc_overlay *ovl)
1644{
1645 struct sh_mobile_lcdc_priv *lcdc = ovl->channel->lcdc;
1646 struct fb_info *info = ovl->info;
1647 unsigned int i;
1648 int ret;
1649
1650 if (info == NULL)
1651 return 0;
1652
1653 ret = register_framebuffer(info);
1654 if (ret < 0)
1655 return ret;
1656
1657 dev_info(lcdc->dev, "registered %s/overlay %u as %dx%d %dbpp.\n",
1658 dev_name(lcdc->dev), ovl->index, info->var.xres,
1659 info->var.yres, info->var.bits_per_pixel);
1660
1661 for (i = 0; i < ARRAY_SIZE(overlay_sysfs_attrs); ++i) {
1662 ret = device_create_file(info->dev, &overlay_sysfs_attrs[i]);
1663 if (ret < 0)
1664 return ret;
1665 }
1666
1667 return 0;
1668}
1669
1670static void
1671sh_mobile_lcdc_overlay_fb_cleanup(struct sh_mobile_lcdc_overlay *ovl)
1672{
1673 struct fb_info *info = ovl->info;
1674
1675 if (info == NULL || info->device == NULL)
1676 return;
1677
1678 framebuffer_release(info);
1679}
1680
1681static int __devinit
1682sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl)
1683{
1684 struct sh_mobile_lcdc_priv *priv = ovl->channel->lcdc;
1685 struct fb_var_screeninfo *var;
1686 struct fb_info *info;
1687
1688 /* Allocate and initialize the frame buffer device. */
1689 info = framebuffer_alloc(0, priv->dev);
1690 if (info == NULL) {
1691 dev_err(priv->dev, "unable to allocate fb_info\n");
1692 return -ENOMEM;
1693 }
1694
1695 ovl->info = info;
1696
1697 info->flags = FBINFO_FLAG_DEFAULT;
1698 info->fbops = &sh_mobile_lcdc_overlay_ops;
1699 info->device = priv->dev;
1700 info->screen_base = ovl->fb_mem;
1701 info->par = ovl;
1702
1703 /* Initialize fixed screen information. Restrict pan to 2 lines steps
1704 * for NV12 and NV21.
1705 */
1706 info->fix = sh_mobile_lcdc_overlay_fix;
1707 snprintf(info->fix.id, sizeof(info->fix.id),
1708 "SH Mobile LCDC Overlay %u", ovl->index);
1709 info->fix.smem_start = ovl->dma_handle;
1710 info->fix.smem_len = ovl->fb_size;
1711 info->fix.line_length = ovl->pitch;
1712
1713 if (ovl->format->yuv)
1714 info->fix.visual = FB_VISUAL_FOURCC;
1715 else
1716 info->fix.visual = FB_VISUAL_TRUECOLOR;
1717
1718 switch (ovl->format->fourcc) {
1719 case V4L2_PIX_FMT_NV12:
1720 case V4L2_PIX_FMT_NV21:
1721 info->fix.ypanstep = 2;
1722 case V4L2_PIX_FMT_NV16:
1723 case V4L2_PIX_FMT_NV61:
1724 info->fix.xpanstep = 2;
1725 }
1726
1727 /* Initialize variable screen information. */
1728 var = &info->var;
1729 memset(var, 0, sizeof(*var));
1730 var->xres = ovl->xres;
1731 var->yres = ovl->yres;
1732 var->xres_virtual = ovl->xres_virtual;
1733 var->yres_virtual = ovl->yres_virtual;
1734 var->activate = FB_ACTIVATE_NOW;
1735
1736 /* Use the legacy API by default for RGB formats, and the FOURCC API
1737 * for YUV formats.
1738 */
1739 if (!ovl->format->yuv)
1740 var->bits_per_pixel = ovl->format->bpp;
1741 else
1742 var->grayscale = ovl->format->fourcc;
1743
1744 return sh_mobile_lcdc_overlay_check_var(var, info);
1745}
1746
1747/* -----------------------------------------------------------------------------
1748 * Frame buffer operations - main frame buffer
980 */ 1749 */
981 1750
982static int sh_mobile_lcdc_setcolreg(u_int regno, 1751static int sh_mobile_lcdc_setcolreg(u_int regno,
@@ -1003,12 +1772,12 @@ static int sh_mobile_lcdc_setcolreg(u_int regno,
1003 return 0; 1772 return 0;
1004} 1773}
1005 1774
1006static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { 1775static const struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
1007 .id = "SH Mobile LCDC", 1776 .id = "SH Mobile LCDC",
1008 .type = FB_TYPE_PACKED_PIXELS, 1777 .type = FB_TYPE_PACKED_PIXELS,
1009 .visual = FB_VISUAL_TRUECOLOR, 1778 .visual = FB_VISUAL_TRUECOLOR,
1010 .accel = FB_ACCEL_NONE, 1779 .accel = FB_ACCEL_NONE,
1011 .xpanstep = 0, 1780 .xpanstep = 1,
1012 .ypanstep = 1, 1781 .ypanstep = 1,
1013 .ywrapstep = 0, 1782 .ywrapstep = 0,
1014 .capabilities = FB_CAP_FOURCC, 1783 .capabilities = FB_CAP_FOURCC,
@@ -1035,78 +1804,74 @@ static void sh_mobile_lcdc_imageblit(struct fb_info *info,
1035 sh_mobile_lcdc_deferred_io_touch(info); 1804 sh_mobile_lcdc_deferred_io_touch(info);
1036} 1805}
1037 1806
1038static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var, 1807static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
1039 struct fb_info *info) 1808 struct fb_info *info)
1040{ 1809{
1041 struct sh_mobile_lcdc_chan *ch = info->par; 1810 struct sh_mobile_lcdc_chan *ch = info->par;
1042 struct sh_mobile_lcdc_priv *priv = ch->lcdc; 1811 struct sh_mobile_lcdc_priv *priv = ch->lcdc;
1043 unsigned long ldrcntr; 1812 unsigned long ldrcntr;
1044 unsigned long new_pan_offset;
1045 unsigned long base_addr_y, base_addr_c; 1813 unsigned long base_addr_y, base_addr_c;
1814 unsigned long y_offset;
1046 unsigned long c_offset; 1815 unsigned long c_offset;
1047 1816
1048 if (!ch->format->yuv) 1817 if (!ch->format->yuv) {
1049 new_pan_offset = var->yoffset * ch->pitch 1818 y_offset = (var->yoffset * ch->xres_virtual + var->xoffset)
1050 + var->xoffset * (ch->format->bpp / 8); 1819 * ch->format->bpp / 8;
1051 else 1820 c_offset = 0;
1052 new_pan_offset = var->yoffset * ch->pitch + var->xoffset; 1821 } else {
1822 unsigned int xsub = ch->format->bpp < 24 ? 2 : 1;
1823 unsigned int ysub = ch->format->bpp < 16 ? 2 : 1;
1053 1824
1054 if (new_pan_offset == ch->pan_offset) 1825 y_offset = var->yoffset * ch->xres_virtual + var->xoffset;
1055 return 0; /* No change, do nothing */ 1826 c_offset = var->yoffset / ysub * ch->xres_virtual * 2 / xsub
1827 + var->xoffset * 2 / xsub;
1828 }
1056 1829
1057 ldrcntr = lcdc_read(priv, _LDRCNTR); 1830 /* If the Y offset hasn't changed, the C offset hasn't either. There's
1831 * nothing to do in that case.
1832 */
1833 if (y_offset == ch->pan_y_offset)
1834 return 0;
1058 1835
1059 /* Set the source address for the next refresh */ 1836 /* Set the source address for the next refresh */
1060 base_addr_y = ch->dma_handle + new_pan_offset; 1837 base_addr_y = ch->dma_handle + y_offset;
1061 if (ch->format->yuv) { 1838 base_addr_c = ch->dma_handle + ch->xres_virtual * ch->yres_virtual
1062 /* Set y offset */ 1839 + c_offset;
1063 c_offset = var->yoffset * ch->pitch
1064 * (ch->format->bpp - 8) / 8;
1065 base_addr_c = ch->dma_handle + ch->xres * ch->yres_virtual
1066 + c_offset;
1067 /* Set x offset */
1068 if (ch->format->fourcc == V4L2_PIX_FMT_NV24)
1069 base_addr_c += 2 * var->xoffset;
1070 else
1071 base_addr_c += var->xoffset;
1072 }
1073 1840
1074 if (ch->meram) { 1841 if (ch->cache)
1075 struct sh_mobile_meram_info *mdev; 1842 sh_mobile_meram_cache_update(priv->meram_dev, ch->cache,
1076 1843 base_addr_y, base_addr_c,
1077 mdev = priv->meram_dev; 1844 &base_addr_y, &base_addr_c);
1078 mdev->ops->meram_update(mdev, ch->meram,
1079 base_addr_y, base_addr_c,
1080 &base_addr_y, &base_addr_c);
1081 }
1082 1845
1083 ch->base_addr_y = base_addr_y; 1846 ch->base_addr_y = base_addr_y;
1084 ch->base_addr_c = base_addr_c; 1847 ch->base_addr_c = base_addr_c;
1848 ch->pan_y_offset = y_offset;
1085 1849
1086 lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y); 1850 lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
1087 if (ch->format->yuv) 1851 if (ch->format->yuv)
1088 lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c); 1852 lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
1089 1853
1854 ldrcntr = lcdc_read(priv, _LDRCNTR);
1090 if (lcdc_chan_is_sublcd(ch)) 1855 if (lcdc_chan_is_sublcd(ch))
1091 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); 1856 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
1092 else 1857 else
1093 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS); 1858 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS);
1094 1859
1095 ch->pan_offset = new_pan_offset;
1096 1860
1097 sh_mobile_lcdc_deferred_io_touch(info); 1861 sh_mobile_lcdc_deferred_io_touch(info);
1098 1862
1099 return 0; 1863 return 0;
1100} 1864}
1101 1865
1102static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd, 1866static int sh_mobile_lcdc_ioctl(struct fb_info *info, unsigned int cmd,
1103 unsigned long arg) 1867 unsigned long arg)
1104{ 1868{
1869 struct sh_mobile_lcdc_chan *ch = info->par;
1105 int retval; 1870 int retval;
1106 1871
1107 switch (cmd) { 1872 switch (cmd) {
1108 case FBIO_WAITFORVSYNC: 1873 case FBIO_WAITFORVSYNC:
1109 retval = sh_mobile_wait_for_vsync(info->par); 1874 retval = sh_mobile_lcdc_wait_for_vsync(ch);
1110 break; 1875 break;
1111 1876
1112 default: 1877 default:
@@ -1158,7 +1923,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info)
1158 * Locking: both .fb_release() and .fb_open() are called with info->lock held if 1923 * Locking: both .fb_release() and .fb_open() are called with info->lock held if
1159 * user == 1, or with console sem held, if user == 0. 1924 * user == 1, or with console sem held, if user == 0.
1160 */ 1925 */
1161static int sh_mobile_release(struct fb_info *info, int user) 1926static int sh_mobile_lcdc_release(struct fb_info *info, int user)
1162{ 1927{
1163 struct sh_mobile_lcdc_chan *ch = info->par; 1928 struct sh_mobile_lcdc_chan *ch = info->par;
1164 1929
@@ -1179,7 +1944,7 @@ static int sh_mobile_release(struct fb_info *info, int user)
1179 return 0; 1944 return 0;
1180} 1945}
1181 1946
1182static int sh_mobile_open(struct fb_info *info, int user) 1947static int sh_mobile_lcdc_open(struct fb_info *info, int user)
1183{ 1948{
1184 struct sh_mobile_lcdc_chan *ch = info->par; 1949 struct sh_mobile_lcdc_chan *ch = info->par;
1185 1950
@@ -1192,7 +1957,8 @@ static int sh_mobile_open(struct fb_info *info, int user)
1192 return 0; 1957 return 0;
1193} 1958}
1194 1959
1195static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 1960static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
1961 struct fb_info *info)
1196{ 1962{
1197 struct sh_mobile_lcdc_chan *ch = info->par; 1963 struct sh_mobile_lcdc_chan *ch = info->par;
1198 struct sh_mobile_lcdc_priv *p = ch->lcdc; 1964 struct sh_mobile_lcdc_priv *p = ch->lcdc;
@@ -1200,9 +1966,7 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
1200 unsigned int best_xres = 0; 1966 unsigned int best_xres = 0;
1201 unsigned int best_yres = 0; 1967 unsigned int best_yres = 0;
1202 unsigned int i; 1968 unsigned int i;
1203 1969 int ret;
1204 if (var->xres > MAX_XRES || var->yres > MAX_YRES)
1205 return -EINVAL;
1206 1970
1207 /* If board code provides us with a list of available modes, make sure 1971 /* If board code provides us with a list of available modes, make sure
1208 * we use one of them. Find the mode closest to the requested one. The 1972 * we use one of them. Find the mode closest to the requested one. The
@@ -1237,73 +2001,9 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
1237 var->yres = best_yres; 2001 var->yres = best_yres;
1238 } 2002 }
1239 2003
1240 /* Make sure the virtual resolution is at least as big as the visible 2004 ret = __sh_mobile_lcdc_check_var(var, info);
1241 * resolution. 2005 if (ret < 0)
1242 */ 2006 return ret;
1243 if (var->xres_virtual < var->xres)
1244 var->xres_virtual = var->xres;
1245 if (var->yres_virtual < var->yres)
1246 var->yres_virtual = var->yres;
1247
1248 if (sh_mobile_format_is_fourcc(var)) {
1249 const struct sh_mobile_lcdc_format_info *format;
1250
1251 format = sh_mobile_format_info(var->grayscale);
1252 if (format == NULL)
1253 return -EINVAL;
1254 var->bits_per_pixel = format->bpp;
1255
1256 /* Default to RGB and JPEG color-spaces for RGB and YUV formats
1257 * respectively.
1258 */
1259 if (!format->yuv)
1260 var->colorspace = V4L2_COLORSPACE_SRGB;
1261 else if (var->colorspace != V4L2_COLORSPACE_REC709)
1262 var->colorspace = V4L2_COLORSPACE_JPEG;
1263 } else {
1264 if (var->bits_per_pixel <= 16) { /* RGB 565 */
1265 var->bits_per_pixel = 16;
1266 var->red.offset = 11;
1267 var->red.length = 5;
1268 var->green.offset = 5;
1269 var->green.length = 6;
1270 var->blue.offset = 0;
1271 var->blue.length = 5;
1272 var->transp.offset = 0;
1273 var->transp.length = 0;
1274 } else if (var->bits_per_pixel <= 24) { /* RGB 888 */
1275 var->bits_per_pixel = 24;
1276 var->red.offset = 16;
1277 var->red.length = 8;
1278 var->green.offset = 8;
1279 var->green.length = 8;
1280 var->blue.offset = 0;
1281 var->blue.length = 8;
1282 var->transp.offset = 0;
1283 var->transp.length = 0;
1284 } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */
1285 var->bits_per_pixel = 32;
1286 var->red.offset = 16;
1287 var->red.length = 8;
1288 var->green.offset = 8;
1289 var->green.length = 8;
1290 var->blue.offset = 0;
1291 var->blue.length = 8;
1292 var->transp.offset = 24;
1293 var->transp.length = 8;
1294 } else
1295 return -EINVAL;
1296
1297 var->red.msb_right = 0;
1298 var->green.msb_right = 0;
1299 var->blue.msb_right = 0;
1300 var->transp.msb_right = 0;
1301 }
1302
1303 /* Make sure we don't exceed our allocated memory. */
1304 if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
1305 info->fix.smem_len)
1306 return -EINVAL;
1307 2007
1308 /* only accept the forced_fourcc for dual channel configurations */ 2008 /* only accept the forced_fourcc for dual channel configurations */
1309 if (p->forced_fourcc && 2009 if (p->forced_fourcc &&
@@ -1313,7 +2013,7 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
1313 return 0; 2013 return 0;
1314} 2014}
1315 2015
1316static int sh_mobile_set_par(struct fb_info *info) 2016static int sh_mobile_lcdc_set_par(struct fb_info *info)
1317{ 2017{
1318 struct sh_mobile_lcdc_chan *ch = info->par; 2018 struct sh_mobile_lcdc_chan *ch = info->par;
1319 int ret; 2019 int ret;
@@ -1329,9 +2029,9 @@ static int sh_mobile_set_par(struct fb_info *info)
1329 ch->yres_virtual = info->var.yres_virtual; 2029 ch->yres_virtual = info->var.yres_virtual;
1330 2030
1331 if (ch->format->yuv) 2031 if (ch->format->yuv)
1332 ch->pitch = info->var.xres; 2032 ch->pitch = info->var.xres_virtual;
1333 else 2033 else
1334 ch->pitch = info->var.xres * ch->format->bpp / 8; 2034 ch->pitch = info->var.xres_virtual * ch->format->bpp / 8;
1335 2035
1336 ret = sh_mobile_lcdc_start(ch->lcdc); 2036 ret = sh_mobile_lcdc_start(ch->lcdc);
1337 if (ret < 0) 2037 if (ret < 0)
@@ -1383,8 +2083,8 @@ static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
1383 * mode will reenable the clocks and update the screen in time, 2083 * mode will reenable the clocks and update the screen in time,
1384 * so it does not need this. */ 2084 * so it does not need this. */
1385 if (!info->fbdefio) { 2085 if (!info->fbdefio) {
1386 sh_mobile_wait_for_vsync(ch); 2086 sh_mobile_lcdc_wait_for_vsync(ch);
1387 sh_mobile_wait_for_vsync(ch); 2087 sh_mobile_lcdc_wait_for_vsync(ch);
1388 } 2088 }
1389 sh_mobile_lcdc_clk_off(p); 2089 sh_mobile_lcdc_clk_off(p);
1390 } 2090 }
@@ -1402,12 +2102,12 @@ static struct fb_ops sh_mobile_lcdc_ops = {
1402 .fb_copyarea = sh_mobile_lcdc_copyarea, 2102 .fb_copyarea = sh_mobile_lcdc_copyarea,
1403 .fb_imageblit = sh_mobile_lcdc_imageblit, 2103 .fb_imageblit = sh_mobile_lcdc_imageblit,
1404 .fb_blank = sh_mobile_lcdc_blank, 2104 .fb_blank = sh_mobile_lcdc_blank,
1405 .fb_pan_display = sh_mobile_fb_pan_display, 2105 .fb_pan_display = sh_mobile_lcdc_pan,
1406 .fb_ioctl = sh_mobile_ioctl, 2106 .fb_ioctl = sh_mobile_lcdc_ioctl,
1407 .fb_open = sh_mobile_open, 2107 .fb_open = sh_mobile_lcdc_open,
1408 .fb_release = sh_mobile_release, 2108 .fb_release = sh_mobile_lcdc_release,
1409 .fb_check_var = sh_mobile_check_var, 2109 .fb_check_var = sh_mobile_lcdc_check_var,
1410 .fb_set_par = sh_mobile_set_par, 2110 .fb_set_par = sh_mobile_lcdc_set_par,
1411}; 2111};
1412 2112
1413static void 2113static void
@@ -1514,19 +2214,24 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
1514 else 2214 else
1515 info->fix.visual = FB_VISUAL_TRUECOLOR; 2215 info->fix.visual = FB_VISUAL_TRUECOLOR;
1516 2216
1517 if (ch->format->fourcc == V4L2_PIX_FMT_NV12 || 2217 switch (ch->format->fourcc) {
1518 ch->format->fourcc == V4L2_PIX_FMT_NV21) 2218 case V4L2_PIX_FMT_NV12:
2219 case V4L2_PIX_FMT_NV21:
1519 info->fix.ypanstep = 2; 2220 info->fix.ypanstep = 2;
2221 case V4L2_PIX_FMT_NV16:
2222 case V4L2_PIX_FMT_NV61:
2223 info->fix.xpanstep = 2;
2224 }
1520 2225
1521 /* Initialize variable screen information using the first mode as 2226 /* Initialize variable screen information using the first mode as
1522 * default. The default Y virtual resolution is twice the panel size to 2227 * default.
1523 * allow for double-buffering.
1524 */ 2228 */
1525 var = &info->var; 2229 var = &info->var;
1526 fb_videomode_to_var(var, mode); 2230 fb_videomode_to_var(var, mode);
1527 var->width = ch->cfg->panel_cfg.width; 2231 var->width = ch->cfg->panel_cfg.width;
1528 var->height = ch->cfg->panel_cfg.height; 2232 var->height = ch->cfg->panel_cfg.height;
1529 var->yres_virtual = var->yres * 2; 2233 var->xres_virtual = ch->xres_virtual;
2234 var->yres_virtual = ch->yres_virtual;
1530 var->activate = FB_ACTIVATE_NOW; 2235 var->activate = FB_ACTIVATE_NOW;
1531 2236
1532 /* Use the legacy API by default for RGB formats, and the FOURCC API 2237 /* Use the legacy API by default for RGB formats, and the FOURCC API
@@ -1537,7 +2242,7 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
1537 else 2242 else
1538 var->grayscale = ch->format->fourcc; 2243 var->grayscale = ch->format->fourcc;
1539 2244
1540 ret = sh_mobile_check_var(var, info); 2245 ret = sh_mobile_lcdc_check_var(var, info);
1541 if (ret) 2246 if (ret)
1542 return ret; 2247 return ret;
1543 2248
@@ -1712,15 +2417,27 @@ static const struct fb_videomode default_720p __devinitconst = {
1712static int sh_mobile_lcdc_remove(struct platform_device *pdev) 2417static int sh_mobile_lcdc_remove(struct platform_device *pdev)
1713{ 2418{
1714 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); 2419 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
1715 int i; 2420 unsigned int i;
1716 2421
1717 fb_unregister_client(&priv->notifier); 2422 fb_unregister_client(&priv->notifier);
1718 2423
2424 for (i = 0; i < ARRAY_SIZE(priv->overlays); i++)
2425 sh_mobile_lcdc_overlay_fb_unregister(&priv->overlays[i]);
1719 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) 2426 for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
1720 sh_mobile_lcdc_channel_fb_unregister(&priv->ch[i]); 2427 sh_mobile_lcdc_channel_fb_unregister(&priv->ch[i]);
1721 2428
1722 sh_mobile_lcdc_stop(priv); 2429 sh_mobile_lcdc_stop(priv);
1723 2430
2431 for (i = 0; i < ARRAY_SIZE(priv->overlays); i++) {
2432 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i];
2433
2434 sh_mobile_lcdc_overlay_fb_cleanup(ovl);
2435
2436 if (ovl->fb_mem)
2437 dma_free_coherent(&pdev->dev, ovl->fb_size,
2438 ovl->fb_mem, ovl->dma_handle);
2439 }
2440
1724 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { 2441 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
1725 struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; 2442 struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
1726 2443
@@ -1737,8 +2454,11 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
1737 } 2454 }
1738 2455
1739 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { 2456 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
1740 if (priv->ch[i].bl) 2457 struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
1741 sh_mobile_lcdc_bl_remove(priv->ch[i].bl); 2458
2459 if (ch->bl)
2460 sh_mobile_lcdc_bl_remove(ch->bl);
2461 mutex_destroy(&ch->open_lock);
1742 } 2462 }
1743 2463
1744 if (priv->dot_clk) { 2464 if (priv->dot_clk) {
@@ -1796,6 +2516,61 @@ static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *
1796} 2516}
1797 2517
1798static int __devinit 2518static int __devinit
2519sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
2520 struct sh_mobile_lcdc_overlay *ovl)
2521{
2522 const struct sh_mobile_lcdc_format_info *format;
2523 int ret;
2524
2525 if (ovl->cfg->fourcc == 0)
2526 return 0;
2527
2528 /* Validate the format. */
2529 format = sh_mobile_format_info(ovl->cfg->fourcc);
2530 if (format == NULL) {
2531 dev_err(priv->dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc);
2532 return -EINVAL;
2533 }
2534
2535 ovl->enabled = false;
2536 ovl->mode = LCDC_OVERLAY_BLEND;
2537 ovl->alpha = 255;
2538 ovl->rop3 = 0;
2539 ovl->pos_x = 0;
2540 ovl->pos_y = 0;
2541
2542 /* The default Y virtual resolution is twice the panel size to allow for
2543 * double-buffering.
2544 */
2545 ovl->format = format;
2546 ovl->xres = ovl->cfg->max_xres;
2547 ovl->xres_virtual = ovl->xres;
2548 ovl->yres = ovl->cfg->max_yres;
2549 ovl->yres_virtual = ovl->yres * 2;
2550
2551 if (!format->yuv)
2552 ovl->pitch = ovl->xres_virtual * format->bpp / 8;
2553 else
2554 ovl->pitch = ovl->xres_virtual;
2555
2556 /* Allocate frame buffer memory. */
2557 ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres
2558 * format->bpp / 8 * 2;
2559 ovl->fb_mem = dma_alloc_coherent(priv->dev, ovl->fb_size,
2560 &ovl->dma_handle, GFP_KERNEL);
2561 if (!ovl->fb_mem) {
2562 dev_err(priv->dev, "unable to allocate buffer\n");
2563 return -ENOMEM;
2564 }
2565
2566 ret = sh_mobile_lcdc_overlay_fb_init(ovl);
2567 if (ret < 0)
2568 return ret;
2569
2570 return 0;
2571}
2572
2573static int __devinit
1799sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, 2574sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
1800 struct sh_mobile_lcdc_chan *ch) 2575 struct sh_mobile_lcdc_chan *ch)
1801{ 2576{
@@ -1854,7 +2629,9 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
1854 num_modes = cfg->num_modes; 2629 num_modes = cfg->num_modes;
1855 } 2630 }
1856 2631
1857 /* Use the first mode as default. */ 2632 /* Use the first mode as default. The default Y virtual resolution is
2633 * twice the panel size to allow for double-buffering.
2634 */
1858 ch->format = format; 2635 ch->format = format;
1859 ch->xres = mode->xres; 2636 ch->xres = mode->xres;
1860 ch->xres_virtual = mode->xres; 2637 ch->xres_virtual = mode->xres;
@@ -1863,10 +2640,10 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
1863 2640
1864 if (!format->yuv) { 2641 if (!format->yuv) {
1865 ch->colorspace = V4L2_COLORSPACE_SRGB; 2642 ch->colorspace = V4L2_COLORSPACE_SRGB;
1866 ch->pitch = ch->xres * format->bpp / 8; 2643 ch->pitch = ch->xres_virtual * format->bpp / 8;
1867 } else { 2644 } else {
1868 ch->colorspace = V4L2_COLORSPACE_REC709; 2645 ch->colorspace = V4L2_COLORSPACE_REC709;
1869 ch->pitch = ch->xres; 2646 ch->pitch = ch->xres_virtual;
1870 } 2647 }
1871 2648
1872 ch->display.width = cfg->panel_cfg.width; 2649 ch->display.width = cfg->panel_cfg.width;
@@ -1952,7 +2729,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1952 } 2729 }
1953 init_waitqueue_head(&ch->frame_end_wait); 2730 init_waitqueue_head(&ch->frame_end_wait);
1954 init_completion(&ch->vsync_completion); 2731 init_completion(&ch->vsync_completion);
1955 ch->pan_offset = 0;
1956 2732
1957 /* probe the backlight is there is one defined */ 2733 /* probe the backlight is there is one defined */
1958 if (ch->cfg->bl_info.max_brightness) 2734 if (ch->cfg->bl_info.max_brightness)
@@ -2003,6 +2779,17 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
2003 goto err1; 2779 goto err1;
2004 } 2780 }
2005 2781
2782 for (i = 0; i < ARRAY_SIZE(pdata->overlays); i++) {
2783 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i];
2784
2785 ovl->cfg = &pdata->overlays[i];
2786 ovl->channel = &priv->ch[0];
2787
2788 error = sh_mobile_lcdc_overlay_init(priv, ovl);
2789 if (error)
2790 goto err1;
2791 }
2792
2006 error = sh_mobile_lcdc_start(priv); 2793 error = sh_mobile_lcdc_start(priv);
2007 if (error) { 2794 if (error) {
2008 dev_err(&pdev->dev, "unable to start hardware\n"); 2795 dev_err(&pdev->dev, "unable to start hardware\n");
@@ -2017,6 +2804,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
2017 goto err1; 2804 goto err1;
2018 } 2805 }
2019 2806
2807 for (i = 0; i < ARRAY_SIZE(pdata->overlays); i++) {
2808 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i];
2809
2810 error = sh_mobile_lcdc_overlay_fb_register(ovl);
2811 if (error)
2812 goto err1;
2813 }
2814
2020 /* Failure ignored */ 2815 /* Failure ignored */
2021 priv->notifier.notifier_call = sh_mobile_lcdc_notify; 2816 priv->notifier.notifier_call = sh_mobile_lcdc_notify;
2022 fb_register_client(&priv->notifier); 2817 fb_register_client(&priv->notifier);
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 5c3bddd2cb72..0f92f6544b94 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -47,6 +47,7 @@ struct sh_mobile_lcdc_entity {
47/* 47/*
48 * struct sh_mobile_lcdc_chan - LCDC display channel 48 * struct sh_mobile_lcdc_chan - LCDC display channel
49 * 49 *
50 * @pan_y_offset: Panning linear offset in bytes (luma component)
50 * @base_addr_y: Frame buffer viewport base address (luma component) 51 * @base_addr_y: Frame buffer viewport base address (luma component)
51 * @base_addr_c: Frame buffer viewport base address (chroma component) 52 * @base_addr_c: Frame buffer viewport base address (chroma component)
52 * @pitch: Frame buffer line pitch 53 * @pitch: Frame buffer line pitch
@@ -59,7 +60,7 @@ struct sh_mobile_lcdc_chan {
59 unsigned long *reg_offs; 60 unsigned long *reg_offs;
60 unsigned long ldmt1r_value; 61 unsigned long ldmt1r_value;
61 unsigned long enabled; /* ME and SE in LDCNT2R */ 62 unsigned long enabled; /* ME and SE in LDCNT2R */
62 void *meram; 63 void *cache;
63 64
64 struct mutex open_lock; /* protects the use counter */ 65 struct mutex open_lock; /* protects the use counter */
65 int use_count; 66 int use_count;
@@ -68,7 +69,7 @@ struct sh_mobile_lcdc_chan {
68 unsigned long fb_size; 69 unsigned long fb_size;
69 70
70 dma_addr_t dma_handle; 71 dma_addr_t dma_handle;
71 unsigned long pan_offset; 72 unsigned long pan_y_offset;
72 73
73 unsigned long frame_end; 74 unsigned long frame_end;
74 wait_queue_head_t frame_end_wait; 75 wait_queue_head_t frame_end_wait;
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 82ba830bf95d..7a0ba8bb3fbe 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/export.h>
14#include <linux/genalloc.h> 15#include <linux/genalloc.h>
15#include <linux/io.h> 16#include <linux/io.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
@@ -194,13 +195,28 @@ static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off)
194} 195}
195 196
196/* ----------------------------------------------------------------------------- 197/* -----------------------------------------------------------------------------
197 * Allocation 198 * MERAM allocation and free
199 */
200
201static unsigned long meram_alloc(struct sh_mobile_meram_priv *priv, size_t size)
202{
203 return gen_pool_alloc(priv->pool, size);
204}
205
206static void meram_free(struct sh_mobile_meram_priv *priv, unsigned long mem,
207 size_t size)
208{
209 gen_pool_free(priv->pool, mem, size);
210}
211
212/* -----------------------------------------------------------------------------
213 * LCDC cache planes allocation, init, cleanup and free
198 */ 214 */
199 215
200/* Allocate ICBs and MERAM for a plane. */ 216/* Allocate ICBs and MERAM for a plane. */
201static int __meram_alloc(struct sh_mobile_meram_priv *priv, 217static int meram_plane_alloc(struct sh_mobile_meram_priv *priv,
202 struct sh_mobile_meram_fb_plane *plane, 218 struct sh_mobile_meram_fb_plane *plane,
203 size_t size) 219 size_t size)
204{ 220{
205 unsigned long mem; 221 unsigned long mem;
206 unsigned long idx; 222 unsigned long idx;
@@ -215,7 +231,7 @@ static int __meram_alloc(struct sh_mobile_meram_priv *priv,
215 return -ENOMEM; 231 return -ENOMEM;
216 plane->marker = &priv->icbs[idx]; 232 plane->marker = &priv->icbs[idx];
217 233
218 mem = gen_pool_alloc(priv->pool, size * 1024); 234 mem = meram_alloc(priv, size * 1024);
219 if (mem == 0) 235 if (mem == 0)
220 return -ENOMEM; 236 return -ENOMEM;
221 237
@@ -229,11 +245,11 @@ static int __meram_alloc(struct sh_mobile_meram_priv *priv,
229} 245}
230 246
231/* Free ICBs and MERAM for a plane. */ 247/* Free ICBs and MERAM for a plane. */
232static void __meram_free(struct sh_mobile_meram_priv *priv, 248static void meram_plane_free(struct sh_mobile_meram_priv *priv,
233 struct sh_mobile_meram_fb_plane *plane) 249 struct sh_mobile_meram_fb_plane *plane)
234{ 250{
235 gen_pool_free(priv->pool, priv->meram + plane->marker->offset, 251 meram_free(priv, priv->meram + plane->marker->offset,
236 plane->marker->size * 1024); 252 plane->marker->size * 1024);
237 253
238 __clear_bit(plane->marker->index, &priv->used_icb); 254 __clear_bit(plane->marker->index, &priv->used_icb);
239 __clear_bit(plane->cache->index, &priv->used_icb); 255 __clear_bit(plane->cache->index, &priv->used_icb);
@@ -248,62 +264,6 @@ static int is_nvcolor(int cspace)
248 return 0; 264 return 0;
249} 265}
250 266
251/* Allocate memory for the ICBs and mark them as used. */
252static struct sh_mobile_meram_fb_cache *
253meram_alloc(struct sh_mobile_meram_priv *priv,
254 const struct sh_mobile_meram_cfg *cfg,
255 int pixelformat)
256{
257 struct sh_mobile_meram_fb_cache *cache;
258 unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
259 int ret;
260
261 if (cfg->icb[0].meram_size == 0)
262 return ERR_PTR(-EINVAL);
263
264 if (nplanes == 2 && cfg->icb[1].meram_size == 0)
265 return ERR_PTR(-EINVAL);
266
267 cache = kzalloc(sizeof(*cache), GFP_KERNEL);
268 if (cache == NULL)
269 return ERR_PTR(-ENOMEM);
270
271 cache->nplanes = nplanes;
272
273 ret = __meram_alloc(priv, &cache->planes[0], cfg->icb[0].meram_size);
274 if (ret < 0)
275 goto error;
276
277 cache->planes[0].marker->current_reg = 1;
278 cache->planes[0].marker->pixelformat = pixelformat;
279
280 if (cache->nplanes == 1)
281 return cache;
282
283 ret = __meram_alloc(priv, &cache->planes[1], cfg->icb[1].meram_size);
284 if (ret < 0) {
285 __meram_free(priv, &cache->planes[0]);
286 goto error;
287 }
288
289 return cache;
290
291error:
292 kfree(cache);
293 return ERR_PTR(-ENOMEM);
294}
295
296/* Unmark the specified ICB as used. */
297static void meram_free(struct sh_mobile_meram_priv *priv,
298 struct sh_mobile_meram_fb_cache *cache)
299{
300 __meram_free(priv, &cache->planes[0]);
301 if (cache->nplanes == 2)
302 __meram_free(priv, &cache->planes[1]);
303
304 kfree(cache);
305}
306
307/* Set the next address to fetch. */ 267/* Set the next address to fetch. */
308static void meram_set_next_addr(struct sh_mobile_meram_priv *priv, 268static void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
309 struct sh_mobile_meram_fb_cache *cache, 269 struct sh_mobile_meram_fb_cache *cache,
@@ -355,10 +315,10 @@ meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
355 (((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1)) 315 (((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1))
356 316
357/* Initialize MERAM. */ 317/* Initialize MERAM. */
358static int meram_init(struct sh_mobile_meram_priv *priv, 318static int meram_plane_init(struct sh_mobile_meram_priv *priv,
359 struct sh_mobile_meram_fb_plane *plane, 319 struct sh_mobile_meram_fb_plane *plane,
360 unsigned int xres, unsigned int yres, 320 unsigned int xres, unsigned int yres,
361 unsigned int *out_pitch) 321 unsigned int *out_pitch)
362{ 322{
363 struct sh_mobile_meram_icb *marker = plane->marker; 323 struct sh_mobile_meram_icb *marker = plane->marker;
364 unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres); 324 unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres);
@@ -427,8 +387,8 @@ static int meram_init(struct sh_mobile_meram_priv *priv,
427 return 0; 387 return 0;
428} 388}
429 389
430static void meram_deinit(struct sh_mobile_meram_priv *priv, 390static void meram_plane_cleanup(struct sh_mobile_meram_priv *priv,
431 struct sh_mobile_meram_fb_plane *plane) 391 struct sh_mobile_meram_fb_plane *plane)
432{ 392{
433 /* disable ICB */ 393 /* disable ICB */
434 meram_write_icb(priv->base, plane->cache->index, MExxCTL, 394 meram_write_icb(priv->base, plane->cache->index, MExxCTL,
@@ -441,20 +401,82 @@ static void meram_deinit(struct sh_mobile_meram_priv *priv,
441} 401}
442 402
443/* ----------------------------------------------------------------------------- 403/* -----------------------------------------------------------------------------
444 * Registration/unregistration 404 * MERAM operations
445 */ 405 */
446 406
447static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, 407unsigned long sh_mobile_meram_alloc(struct sh_mobile_meram_info *pdata,
448 const struct sh_mobile_meram_cfg *cfg, 408 size_t size)
449 unsigned int xres, unsigned int yres, 409{
450 unsigned int pixelformat, 410 struct sh_mobile_meram_priv *priv = pdata->priv;
451 unsigned int *pitch) 411
412 return meram_alloc(priv, size);
413}
414EXPORT_SYMBOL_GPL(sh_mobile_meram_alloc);
415
416void sh_mobile_meram_free(struct sh_mobile_meram_info *pdata, unsigned long mem,
417 size_t size)
418{
419 struct sh_mobile_meram_priv *priv = pdata->priv;
420
421 meram_free(priv, mem, size);
422}
423EXPORT_SYMBOL_GPL(sh_mobile_meram_free);
424
425/* Allocate memory for the ICBs and mark them as used. */
426static struct sh_mobile_meram_fb_cache *
427meram_cache_alloc(struct sh_mobile_meram_priv *priv,
428 const struct sh_mobile_meram_cfg *cfg,
429 int pixelformat)
430{
431 unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
432 struct sh_mobile_meram_fb_cache *cache;
433 int ret;
434
435 cache = kzalloc(sizeof(*cache), GFP_KERNEL);
436 if (cache == NULL)
437 return ERR_PTR(-ENOMEM);
438
439 cache->nplanes = nplanes;
440
441 ret = meram_plane_alloc(priv, &cache->planes[0],
442 cfg->icb[0].meram_size);
443 if (ret < 0)
444 goto error;
445
446 cache->planes[0].marker->current_reg = 1;
447 cache->planes[0].marker->pixelformat = pixelformat;
448
449 if (cache->nplanes == 1)
450 return cache;
451
452 ret = meram_plane_alloc(priv, &cache->planes[1],
453 cfg->icb[1].meram_size);
454 if (ret < 0) {
455 meram_plane_free(priv, &cache->planes[0]);
456 goto error;
457 }
458
459 return cache;
460
461error:
462 kfree(cache);
463 return ERR_PTR(-ENOMEM);
464}
465
466void *sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *pdata,
467 const struct sh_mobile_meram_cfg *cfg,
468 unsigned int xres, unsigned int yres,
469 unsigned int pixelformat, unsigned int *pitch)
452{ 470{
453 struct sh_mobile_meram_fb_cache *cache; 471 struct sh_mobile_meram_fb_cache *cache;
454 struct sh_mobile_meram_priv *priv = pdata->priv; 472 struct sh_mobile_meram_priv *priv = pdata->priv;
455 struct platform_device *pdev = pdata->pdev; 473 struct platform_device *pdev = pdata->pdev;
474 unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
456 unsigned int out_pitch; 475 unsigned int out_pitch;
457 476
477 if (priv == NULL)
478 return ERR_PTR(-ENODEV);
479
458 if (pixelformat != SH_MOBILE_MERAM_PF_NV && 480 if (pixelformat != SH_MOBILE_MERAM_PF_NV &&
459 pixelformat != SH_MOBILE_MERAM_PF_NV24 && 481 pixelformat != SH_MOBILE_MERAM_PF_NV24 &&
460 pixelformat != SH_MOBILE_MERAM_PF_RGB) 482 pixelformat != SH_MOBILE_MERAM_PF_RGB)
@@ -469,10 +491,16 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
469 return ERR_PTR(-EINVAL); 491 return ERR_PTR(-EINVAL);
470 } 492 }
471 493
494 if (cfg->icb[0].meram_size == 0)
495 return ERR_PTR(-EINVAL);
496
497 if (nplanes == 2 && cfg->icb[1].meram_size == 0)
498 return ERR_PTR(-EINVAL);
499
472 mutex_lock(&priv->lock); 500 mutex_lock(&priv->lock);
473 501
474 /* We now register the ICBs and allocate the MERAM regions. */ 502 /* We now register the ICBs and allocate the MERAM regions. */
475 cache = meram_alloc(priv, cfg, pixelformat); 503 cache = meram_cache_alloc(priv, cfg, pixelformat);
476 if (IS_ERR(cache)) { 504 if (IS_ERR(cache)) {
477 dev_err(&pdev->dev, "MERAM allocation failed (%ld).", 505 dev_err(&pdev->dev, "MERAM allocation failed (%ld).",
478 PTR_ERR(cache)); 506 PTR_ERR(cache));
@@ -480,42 +508,50 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
480 } 508 }
481 509
482 /* initialize MERAM */ 510 /* initialize MERAM */
483 meram_init(priv, &cache->planes[0], xres, yres, &out_pitch); 511 meram_plane_init(priv, &cache->planes[0], xres, yres, &out_pitch);
484 *pitch = out_pitch; 512 *pitch = out_pitch;
485 if (pixelformat == SH_MOBILE_MERAM_PF_NV) 513 if (pixelformat == SH_MOBILE_MERAM_PF_NV)
486 meram_init(priv, &cache->planes[1], xres, (yres + 1) / 2, 514 meram_plane_init(priv, &cache->planes[1],
487 &out_pitch); 515 xres, (yres + 1) / 2, &out_pitch);
488 else if (pixelformat == SH_MOBILE_MERAM_PF_NV24) 516 else if (pixelformat == SH_MOBILE_MERAM_PF_NV24)
489 meram_init(priv, &cache->planes[1], 2 * xres, (yres + 1) / 2, 517 meram_plane_init(priv, &cache->planes[1],
490 &out_pitch); 518 2 * xres, (yres + 1) / 2, &out_pitch);
491 519
492err: 520err:
493 mutex_unlock(&priv->lock); 521 mutex_unlock(&priv->lock);
494 return cache; 522 return cache;
495} 523}
524EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_alloc);
496 525
497static void 526void
498sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata, void *data) 527sh_mobile_meram_cache_free(struct sh_mobile_meram_info *pdata, void *data)
499{ 528{
500 struct sh_mobile_meram_fb_cache *cache = data; 529 struct sh_mobile_meram_fb_cache *cache = data;
501 struct sh_mobile_meram_priv *priv = pdata->priv; 530 struct sh_mobile_meram_priv *priv = pdata->priv;
502 531
503 mutex_lock(&priv->lock); 532 mutex_lock(&priv->lock);
504 533
505 /* deinit & free */ 534 /* Cleanup and free. */
506 meram_deinit(priv, &cache->planes[0]); 535 meram_plane_cleanup(priv, &cache->planes[0]);
507 if (cache->nplanes == 2) 536 meram_plane_free(priv, &cache->planes[0]);
508 meram_deinit(priv, &cache->planes[1]); 537
538 if (cache->nplanes == 2) {
539 meram_plane_cleanup(priv, &cache->planes[1]);
540 meram_plane_free(priv, &cache->planes[1]);
541 }
509 542
510 meram_free(priv, cache); 543 kfree(cache);
511 544
512 mutex_unlock(&priv->lock); 545 mutex_unlock(&priv->lock);
513} 546}
514 547EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_free);
515static void 548
516sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, void *data, 549void
517 unsigned long base_addr_y, unsigned long base_addr_c, 550sh_mobile_meram_cache_update(struct sh_mobile_meram_info *pdata, void *data,
518 unsigned long *icb_addr_y, unsigned long *icb_addr_c) 551 unsigned long base_addr_y,
552 unsigned long base_addr_c,
553 unsigned long *icb_addr_y,
554 unsigned long *icb_addr_c)
519{ 555{
520 struct sh_mobile_meram_fb_cache *cache = data; 556 struct sh_mobile_meram_fb_cache *cache = data;
521 struct sh_mobile_meram_priv *priv = pdata->priv; 557 struct sh_mobile_meram_priv *priv = pdata->priv;
@@ -527,13 +563,7 @@ sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, void *data,
527 563
528 mutex_unlock(&priv->lock); 564 mutex_unlock(&priv->lock);
529} 565}
530 566EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_update);
531static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
532 .module = THIS_MODULE,
533 .meram_register = sh_mobile_meram_register,
534 .meram_unregister = sh_mobile_meram_unregister,
535 .meram_update = sh_mobile_meram_update,
536};
537 567
538/* ----------------------------------------------------------------------------- 568/* -----------------------------------------------------------------------------
539 * Power management 569 * Power management
@@ -624,7 +654,6 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
624 for (i = 0; i < MERAM_ICB_NUM; ++i) 654 for (i = 0; i < MERAM_ICB_NUM; ++i)
625 priv->icbs[i].index = i; 655 priv->icbs[i].index = i;
626 656
627 pdata->ops = &sh_mobile_meram_ops;
628 pdata->priv = priv; 657 pdata->priv = priv;
629 pdata->pdev = pdev; 658 pdata->pdev = pdev;
630 659
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index 26f864289498..5533a32c6ca1 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -904,7 +904,7 @@ static ssize_t ufx_ops_write(struct fb_info *info, const char __user *buf,
904 result = fb_sys_write(info, buf, count, ppos); 904 result = fb_sys_write(info, buf, count, ppos);
905 905
906 if (result > 0) { 906 if (result > 0) {
907 int start = max((int)(offset / info->fix.line_length) - 1, 0); 907 int start = max((int)(offset / info->fix.line_length), 0);
908 int lines = min((u32)((result / info->fix.line_length) + 1), 908 int lines = min((u32)((result / info->fix.line_length) + 1),
909 (u32)info->var.yres); 909 (u32)info->var.yres);
910 910
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 90a2e30272ad..2f6b2b835f88 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -1567,6 +1567,18 @@ static void w100_suspend(u32 mode)
1567 val = readl(remapped_regs + mmPLL_CNTL); 1567 val = readl(remapped_regs + mmPLL_CNTL);
1568 val |= 0x00000004; /* bit2=1 */ 1568 val |= 0x00000004; /* bit2=1 */
1569 writel(val, remapped_regs + mmPLL_CNTL); 1569 writel(val, remapped_regs + mmPLL_CNTL);
1570
1571 writel(0x00000000, remapped_regs + mmLCDD_CNTL1);
1572 writel(0x00000000, remapped_regs + mmLCDD_CNTL2);
1573 writel(0x00000000, remapped_regs + mmGENLCD_CNTL1);
1574 writel(0x00000000, remapped_regs + mmGENLCD_CNTL2);
1575 writel(0x00000000, remapped_regs + mmGENLCD_CNTL3);
1576
1577 val = readl(remapped_regs + mmMEM_EXT_CNTL);
1578 val |= 0xF0000000;
1579 val &= ~(0x00000001);
1580 writel(val, remapped_regs + mmMEM_EXT_CNTL);
1581
1570 writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL); 1582 writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL);
1571 } 1583 }
1572} 1584}