diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-03 02:26:33 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-03 02:26:33 -0400 |
commit | c50e86ce7c2961a41f2f7aa6e4fd6c99229ba205 (patch) | |
tree | 4ea36009719bd8fc523239fe1bdccb90f0dce3ae /drivers/video | |
parent | 14d33d384693eb6083396199de516fdef320f7af (diff) | |
parent | 4cbe5a555fa58a79b6ecbb6c531b8bab0650778d (diff) |
Merge tag 'v3.6-rc4'
Merge 3.6-rc4 to get latest OMAP and device tree fixes.
Diffstat (limited to 'drivers/video')
50 files changed, 1721 insertions, 633 deletions
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index c22e8d39a2cb..a1d58e9d3073 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c | |||
@@ -336,8 +336,8 @@ static void arcfb_lcd_update_horiz(struct arcfb_par *par, unsigned int left, | |||
336 | } | 336 | } |
337 | 337 | ||
338 | /* | 338 | /* |
339 | * here we start the process of spliting out the fb update into | 339 | * here we start the process of splitting out the fb update into |
340 | * individual blocks of pixels. we end up spliting into 64x64 blocks | 340 | * individual blocks of pixels. we end up splitting into 64x64 blocks |
341 | * and finally down to 64x8 pages. | 341 | * and finally down to 64x8 pages. |
342 | */ | 342 | */ |
343 | static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx, | 343 | static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx, |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index d99505b16374..15055395cd95 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -939,7 +939,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) | |||
939 | * up a splash image. | 939 | * up a splash image. |
940 | */ | 940 | */ |
941 | } else { | 941 | } else { |
942 | /* alocate memory buffer */ | 942 | /* allocate memory buffer */ |
943 | ret = atmel_lcdfb_alloc_video_memory(sinfo); | 943 | ret = atmel_lcdfb_alloc_video_memory(sinfo); |
944 | if (ret < 0) { | 944 | if (ret < 0) { |
945 | dev_err(dev, "cannot allocate framebuffer: %d\n", ret); | 945 | dev_err(dev, "cannot allocate framebuffer: %d\n", ret); |
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 |
451 | static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, | 452 | static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, |
452 | void __iomem *bios); | 453 | void __iomem *bios); |
453 | static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); | 454 | static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev, |
455 | const struct aty128fb_par *par); | ||
454 | #endif | 456 | #endif |
455 | static void aty128_timings(struct aty128fb_par *par); | 457 | static void aty128_timings(struct aty128fb_par *par); |
456 | static void aty128_init_engine(struct aty128fb_par *par); | 458 | static 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__ |
782 | static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) | 784 | static 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 | ||
866 | static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) | 871 | static 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, | |||
1247 | static void aty128_set_crt_enable(struct aty128fb_par *par, int on) | 1253 | static 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 | ||
1256 | static void aty128_set_lcd_enable(struct aty128fb_par *par, int on) | 1265 | static 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 | ||
1284 | static void aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par) | 1293 | static 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 | ||
1369 | static int aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var) | 1379 | static 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 | ||
1515 | static int aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par) | 1526 | static 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 | ||
1562 | static int aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 1574 | static 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 | */ |
1578 | static int aty128fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb) | 1591 | static 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 | ||
1872 | static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) | 1891 | static 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 */ |
2021 | static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 2042 | static 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 | ||
2361 | static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx, | 2383 | static 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/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 622f12b62a47..3f2e8c13f1ca 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -863,7 +863,7 @@ static int aty_var_to_crtc(const struct fb_info *info, | |||
863 | 863 | ||
864 | if ((xres > 1600) || (yres > 1200)) { | 864 | if ((xres > 1600) || (yres > 1200)) { |
865 | FAIL("MACH64 chips are designed for max 1600x1200\n" | 865 | FAIL("MACH64 chips are designed for max 1600x1200\n" |
866 | "select anoter resolution."); | 866 | "select another resolution."); |
867 | } | 867 | } |
868 | h_sync_strt = h_disp + var->right_margin; | 868 | h_sync_strt = h_disp + var->right_margin; |
869 | h_sync_end = h_sync_strt + var->hsync_len; | 869 | h_sync_end = h_sync_strt + var->hsync_len; |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index ce1506b75adf..9e279ee38da8 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -2018,7 +2018,7 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) | |||
2018 | if ((rinfo->family == CHIP_FAMILY_RS100) || | 2018 | if ((rinfo->family == CHIP_FAMILY_RS100) || |
2019 | (rinfo->family == CHIP_FAMILY_RS200)) { | 2019 | (rinfo->family == CHIP_FAMILY_RS200)) { |
2020 | /* This is to workaround the asic bug for RMX, some versions | 2020 | /* This is to workaround the asic bug for RMX, some versions |
2021 | of BIOS dosen't have this register initialized correctly. | 2021 | of BIOS doesn't have this register initialized correctly. |
2022 | */ | 2022 | */ |
2023 | OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN, | 2023 | OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN, |
2024 | ~CRTC_H_CUTOFF_ACTIVE_EN); | 2024 | ~CRTC_H_CUTOFF_ACTIVE_EN); |
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c index 9261c918fde8..5c23eac0eb9a 100644 --- a/drivers/video/aty/radeon_monitor.c +++ b/drivers/video/aty/radeon_monitor.c | |||
@@ -730,6 +730,25 @@ static void radeon_videomode_to_var(struct fb_var_screeninfo *var, | |||
730 | var->vmode = mode->vmode; | 730 | var->vmode = mode->vmode; |
731 | } | 731 | } |
732 | 732 | ||
733 | #ifdef CONFIG_PPC_PSERIES | ||
734 | static int is_powerblade(const char *model) | ||
735 | { | ||
736 | struct device_node *root; | ||
737 | const char* cp; | ||
738 | int len, l, rc = 0; | ||
739 | |||
740 | root = of_find_node_by_path("/"); | ||
741 | if (root && model) { | ||
742 | l = strlen(model); | ||
743 | cp = of_get_property(root, "model", &len); | ||
744 | if (cp) | ||
745 | rc = memcmp(model, cp, min(len, l)) == 0; | ||
746 | of_node_put(root); | ||
747 | } | ||
748 | return rc; | ||
749 | } | ||
750 | #endif | ||
751 | |||
733 | /* | 752 | /* |
734 | * Build the modedb for head 1 (head 2 will come later), check panel infos | 753 | * Build the modedb for head 1 (head 2 will come later), check panel infos |
735 | * from either BIOS or EDID, and pick up the default mode | 754 | * from either BIOS or EDID, and pick up the default mode |
@@ -865,6 +884,22 @@ void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_ | |||
865 | has_default_mode = 1; | 884 | has_default_mode = 1; |
866 | } | 885 | } |
867 | 886 | ||
887 | #ifdef CONFIG_PPC_PSERIES | ||
888 | if (!has_default_mode && ( | ||
889 | is_powerblade("IBM,8842") || /* JS20 */ | ||
890 | is_powerblade("IBM,8844") || /* JS21 */ | ||
891 | is_powerblade("IBM,7998") || /* JS12/JS21/JS22 */ | ||
892 | is_powerblade("IBM,0792") || /* QS21 */ | ||
893 | is_powerblade("IBM,0793") /* QS22 */ | ||
894 | )) { | ||
895 | printk("Falling back to 800x600 on JSxx hardware\n"); | ||
896 | if (fb_find_mode(&info->var, info, "800x600@60", | ||
897 | info->monspecs.modedb, | ||
898 | info->monspecs.modedb_len, NULL, 8) != 0) | ||
899 | has_default_mode = 1; | ||
900 | } | ||
901 | #endif | ||
902 | |||
868 | /* | 903 | /* |
869 | * Still no mode, let's pick up a default from the db | 904 | * Still no mode, let's pick up a default from the db |
870 | */ | 905 | */ |
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index f49181c73113..f75da8758adc 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c | |||
@@ -228,6 +228,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev) | |||
228 | data->port = pdata->flags; | 228 | data->port = pdata->flags; |
229 | if (data->port < 0) { | 229 | if (data->port < 0) { |
230 | dev_err(&pdev->dev, "wrong platform data is assigned"); | 230 | dev_err(&pdev->dev, "wrong platform data is assigned"); |
231 | kfree(data); | ||
231 | return -EINVAL; | 232 | return -EINVAL; |
232 | } | 233 | } |
233 | 234 | ||
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index fa2b03750316..cf282763a8dc 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -88,7 +88,7 @@ config LCD_PLATFORM | |||
88 | 88 | ||
89 | config LCD_TOSA | 89 | config LCD_TOSA |
90 | tristate "Sharp SL-6000 LCD Driver" | 90 | tristate "Sharp SL-6000 LCD Driver" |
91 | depends on SPI && MACH_TOSA | 91 | depends on I2C && SPI && MACH_TOSA |
92 | help | 92 | help |
93 | If you have an Sharp SL-6000 Zaurus say Y to enable a driver | 93 | If you have an Sharp SL-6000 Zaurus say Y to enable a driver |
94 | for its LCD. | 94 | for its LCD. |
@@ -245,7 +245,7 @@ config BACKLIGHT_CARILLO_RANCH | |||
245 | 245 | ||
246 | config BACKLIGHT_PWM | 246 | config BACKLIGHT_PWM |
247 | tristate "Generic PWM based Backlight Driver" | 247 | tristate "Generic PWM based Backlight Driver" |
248 | depends on HAVE_PWM | 248 | depends on PWM |
249 | help | 249 | help |
250 | If you have a LCD backlight adjustable by PWM, say Y to enable | 250 | If you have a LCD backlight adjustable by PWM, say Y to enable |
251 | this driver. | 251 | this driver. |
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c index 0443a4f71858..df1cbb7ef6ca 100644 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ b/drivers/video/backlight/atmel-pwm-bl.c | |||
@@ -127,7 +127,8 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) | |||
127 | struct atmel_pwm_bl *pwmbl; | 127 | struct atmel_pwm_bl *pwmbl; |
128 | int retval; | 128 | int retval; |
129 | 129 | ||
130 | pwmbl = kzalloc(sizeof(struct atmel_pwm_bl), GFP_KERNEL); | 130 | pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl), |
131 | GFP_KERNEL); | ||
131 | if (!pwmbl) | 132 | if (!pwmbl) |
132 | return -ENOMEM; | 133 | return -ENOMEM; |
133 | 134 | ||
@@ -154,7 +155,8 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) | |||
154 | goto err_free_mem; | 155 | goto err_free_mem; |
155 | 156 | ||
156 | if (pwmbl->gpio_on != -1) { | 157 | if (pwmbl->gpio_on != -1) { |
157 | retval = gpio_request(pwmbl->gpio_on, "gpio_atmel_pwm_bl"); | 158 | retval = devm_gpio_request(&pdev->dev, pwmbl->gpio_on, |
159 | "gpio_atmel_pwm_bl"); | ||
158 | if (retval) { | 160 | if (retval) { |
159 | pwmbl->gpio_on = -1; | 161 | pwmbl->gpio_on = -1; |
160 | goto err_free_pwm; | 162 | goto err_free_pwm; |
@@ -164,7 +166,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) | |||
164 | retval = gpio_direction_output(pwmbl->gpio_on, | 166 | retval = gpio_direction_output(pwmbl->gpio_on, |
165 | 0 ^ pdata->on_active_low); | 167 | 0 ^ pdata->on_active_low); |
166 | if (retval) | 168 | if (retval) |
167 | goto err_free_gpio; | 169 | goto err_free_pwm; |
168 | } | 170 | } |
169 | 171 | ||
170 | memset(&props, 0, sizeof(struct backlight_properties)); | 172 | memset(&props, 0, sizeof(struct backlight_properties)); |
@@ -174,7 +176,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) | |||
174 | &atmel_pwm_bl_ops, &props); | 176 | &atmel_pwm_bl_ops, &props); |
175 | if (IS_ERR(bldev)) { | 177 | if (IS_ERR(bldev)) { |
176 | retval = PTR_ERR(bldev); | 178 | retval = PTR_ERR(bldev); |
177 | goto err_free_gpio; | 179 | goto err_free_pwm; |
178 | } | 180 | } |
179 | 181 | ||
180 | pwmbl->bldev = bldev; | 182 | pwmbl->bldev = bldev; |
@@ -196,13 +198,9 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) | |||
196 | err_free_bl_dev: | 198 | err_free_bl_dev: |
197 | platform_set_drvdata(pdev, NULL); | 199 | platform_set_drvdata(pdev, NULL); |
198 | backlight_device_unregister(bldev); | 200 | backlight_device_unregister(bldev); |
199 | err_free_gpio: | ||
200 | if (pwmbl->gpio_on != -1) | ||
201 | gpio_free(pwmbl->gpio_on); | ||
202 | err_free_pwm: | 201 | err_free_pwm: |
203 | pwm_channel_free(&pwmbl->pwmc); | 202 | pwm_channel_free(&pwmbl->pwmc); |
204 | err_free_mem: | 203 | err_free_mem: |
205 | kfree(pwmbl); | ||
206 | return retval; | 204 | return retval; |
207 | } | 205 | } |
208 | 206 | ||
@@ -210,15 +208,12 @@ static int __exit atmel_pwm_bl_remove(struct platform_device *pdev) | |||
210 | { | 208 | { |
211 | struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev); | 209 | struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev); |
212 | 210 | ||
213 | if (pwmbl->gpio_on != -1) { | 211 | if (pwmbl->gpio_on != -1) |
214 | gpio_set_value(pwmbl->gpio_on, 0); | 212 | gpio_set_value(pwmbl->gpio_on, 0); |
215 | gpio_free(pwmbl->gpio_on); | ||
216 | } | ||
217 | pwm_channel_disable(&pwmbl->pwmc); | 213 | pwm_channel_disable(&pwmbl->pwmc); |
218 | pwm_channel_free(&pwmbl->pwmc); | 214 | pwm_channel_free(&pwmbl->pwmc); |
219 | backlight_device_unregister(pwmbl->bldev); | 215 | backlight_device_unregister(pwmbl->bldev); |
220 | platform_set_drvdata(pdev, NULL); | 216 | platform_set_drvdata(pdev, NULL); |
221 | kfree(pwmbl); | ||
222 | 217 | ||
223 | return 0; | 218 | return 0; |
224 | } | 219 | } |
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index 23d732677ba1..c781768ba892 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c | |||
@@ -492,7 +492,8 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd, | |||
492 | lcd->gpio_backlight_cont = -1; | 492 | lcd->gpio_backlight_cont = -1; |
493 | 493 | ||
494 | if (gpio_is_valid(pdata->gpio_backlight_on)) { | 494 | if (gpio_is_valid(pdata->gpio_backlight_on)) { |
495 | err = gpio_request(pdata->gpio_backlight_on, "BL_ON"); | 495 | err = devm_gpio_request(&spi->dev, pdata->gpio_backlight_on, |
496 | "BL_ON"); | ||
496 | if (err) { | 497 | if (err) { |
497 | dev_err(&spi->dev, "failed to request GPIO%d for " | 498 | dev_err(&spi->dev, "failed to request GPIO%d for " |
498 | "backlight_on\n", pdata->gpio_backlight_on); | 499 | "backlight_on\n", pdata->gpio_backlight_on); |
@@ -504,11 +505,12 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd, | |||
504 | } | 505 | } |
505 | 506 | ||
506 | if (gpio_is_valid(pdata->gpio_backlight_cont)) { | 507 | if (gpio_is_valid(pdata->gpio_backlight_cont)) { |
507 | err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT"); | 508 | err = devm_gpio_request(&spi->dev, pdata->gpio_backlight_cont, |
509 | "BL_CONT"); | ||
508 | if (err) { | 510 | if (err) { |
509 | dev_err(&spi->dev, "failed to request GPIO%d for " | 511 | dev_err(&spi->dev, "failed to request GPIO%d for " |
510 | "backlight_cont\n", pdata->gpio_backlight_cont); | 512 | "backlight_cont\n", pdata->gpio_backlight_cont); |
511 | goto err_free_backlight_on; | 513 | return err; |
512 | } | 514 | } |
513 | 515 | ||
514 | lcd->gpio_backlight_cont = pdata->gpio_backlight_cont; | 516 | lcd->gpio_backlight_cont = pdata->gpio_backlight_cont; |
@@ -525,11 +527,6 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd, | |||
525 | } | 527 | } |
526 | } | 528 | } |
527 | return 0; | 529 | return 0; |
528 | |||
529 | err_free_backlight_on: | ||
530 | if (gpio_is_valid(lcd->gpio_backlight_on)) | ||
531 | gpio_free(lcd->gpio_backlight_on); | ||
532 | return err; | ||
533 | } | 530 | } |
534 | 531 | ||
535 | static int __devinit corgi_lcd_probe(struct spi_device *spi) | 532 | static int __devinit corgi_lcd_probe(struct spi_device *spi) |
@@ -602,12 +599,6 @@ static int __devexit corgi_lcd_remove(struct spi_device *spi) | |||
602 | backlight_update_status(lcd->bl_dev); | 599 | backlight_update_status(lcd->bl_dev); |
603 | backlight_device_unregister(lcd->bl_dev); | 600 | backlight_device_unregister(lcd->bl_dev); |
604 | 601 | ||
605 | if (gpio_is_valid(lcd->gpio_backlight_on)) | ||
606 | gpio_free(lcd->gpio_backlight_on); | ||
607 | |||
608 | if (gpio_is_valid(lcd->gpio_backlight_cont)) | ||
609 | gpio_free(lcd->gpio_backlight_cont); | ||
610 | |||
611 | corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); | 602 | corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); |
612 | lcd_device_unregister(lcd->lcd_dev); | 603 | lcd_device_unregister(lcd->lcd_dev); |
613 | 604 | ||
diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c index 6c9399341bcf..9327cd1b3143 100644 --- a/drivers/video/backlight/ili9320.c +++ b/drivers/video/backlight/ili9320.c | |||
@@ -263,7 +263,7 @@ int __devinit ili9320_probe_spi(struct spi_device *spi, | |||
263 | 263 | ||
264 | EXPORT_SYMBOL_GPL(ili9320_probe_spi); | 264 | EXPORT_SYMBOL_GPL(ili9320_probe_spi); |
265 | 265 | ||
266 | int __devexit ili9320_remove(struct ili9320 *ili) | 266 | int ili9320_remove(struct ili9320 *ili) |
267 | { | 267 | { |
268 | ili9320_power(ili, FB_BLANK_POWERDOWN); | 268 | ili9320_power(ili, FB_BLANK_POWERDOWN); |
269 | 269 | ||
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 40f606a86093..2d90c0648aa0 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c | |||
@@ -175,28 +175,27 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) | |||
175 | 175 | ||
176 | priv->spi = spi; | 176 | priv->spi = spi; |
177 | 177 | ||
178 | ret = gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, | 178 | ret = devm_gpio_request_one(&spi->dev, pdata->reset_gpio, |
179 | "lcd l4f00242t03 reset"); | 179 | GPIOF_OUT_INIT_HIGH, "lcd l4f00242t03 reset"); |
180 | if (ret) { | 180 | if (ret) { |
181 | dev_err(&spi->dev, | 181 | dev_err(&spi->dev, |
182 | "Unable to get the lcd l4f00242t03 reset gpio.\n"); | 182 | "Unable to get the lcd l4f00242t03 reset gpio.\n"); |
183 | return ret; | 183 | return ret; |
184 | } | 184 | } |
185 | 185 | ||
186 | ret = gpio_request_one(pdata->data_enable_gpio, GPIOF_OUT_INIT_LOW, | 186 | ret = devm_gpio_request_one(&spi->dev, pdata->data_enable_gpio, |
187 | "lcd l4f00242t03 data enable"); | 187 | GPIOF_OUT_INIT_LOW, "lcd l4f00242t03 data enable"); |
188 | if (ret) { | 188 | if (ret) { |
189 | dev_err(&spi->dev, | 189 | dev_err(&spi->dev, |
190 | "Unable to get the lcd l4f00242t03 data en gpio.\n"); | 190 | "Unable to get the lcd l4f00242t03 data en gpio.\n"); |
191 | goto err; | 191 | return ret; |
192 | } | 192 | } |
193 | 193 | ||
194 | priv->io_reg = regulator_get(&spi->dev, "vdd"); | 194 | priv->io_reg = regulator_get(&spi->dev, "vdd"); |
195 | if (IS_ERR(priv->io_reg)) { | 195 | if (IS_ERR(priv->io_reg)) { |
196 | ret = PTR_ERR(priv->io_reg); | ||
197 | dev_err(&spi->dev, "%s: Unable to get the IO regulator\n", | 196 | dev_err(&spi->dev, "%s: Unable to get the IO regulator\n", |
198 | __func__); | 197 | __func__); |
199 | goto err2; | 198 | return PTR_ERR(priv->io_reg); |
200 | } | 199 | } |
201 | 200 | ||
202 | priv->core_reg = regulator_get(&spi->dev, "vcore"); | 201 | priv->core_reg = regulator_get(&spi->dev, "vcore"); |
@@ -204,14 +203,14 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) | |||
204 | ret = PTR_ERR(priv->core_reg); | 203 | ret = PTR_ERR(priv->core_reg); |
205 | dev_err(&spi->dev, "%s: Unable to get the core regulator\n", | 204 | dev_err(&spi->dev, "%s: Unable to get the core regulator\n", |
206 | __func__); | 205 | __func__); |
207 | goto err3; | 206 | goto err1; |
208 | } | 207 | } |
209 | 208 | ||
210 | priv->ld = lcd_device_register("l4f00242t03", | 209 | priv->ld = lcd_device_register("l4f00242t03", |
211 | &spi->dev, priv, &l4f_ops); | 210 | &spi->dev, priv, &l4f_ops); |
212 | if (IS_ERR(priv->ld)) { | 211 | if (IS_ERR(priv->ld)) { |
213 | ret = PTR_ERR(priv->ld); | 212 | ret = PTR_ERR(priv->ld); |
214 | goto err4; | 213 | goto err2; |
215 | } | 214 | } |
216 | 215 | ||
217 | /* Init the LCD */ | 216 | /* Init the LCD */ |
@@ -223,14 +222,10 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) | |||
223 | 222 | ||
224 | return 0; | 223 | return 0; |
225 | 224 | ||
226 | err4: | 225 | err2: |
227 | regulator_put(priv->core_reg); | 226 | regulator_put(priv->core_reg); |
228 | err3: | 227 | err1: |
229 | regulator_put(priv->io_reg); | 228 | regulator_put(priv->io_reg); |
230 | err2: | ||
231 | gpio_free(pdata->data_enable_gpio); | ||
232 | err: | ||
233 | gpio_free(pdata->reset_gpio); | ||
234 | 229 | ||
235 | return ret; | 230 | return ret; |
236 | } | 231 | } |
@@ -238,16 +233,12 @@ err: | |||
238 | static int __devexit l4f00242t03_remove(struct spi_device *spi) | 233 | static int __devexit l4f00242t03_remove(struct spi_device *spi) |
239 | { | 234 | { |
240 | struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); | 235 | struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); |
241 | struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data; | ||
242 | 236 | ||
243 | l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); | 237 | l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); |
244 | lcd_device_unregister(priv->ld); | 238 | lcd_device_unregister(priv->ld); |
245 | 239 | ||
246 | dev_set_drvdata(&spi->dev, NULL); | 240 | dev_set_drvdata(&spi->dev, NULL); |
247 | 241 | ||
248 | gpio_free(pdata->data_enable_gpio); | ||
249 | gpio_free(pdata->reset_gpio); | ||
250 | |||
251 | regulator_put(priv->io_reg); | 242 | regulator_put(priv->io_reg); |
252 | regulator_put(priv->core_reg); | 243 | regulator_put(priv->core_reg); |
253 | 244 | ||
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c index bebeb63607db..18dca0c29c68 100644 --- a/drivers/video/backlight/lm3533_bl.c +++ b/drivers/video/backlight/lm3533_bl.c | |||
@@ -295,7 +295,7 @@ static int __devinit lm3533_bl_probe(struct platform_device *pdev) | |||
295 | return -EINVAL; | 295 | return -EINVAL; |
296 | } | 296 | } |
297 | 297 | ||
298 | bl = kzalloc(sizeof(*bl), GFP_KERNEL); | 298 | bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL); |
299 | if (!bl) { | 299 | if (!bl) { |
300 | dev_err(&pdev->dev, | 300 | dev_err(&pdev->dev, |
301 | "failed to allocate memory for backlight\n"); | 301 | "failed to allocate memory for backlight\n"); |
@@ -317,8 +317,7 @@ static int __devinit lm3533_bl_probe(struct platform_device *pdev) | |||
317 | &lm3533_bl_ops, &props); | 317 | &lm3533_bl_ops, &props); |
318 | if (IS_ERR(bd)) { | 318 | if (IS_ERR(bd)) { |
319 | dev_err(&pdev->dev, "failed to register backlight device\n"); | 319 | dev_err(&pdev->dev, "failed to register backlight device\n"); |
320 | ret = PTR_ERR(bd); | 320 | return PTR_ERR(bd); |
321 | goto err_free; | ||
322 | } | 321 | } |
323 | 322 | ||
324 | bl->bd = bd; | 323 | bl->bd = bd; |
@@ -348,8 +347,6 @@ err_sysfs_remove: | |||
348 | sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); | 347 | sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); |
349 | err_unregister: | 348 | err_unregister: |
350 | backlight_device_unregister(bd); | 349 | backlight_device_unregister(bd); |
351 | err_free: | ||
352 | kfree(bl); | ||
353 | 350 | ||
354 | return ret; | 351 | return ret; |
355 | } | 352 | } |
@@ -367,7 +364,6 @@ static int __devexit lm3533_bl_remove(struct platform_device *pdev) | |||
367 | lm3533_ctrlbank_disable(&bl->cb); | 364 | lm3533_ctrlbank_disable(&bl->cb); |
368 | sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); | 365 | sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); |
369 | backlight_device_unregister(bd); | 366 | backlight_device_unregister(bd); |
370 | kfree(bl); | ||
371 | 367 | ||
372 | return 0; | 368 | return 0; |
373 | } | 369 | } |
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c index a9f2c36966f1..ea43f2254196 100644 --- a/drivers/video/backlight/lms283gf05.c +++ b/drivers/video/backlight/lms283gf05.c | |||
@@ -158,29 +158,27 @@ static int __devinit lms283gf05_probe(struct spi_device *spi) | |||
158 | int ret = 0; | 158 | int ret = 0; |
159 | 159 | ||
160 | if (pdata != NULL) { | 160 | if (pdata != NULL) { |
161 | ret = gpio_request(pdata->reset_gpio, "LMS285GF05 RESET"); | 161 | ret = devm_gpio_request(&spi->dev, pdata->reset_gpio, |
162 | "LMS285GF05 RESET"); | ||
162 | if (ret) | 163 | if (ret) |
163 | return ret; | 164 | return ret; |
164 | 165 | ||
165 | ret = gpio_direction_output(pdata->reset_gpio, | 166 | ret = gpio_direction_output(pdata->reset_gpio, |
166 | !pdata->reset_inverted); | 167 | !pdata->reset_inverted); |
167 | if (ret) | 168 | if (ret) |
168 | goto err; | 169 | return ret; |
169 | } | 170 | } |
170 | 171 | ||
171 | st = devm_kzalloc(&spi->dev, sizeof(struct lms283gf05_state), | 172 | st = devm_kzalloc(&spi->dev, sizeof(struct lms283gf05_state), |
172 | GFP_KERNEL); | 173 | GFP_KERNEL); |
173 | if (st == NULL) { | 174 | if (st == NULL) { |
174 | dev_err(&spi->dev, "No memory for device state\n"); | 175 | dev_err(&spi->dev, "No memory for device state\n"); |
175 | ret = -ENOMEM; | 176 | return -ENOMEM; |
176 | goto err; | ||
177 | } | 177 | } |
178 | 178 | ||
179 | ld = lcd_device_register("lms283gf05", &spi->dev, st, &lms_ops); | 179 | ld = lcd_device_register("lms283gf05", &spi->dev, st, &lms_ops); |
180 | if (IS_ERR(ld)) { | 180 | if (IS_ERR(ld)) |
181 | ret = PTR_ERR(ld); | 181 | return PTR_ERR(ld); |
182 | goto err; | ||
183 | } | ||
184 | 182 | ||
185 | st->spi = spi; | 183 | st->spi = spi; |
186 | st->ld = ld; | 184 | st->ld = ld; |
@@ -193,24 +191,14 @@ static int __devinit lms283gf05_probe(struct spi_device *spi) | |||
193 | lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq)); | 191 | lms283gf05_toggle(spi, disp_initseq, ARRAY_SIZE(disp_initseq)); |
194 | 192 | ||
195 | return 0; | 193 | return 0; |
196 | |||
197 | err: | ||
198 | if (pdata != NULL) | ||
199 | gpio_free(pdata->reset_gpio); | ||
200 | |||
201 | return ret; | ||
202 | } | 194 | } |
203 | 195 | ||
204 | static int __devexit lms283gf05_remove(struct spi_device *spi) | 196 | static int __devexit lms283gf05_remove(struct spi_device *spi) |
205 | { | 197 | { |
206 | struct lms283gf05_state *st = dev_get_drvdata(&spi->dev); | 198 | struct lms283gf05_state *st = dev_get_drvdata(&spi->dev); |
207 | struct lms283gf05_pdata *pdata = st->spi->dev.platform_data; | ||
208 | 199 | ||
209 | lcd_device_unregister(st->ld); | 200 | lcd_device_unregister(st->ld); |
210 | 201 | ||
211 | if (pdata != NULL) | ||
212 | gpio_free(pdata->reset_gpio); | ||
213 | |||
214 | return 0; | 202 | return 0; |
215 | } | 203 | } |
216 | 204 | ||
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index 72a0e0c917cf..aa6d4f71131f 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c | |||
@@ -14,11 +14,15 @@ | |||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/backlight.h> | 15 | #include <linux/backlight.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/lp855x.h> | 17 | #include <linux/platform_data/lp855x.h> |
18 | 18 | ||
19 | /* Registers */ | 19 | /* Registers */ |
20 | #define BRIGHTNESS_CTRL (0x00) | 20 | #define BRIGHTNESS_CTRL 0x00 |
21 | #define DEVICE_CTRL (0x01) | 21 | #define DEVICE_CTRL 0x01 |
22 | #define EEPROM_START 0xA0 | ||
23 | #define EEPROM_END 0xA7 | ||
24 | #define EPROM_START 0xA0 | ||
25 | #define EPROM_END 0xAF | ||
22 | 26 | ||
23 | #define BUF_SIZE 20 | 27 | #define BUF_SIZE 20 |
24 | #define DEFAULT_BL_NAME "lcd-backlight" | 28 | #define DEFAULT_BL_NAME "lcd-backlight" |
diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c index f519d55a294c..469cf0f109d2 100644 --- a/drivers/video/backlight/ot200_bl.c +++ b/drivers/video/backlight/ot200_bl.c | |||
@@ -84,7 +84,8 @@ static int ot200_backlight_probe(struct platform_device *pdev) | |||
84 | int retval = 0; | 84 | int retval = 0; |
85 | 85 | ||
86 | /* request gpio */ | 86 | /* request gpio */ |
87 | if (gpio_request(GPIO_DIMM, "ot200 backlight dimmer") < 0) { | 87 | if (devm_gpio_request(&pdev->dev, GPIO_DIMM, |
88 | "ot200 backlight dimmer") < 0) { | ||
88 | dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM); | 89 | dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM); |
89 | return -ENODEV; | 90 | return -ENODEV; |
90 | } | 91 | } |
@@ -93,14 +94,13 @@ static int ot200_backlight_probe(struct platform_device *pdev) | |||
93 | pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY); | 94 | pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY); |
94 | if (!pwm_timer) { | 95 | if (!pwm_timer) { |
95 | dev_err(&pdev->dev, "MFGPT 7 not available\n"); | 96 | dev_err(&pdev->dev, "MFGPT 7 not available\n"); |
96 | retval = -ENODEV; | 97 | return -ENODEV; |
97 | goto error_mfgpt_alloc; | ||
98 | } | 98 | } |
99 | 99 | ||
100 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 100 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
101 | if (!data) { | 101 | if (!data) { |
102 | retval = -ENOMEM; | 102 | retval = -ENOMEM; |
103 | goto error_kzalloc; | 103 | goto error_devm_kzalloc; |
104 | } | 104 | } |
105 | 105 | ||
106 | /* setup gpio */ | 106 | /* setup gpio */ |
@@ -122,26 +122,21 @@ static int ot200_backlight_probe(struct platform_device *pdev) | |||
122 | if (IS_ERR(bl)) { | 122 | if (IS_ERR(bl)) { |
123 | dev_err(&pdev->dev, "failed to register backlight\n"); | 123 | dev_err(&pdev->dev, "failed to register backlight\n"); |
124 | retval = PTR_ERR(bl); | 124 | retval = PTR_ERR(bl); |
125 | goto error_backlight_device_register; | 125 | goto error_devm_kzalloc; |
126 | } | 126 | } |
127 | 127 | ||
128 | platform_set_drvdata(pdev, bl); | 128 | platform_set_drvdata(pdev, bl); |
129 | 129 | ||
130 | return 0; | 130 | return 0; |
131 | 131 | ||
132 | error_backlight_device_register: | 132 | error_devm_kzalloc: |
133 | kfree(data); | ||
134 | error_kzalloc: | ||
135 | cs5535_mfgpt_free_timer(pwm_timer); | 133 | cs5535_mfgpt_free_timer(pwm_timer); |
136 | error_mfgpt_alloc: | ||
137 | gpio_free(GPIO_DIMM); | ||
138 | return retval; | 134 | return retval; |
139 | } | 135 | } |
140 | 136 | ||
141 | static int ot200_backlight_remove(struct platform_device *pdev) | 137 | static int ot200_backlight_remove(struct platform_device *pdev) |
142 | { | 138 | { |
143 | struct backlight_device *bl = platform_get_drvdata(pdev); | 139 | struct backlight_device *bl = platform_get_drvdata(pdev); |
144 | struct ot200_backlight_data *data = bl_get_data(bl); | ||
145 | 140 | ||
146 | backlight_device_unregister(bl); | 141 | backlight_device_unregister(bl); |
147 | 142 | ||
@@ -152,9 +147,7 @@ static int ot200_backlight_remove(struct platform_device *pdev) | |||
152 | MAX_COMP2 - dim_table[100]); | 147 | MAX_COMP2 - dim_table[100]); |
153 | 148 | ||
154 | cs5535_mfgpt_free_timer(pwm_timer); | 149 | cs5535_mfgpt_free_timer(pwm_timer); |
155 | gpio_free(GPIO_DIMM); | ||
156 | 150 | ||
157 | kfree(data); | ||
158 | return 0; | 151 | return 0; |
159 | } | 152 | } |
160 | 153 | ||
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 342b7d7cbb63..995f0164c9b0 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c | |||
@@ -26,11 +26,13 @@ struct pwm_bl_data { | |||
26 | struct device *dev; | 26 | struct device *dev; |
27 | unsigned int period; | 27 | unsigned int period; |
28 | unsigned int lth_brightness; | 28 | unsigned int lth_brightness; |
29 | unsigned int *levels; | ||
29 | int (*notify)(struct device *, | 30 | int (*notify)(struct device *, |
30 | int brightness); | 31 | int brightness); |
31 | void (*notify_after)(struct device *, | 32 | void (*notify_after)(struct device *, |
32 | int brightness); | 33 | int brightness); |
33 | int (*check_fb)(struct device *, struct fb_info *); | 34 | int (*check_fb)(struct device *, struct fb_info *); |
35 | void (*exit)(struct device *); | ||
34 | }; | 36 | }; |
35 | 37 | ||
36 | static int pwm_backlight_update_status(struct backlight_device *bl) | 38 | static int pwm_backlight_update_status(struct backlight_device *bl) |
@@ -52,9 +54,18 @@ static int pwm_backlight_update_status(struct backlight_device *bl) | |||
52 | pwm_config(pb->pwm, 0, pb->period); | 54 | pwm_config(pb->pwm, 0, pb->period); |
53 | pwm_disable(pb->pwm); | 55 | pwm_disable(pb->pwm); |
54 | } else { | 56 | } else { |
55 | brightness = pb->lth_brightness + | 57 | int duty_cycle; |
56 | (brightness * (pb->period - pb->lth_brightness) / max); | 58 | |
57 | pwm_config(pb->pwm, brightness, pb->period); | 59 | if (pb->levels) { |
60 | duty_cycle = pb->levels[brightness]; | ||
61 | max = pb->levels[max]; | ||
62 | } else { | ||
63 | duty_cycle = brightness; | ||
64 | } | ||
65 | |||
66 | duty_cycle = pb->lth_brightness + | ||
67 | (duty_cycle * (pb->period - pb->lth_brightness) / max); | ||
68 | pwm_config(pb->pwm, duty_cycle, pb->period); | ||
58 | pwm_enable(pb->pwm); | 69 | pwm_enable(pb->pwm); |
59 | } | 70 | } |
60 | 71 | ||
@@ -83,17 +94,98 @@ static const struct backlight_ops pwm_backlight_ops = { | |||
83 | .check_fb = pwm_backlight_check_fb, | 94 | .check_fb = pwm_backlight_check_fb, |
84 | }; | 95 | }; |
85 | 96 | ||
97 | #ifdef CONFIG_OF | ||
98 | static int pwm_backlight_parse_dt(struct device *dev, | ||
99 | struct platform_pwm_backlight_data *data) | ||
100 | { | ||
101 | struct device_node *node = dev->of_node; | ||
102 | struct property *prop; | ||
103 | int length; | ||
104 | u32 value; | ||
105 | int ret; | ||
106 | |||
107 | if (!node) | ||
108 | return -ENODEV; | ||
109 | |||
110 | memset(data, 0, sizeof(*data)); | ||
111 | |||
112 | /* determine the number of brightness levels */ | ||
113 | prop = of_find_property(node, "brightness-levels", &length); | ||
114 | if (!prop) | ||
115 | return -EINVAL; | ||
116 | |||
117 | data->max_brightness = length / sizeof(u32); | ||
118 | |||
119 | /* read brightness levels from DT property */ | ||
120 | if (data->max_brightness > 0) { | ||
121 | size_t size = sizeof(*data->levels) * data->max_brightness; | ||
122 | |||
123 | data->levels = devm_kzalloc(dev, size, GFP_KERNEL); | ||
124 | if (!data->levels) | ||
125 | return -ENOMEM; | ||
126 | |||
127 | ret = of_property_read_u32_array(node, "brightness-levels", | ||
128 | data->levels, | ||
129 | data->max_brightness); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | |||
133 | ret = of_property_read_u32(node, "default-brightness-level", | ||
134 | &value); | ||
135 | if (ret < 0) | ||
136 | return ret; | ||
137 | |||
138 | if (value >= data->max_brightness) { | ||
139 | dev_warn(dev, "invalid default brightness level: %u, using %u\n", | ||
140 | value, data->max_brightness - 1); | ||
141 | value = data->max_brightness - 1; | ||
142 | } | ||
143 | |||
144 | data->dft_brightness = value; | ||
145 | data->max_brightness--; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * TODO: Most users of this driver use a number of GPIOs to control | ||
150 | * backlight power. Support for specifying these needs to be | ||
151 | * added. | ||
152 | */ | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static struct of_device_id pwm_backlight_of_match[] = { | ||
158 | { .compatible = "pwm-backlight" }, | ||
159 | { } | ||
160 | }; | ||
161 | |||
162 | MODULE_DEVICE_TABLE(of, pwm_backlight_of_match); | ||
163 | #else | ||
164 | static int pwm_backlight_parse_dt(struct device *dev, | ||
165 | struct platform_pwm_backlight_data *data) | ||
166 | { | ||
167 | return -ENODEV; | ||
168 | } | ||
169 | #endif | ||
170 | |||
86 | static int pwm_backlight_probe(struct platform_device *pdev) | 171 | static int pwm_backlight_probe(struct platform_device *pdev) |
87 | { | 172 | { |
88 | struct backlight_properties props; | ||
89 | struct platform_pwm_backlight_data *data = pdev->dev.platform_data; | 173 | struct platform_pwm_backlight_data *data = pdev->dev.platform_data; |
174 | struct platform_pwm_backlight_data defdata; | ||
175 | struct backlight_properties props; | ||
90 | struct backlight_device *bl; | 176 | struct backlight_device *bl; |
91 | struct pwm_bl_data *pb; | 177 | struct pwm_bl_data *pb; |
178 | unsigned int max; | ||
92 | int ret; | 179 | int ret; |
93 | 180 | ||
94 | if (!data) { | 181 | if (!data) { |
95 | dev_err(&pdev->dev, "failed to find platform data\n"); | 182 | ret = pwm_backlight_parse_dt(&pdev->dev, &defdata); |
96 | return -EINVAL; | 183 | if (ret < 0) { |
184 | dev_err(&pdev->dev, "failed to find platform data\n"); | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | data = &defdata; | ||
97 | } | 189 | } |
98 | 190 | ||
99 | if (data->init) { | 191 | if (data->init) { |
@@ -109,21 +201,42 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
109 | goto err_alloc; | 201 | goto err_alloc; |
110 | } | 202 | } |
111 | 203 | ||
112 | pb->period = data->pwm_period_ns; | 204 | if (data->levels) { |
205 | max = data->levels[data->max_brightness]; | ||
206 | pb->levels = data->levels; | ||
207 | } else | ||
208 | max = data->max_brightness; | ||
209 | |||
113 | pb->notify = data->notify; | 210 | pb->notify = data->notify; |
114 | pb->notify_after = data->notify_after; | 211 | pb->notify_after = data->notify_after; |
115 | pb->check_fb = data->check_fb; | 212 | pb->check_fb = data->check_fb; |
116 | pb->lth_brightness = data->lth_brightness * | 213 | pb->exit = data->exit; |
117 | (data->pwm_period_ns / data->max_brightness); | ||
118 | pb->dev = &pdev->dev; | 214 | pb->dev = &pdev->dev; |
119 | 215 | ||
120 | pb->pwm = pwm_request(data->pwm_id, "backlight"); | 216 | pb->pwm = pwm_get(&pdev->dev, NULL); |
121 | if (IS_ERR(pb->pwm)) { | 217 | if (IS_ERR(pb->pwm)) { |
122 | dev_err(&pdev->dev, "unable to request PWM for backlight\n"); | 218 | dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); |
123 | ret = PTR_ERR(pb->pwm); | 219 | |
124 | goto err_alloc; | 220 | pb->pwm = pwm_request(data->pwm_id, "pwm-backlight"); |
125 | } else | 221 | if (IS_ERR(pb->pwm)) { |
126 | dev_dbg(&pdev->dev, "got pwm for backlight\n"); | 222 | dev_err(&pdev->dev, "unable to request legacy PWM\n"); |
223 | ret = PTR_ERR(pb->pwm); | ||
224 | goto err_alloc; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | dev_dbg(&pdev->dev, "got pwm for backlight\n"); | ||
229 | |||
230 | /* | ||
231 | * The DT case will set the pwm_period_ns field to 0 and store the | ||
232 | * period, parsed from the DT, in the PWM device. For the non-DT case, | ||
233 | * set the period from platform data. | ||
234 | */ | ||
235 | if (data->pwm_period_ns > 0) | ||
236 | pwm_set_period(pb->pwm, data->pwm_period_ns); | ||
237 | |||
238 | pb->period = pwm_get_period(pb->pwm); | ||
239 | pb->lth_brightness = data->lth_brightness * (pb->period / max); | ||
127 | 240 | ||
128 | memset(&props, 0, sizeof(struct backlight_properties)); | 241 | memset(&props, 0, sizeof(struct backlight_properties)); |
129 | props.type = BACKLIGHT_RAW; | 242 | props.type = BACKLIGHT_RAW; |
@@ -143,7 +256,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
143 | return 0; | 256 | return 0; |
144 | 257 | ||
145 | err_bl: | 258 | err_bl: |
146 | pwm_free(pb->pwm); | 259 | pwm_put(pb->pwm); |
147 | err_alloc: | 260 | err_alloc: |
148 | if (data->exit) | 261 | if (data->exit) |
149 | data->exit(&pdev->dev); | 262 | data->exit(&pdev->dev); |
@@ -152,16 +265,15 @@ err_alloc: | |||
152 | 265 | ||
153 | static int pwm_backlight_remove(struct platform_device *pdev) | 266 | static int pwm_backlight_remove(struct platform_device *pdev) |
154 | { | 267 | { |
155 | struct platform_pwm_backlight_data *data = pdev->dev.platform_data; | ||
156 | struct backlight_device *bl = platform_get_drvdata(pdev); | 268 | struct backlight_device *bl = platform_get_drvdata(pdev); |
157 | struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); | 269 | struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); |
158 | 270 | ||
159 | backlight_device_unregister(bl); | 271 | backlight_device_unregister(bl); |
160 | pwm_config(pb->pwm, 0, pb->period); | 272 | pwm_config(pb->pwm, 0, pb->period); |
161 | pwm_disable(pb->pwm); | 273 | pwm_disable(pb->pwm); |
162 | pwm_free(pb->pwm); | 274 | pwm_put(pb->pwm); |
163 | if (data->exit) | 275 | if (pb->exit) |
164 | data->exit(&pdev->dev); | 276 | pb->exit(&pdev->dev); |
165 | return 0; | 277 | return 0; |
166 | } | 278 | } |
167 | 279 | ||
@@ -195,11 +307,12 @@ static SIMPLE_DEV_PM_OPS(pwm_backlight_pm_ops, pwm_backlight_suspend, | |||
195 | 307 | ||
196 | static struct platform_driver pwm_backlight_driver = { | 308 | static struct platform_driver pwm_backlight_driver = { |
197 | .driver = { | 309 | .driver = { |
198 | .name = "pwm-backlight", | 310 | .name = "pwm-backlight", |
199 | .owner = THIS_MODULE, | 311 | .owner = THIS_MODULE, |
200 | #ifdef CONFIG_PM | 312 | #ifdef CONFIG_PM |
201 | .pm = &pwm_backlight_pm_ops, | 313 | .pm = &pwm_backlight_pm_ops, |
202 | #endif | 314 | #endif |
315 | .of_match_table = of_match_ptr(pwm_backlight_of_match), | ||
203 | }, | 316 | }, |
204 | .probe = pwm_backlight_probe, | 317 | .probe = pwm_backlight_probe, |
205 | .remove = pwm_backlight_remove, | 318 | .remove = pwm_backlight_remove, |
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index 0d54e607e82d..49342e1d20be 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c | |||
@@ -92,14 +92,14 @@ static int __devinit tosa_bl_probe(struct i2c_client *client, | |||
92 | 92 | ||
93 | data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj; | 93 | data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj; |
94 | 94 | ||
95 | ret = gpio_request(TOSA_GPIO_BL_C20MA, "backlight"); | 95 | ret = devm_gpio_request(&client->dev, TOSA_GPIO_BL_C20MA, "backlight"); |
96 | if (ret) { | 96 | if (ret) { |
97 | dev_dbg(&data->bl->dev, "Unable to request gpio!\n"); | 97 | dev_dbg(&data->bl->dev, "Unable to request gpio!\n"); |
98 | return ret; | 98 | return ret; |
99 | } | 99 | } |
100 | ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0); | 100 | ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0); |
101 | if (ret) | 101 | if (ret) |
102 | goto err_gpio_dir; | 102 | return ret; |
103 | 103 | ||
104 | i2c_set_clientdata(client, data); | 104 | i2c_set_clientdata(client, data); |
105 | data->i2c = client; | 105 | data->i2c = client; |
@@ -123,8 +123,6 @@ static int __devinit tosa_bl_probe(struct i2c_client *client, | |||
123 | 123 | ||
124 | err_reg: | 124 | err_reg: |
125 | data->bl = NULL; | 125 | data->bl = NULL; |
126 | err_gpio_dir: | ||
127 | gpio_free(TOSA_GPIO_BL_C20MA); | ||
128 | return ret; | 126 | return ret; |
129 | } | 127 | } |
130 | 128 | ||
@@ -135,8 +133,6 @@ static int __devexit tosa_bl_remove(struct i2c_client *client) | |||
135 | backlight_device_unregister(data->bl); | 133 | backlight_device_unregister(data->bl); |
136 | data->bl = NULL; | 134 | data->bl = NULL; |
137 | 135 | ||
138 | gpio_free(TOSA_GPIO_BL_C20MA); | ||
139 | |||
140 | return 0; | 136 | return 0; |
141 | } | 137 | } |
142 | 138 | ||
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index 47823b8efff0..33047a66cc24 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c | |||
@@ -193,7 +193,7 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi) | |||
193 | data->spi = spi; | 193 | data->spi = spi; |
194 | dev_set_drvdata(&spi->dev, data); | 194 | dev_set_drvdata(&spi->dev, data); |
195 | 195 | ||
196 | ret = gpio_request(TOSA_GPIO_TG_ON, "tg #pwr"); | 196 | ret = devm_gpio_request(&spi->dev, TOSA_GPIO_TG_ON, "tg #pwr"); |
197 | if (ret < 0) | 197 | if (ret < 0) |
198 | goto err_gpio_tg; | 198 | goto err_gpio_tg; |
199 | 199 | ||
@@ -201,7 +201,7 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi) | |||
201 | 201 | ||
202 | ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0); | 202 | ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0); |
203 | if (ret < 0) | 203 | if (ret < 0) |
204 | goto err_gpio_dir; | 204 | goto err_gpio_tg; |
205 | 205 | ||
206 | mdelay(60); | 206 | mdelay(60); |
207 | tosa_lcd_tg_init(data); | 207 | tosa_lcd_tg_init(data); |
@@ -221,8 +221,6 @@ static int __devinit tosa_lcd_probe(struct spi_device *spi) | |||
221 | 221 | ||
222 | err_register: | 222 | err_register: |
223 | tosa_lcd_tg_off(data); | 223 | tosa_lcd_tg_off(data); |
224 | err_gpio_dir: | ||
225 | gpio_free(TOSA_GPIO_TG_ON); | ||
226 | err_gpio_tg: | 224 | err_gpio_tg: |
227 | dev_set_drvdata(&spi->dev, NULL); | 225 | dev_set_drvdata(&spi->dev, NULL); |
228 | return ret; | 226 | return ret; |
@@ -239,7 +237,6 @@ static int __devexit tosa_lcd_remove(struct spi_device *spi) | |||
239 | 237 | ||
240 | tosa_lcd_tg_off(data); | 238 | tosa_lcd_tg_off(data); |
241 | 239 | ||
242 | gpio_free(TOSA_GPIO_TG_ON); | ||
243 | dev_set_drvdata(&spi->dev, NULL); | 240 | dev_set_drvdata(&spi->dev, NULL); |
244 | 241 | ||
245 | return 0; | 242 | return 0; |
diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c index 33ea874c87d2..d0f121bd8b25 100644 --- a/drivers/video/bfin_adv7393fb.c +++ b/drivers/video/bfin_adv7393fb.c | |||
@@ -58,7 +58,7 @@ static const unsigned short ppi_pins[] = { | |||
58 | */ | 58 | */ |
59 | 59 | ||
60 | static struct bfin_adv7393_fb_par { | 60 | static struct bfin_adv7393_fb_par { |
61 | /* structure holding blackfin / adv7393 paramters when | 61 | /* structure holding blackfin / adv7393 parameters when |
62 | screen is blanked */ | 62 | screen is blanked */ |
63 | struct { | 63 | struct { |
64 | u8 Mode; /* ntsc/pal/? */ | 64 | u8 Mode; /* ntsc/pal/? */ |
@@ -353,18 +353,16 @@ adv7393_read_proc(char *page, char **start, off_t off, | |||
353 | 353 | ||
354 | static int | 354 | static int |
355 | adv7393_write_proc(struct file *file, const char __user * buffer, | 355 | adv7393_write_proc(struct file *file, const char __user * buffer, |
356 | unsigned long count, void *data) | 356 | size_t count, void *data) |
357 | { | 357 | { |
358 | struct adv7393fb_device *fbdev = data; | 358 | struct adv7393fb_device *fbdev = data; |
359 | char line[8]; | ||
360 | unsigned int val; | 359 | unsigned int val; |
361 | int ret; | 360 | int ret; |
362 | 361 | ||
363 | ret = copy_from_user(line, buffer, count); | 362 | ret = kstrtouint_from_user(buffer, count, 0, &val); |
364 | if (ret) | 363 | if (ret) |
365 | return -EFAULT; | 364 | return -EFAULT; |
366 | 365 | ||
367 | val = simple_strtoul(line, NULL, 0); | ||
368 | adv7393_write(fbdev->client, val >> 8, val & 0xff); | 366 | adv7393_write(fbdev->client, val >> 8, val & 0xff); |
369 | 367 | ||
370 | return count; | 368 | return count; |
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c index 377dde3d5bfc..c95b417d0d41 100644 --- a/drivers/video/broadsheetfb.c +++ b/drivers/video/broadsheetfb.c | |||
@@ -1211,7 +1211,7 @@ static int __devexit broadsheetfb_remove(struct platform_device *dev) | |||
1211 | 1211 | ||
1212 | static struct platform_driver broadsheetfb_driver = { | 1212 | static struct platform_driver broadsheetfb_driver = { |
1213 | .probe = broadsheetfb_probe, | 1213 | .probe = broadsheetfb_probe, |
1214 | .remove = broadsheetfb_remove, | 1214 | .remove = __devexit_p(broadsheetfb_remove), |
1215 | .driver = { | 1215 | .driver = { |
1216 | .owner = THIS_MODULE, | 1216 | .owner = THIS_MODULE, |
1217 | .name = "broadsheetfb", | 1217 | .name = "broadsheetfb", |
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 738c8ce7d132..bc67d05cad60 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -1611,7 +1611,7 @@ static void init_vgachip(struct fb_info *info) | |||
1611 | /* ext. display controls: ext.adr. wrap */ | 1611 | /* ext. display controls: ext.adr. wrap */ |
1612 | vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02); | 1612 | vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02); |
1613 | 1613 | ||
1614 | /* Set/Reset registes: - */ | 1614 | /* Set/Reset registers: - */ |
1615 | vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00); | 1615 | vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00); |
1616 | /* Set/Reset enable: - */ | 1616 | /* Set/Reset enable: - */ |
1617 | vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00); | 1617 | vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00); |
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index c2d11fef114b..e2c96d01d8f5 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -224,5 +224,19 @@ config FONT_10x18 | |||
224 | big letters. It fits between the sun 12x22 and the normal 8x16 font. | 224 | big letters. It fits between the sun 12x22 and the normal 8x16 font. |
225 | If other fonts are too big or too small for you, say Y, otherwise say N. | 225 | If other fonts are too big or too small for you, say Y, otherwise say N. |
226 | 226 | ||
227 | config FONT_AUTOSELECT | ||
228 | def_bool y | ||
229 | depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE || STI_CONSOLE || USB_SISUSBVGA_CON | ||
230 | depends on !FONT_8x8 | ||
231 | depends on !FONT_6x11 | ||
232 | depends on !FONT_7x14 | ||
233 | depends on !FONT_PEARL_8x8 | ||
234 | depends on !FONT_ACORN_8x8 | ||
235 | depends on !FONT_MINI_4x6 | ||
236 | depends on !FONT_SUN8x16 | ||
237 | depends on !FONT_SUN12x22 | ||
238 | depends on !FONT_10x18 | ||
239 | select FONT_8x16 | ||
240 | |||
227 | endmenu | 241 | endmenu |
228 | 242 | ||
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 2e471c22abf5..88e92041d8f0 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -372,8 +372,15 @@ static void fb_flashcursor(struct work_struct *work) | |||
372 | struct vc_data *vc = NULL; | 372 | struct vc_data *vc = NULL; |
373 | int c; | 373 | int c; |
374 | int mode; | 374 | int mode; |
375 | int ret; | ||
376 | |||
377 | /* FIXME: we should sort out the unbind locking instead */ | ||
378 | /* instead we just fail to flash the cursor if we can't get | ||
379 | * the lock instead of blocking fbcon deinit */ | ||
380 | ret = console_trylock(); | ||
381 | if (ret == 0) | ||
382 | return; | ||
375 | 383 | ||
376 | console_lock(); | ||
377 | if (ops && ops->currcon != -1) | 384 | if (ops && ops->currcon != -1) |
378 | vc = vc_cons[ops->currcon].d; | 385 | vc = vc_cons[ops->currcon].d; |
379 | 386 | ||
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 | ||
286 | static void lcd_blit(int load_mode, struct da8xx_fb_par *par) | 300 | static 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 */ |
348 | static int lcd_cfg_dma(int burst_size) | 362 | static 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 | ||
480 | static int epson1355_width_tab[2][4] __initdata = | 480 | static 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} }; |
482 | static int epson1355_bpp_tab[8] __initdata = { 1, 2, 4, 8, 15, 16 }; | 482 | static int epson1355_bpp_tab[8] __devinitdata = { 1, 2, 4, 8, 15, 16 }; |
483 | 483 | ||
484 | static void __init fetch_hw_state(struct fb_info *info, struct epson1355_par *par) | 484 | static 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 | ||
604 | int __devinit epson1355fb_probe(struct platform_device *dev) | 604 | static 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); | |||
85 | void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype); | 85 | void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype); |
86 | void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count); | 86 | void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count); |
87 | void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count); | 87 | void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count); |
88 | void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype); | ||
89 | void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype); | ||
90 | void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count); | ||
91 | void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count); | ||
92 | void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable); | 88 | void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable); |
93 | void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, | 89 | void 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 6ce76d56c3a1..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 | ||
@@ -752,7 +752,7 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, | |||
752 | 752 | ||
753 | /* | 753 | /* |
754 | * If Rx sends defer, Tx sends only reads | 754 | * If Rx sends defer, Tx sends only reads |
755 | * request without sending addres | 755 | * request without sending address |
756 | */ | 756 | */ |
757 | if (!defer) | 757 | if (!defer) |
758 | retval = exynos_dp_select_i2c_device(dp, | 758 | retval = exynos_dp_select_i2c_device(dp, |
@@ -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 6c1f5c314a42..4bc2b8a5dd8b 100644 --- a/drivers/video/exynos/exynos_mipi_dsi.c +++ b/drivers/video/exynos/exynos_mipi_dsi.c | |||
@@ -106,7 +106,7 @@ static void exynos_mipi_update_cfg(struct mipi_dsim_device *dsim) | |||
106 | 106 | ||
107 | /* | 107 | /* |
108 | * data from Display controller(FIMD) is transferred in video mode | 108 | * data from Display controller(FIMD) is transferred in video mode |
109 | * but in case of command mode, all settigs is updated to registers. | 109 | * but in case of command mode, all settings are updated to registers. |
110 | */ | 110 | */ |
111 | exynos_mipi_dsi_stand_by(dsim, 1); | 111 | exynos_mipi_dsi_stand_by(dsim, 1); |
112 | } | 112 | } |
@@ -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 | |||
18 | extern void s6e8ax0_init(void); | ||
19 | |||
20 | #endif | ||
21 | |||
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 1ddeb11659d4..64cda560c488 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c | |||
@@ -104,6 +104,8 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, | |||
104 | deferred framebuffer IO. then if userspace touches a page | 104 | deferred framebuffer IO. then if userspace touches a page |
105 | again, we repeat the same scheme */ | 105 | again, we repeat the same scheme */ |
106 | 106 | ||
107 | file_update_time(vma->vm_file); | ||
108 | |||
107 | /* protect against the workqueue changing the page list */ | 109 | /* protect against the workqueue changing the page list */ |
108 | mutex_lock(&fbdefio->lock); | 110 | mutex_lock(&fbdefio->lock); |
109 | 111 | ||
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 | ||
496 | err4: | 498 | free_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); |
503 | err3: | 504 | dealloc_cmap: |
504 | fb_dealloc_cmap(&info->cmap); | 505 | fb_dealloc_cmap(&info->cmap); |
505 | err2: | 506 | unmap_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])); |
508 | err1: | 509 | free_fb: |
509 | release_mem_region(dev->resource[0].start, resource_size(&dev->resource[0])); | ||
510 | err: | ||
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/i740fb.c b/drivers/video/i740fb.c index fe574d84ed99..ff3f8808e4e9 100644 --- a/drivers/video/i740fb.c +++ b/drivers/video/i740fb.c | |||
@@ -497,7 +497,7 @@ static int i740fb_decode_var(const struct fb_var_screeninfo *var, | |||
497 | 497 | ||
498 | mem = vxres * vyres * ((bpp + 1) / 8); | 498 | mem = vxres * vyres * ((bpp + 1) / 8); |
499 | if (mem > info->screen_size) { | 499 | if (mem > info->screen_size) { |
500 | dev_err(info->device, "not enough video memory (%d KB requested, %ld KB avaliable)\n", | 500 | dev_err(info->device, "not enough video memory (%d KB requested, %ld KB available)\n", |
501 | mem >> 10, info->screen_size >> 10); | 501 | mem >> 10, info->screen_size >> 10); |
502 | return -ENOMEM; | 502 | return -ENOMEM; |
503 | } | 503 | } |
@@ -728,7 +728,7 @@ static void vga_protect(struct i740fb_par *par) | |||
728 | i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0x20, 0x20); | 728 | i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0x20, 0x20); |
729 | 729 | ||
730 | i740inb(par, 0x3DA); | 730 | i740inb(par, 0x3DA); |
731 | i740outb(par, VGA_ATT_W, 0x00); /* enable pallete access */ | 731 | i740outb(par, VGA_ATT_W, 0x00); /* enable palette access */ |
732 | } | 732 | } |
733 | 733 | ||
734 | static void vga_unprotect(struct i740fb_par *par) | 734 | static void vga_unprotect(struct i740fb_par *par) |
@@ -737,7 +737,7 @@ static void vga_unprotect(struct i740fb_par *par) | |||
737 | i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0, 0x20); | 737 | i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0, 0x20); |
738 | 738 | ||
739 | i740inb(par, 0x3DA); | 739 | i740inb(par, 0x3DA); |
740 | i740outb(par, VGA_ATT_W, 0x20); /* disable pallete access */ | 740 | i740outb(par, VGA_ATT_W, 0x20); /* disable palette access */ |
741 | } | 741 | } |
742 | 742 | ||
743 | static int i740fb_set_par(struct fb_info *info) | 743 | static int i740fb_set_par(struct fb_info *info) |
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index ab0a8e527333..85e4f44bfa61 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c | |||
@@ -1045,7 +1045,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev) | |||
1045 | 1045 | ||
1046 | static struct platform_driver mbxfb_driver = { | 1046 | static struct platform_driver mbxfb_driver = { |
1047 | .probe = mbxfb_probe, | 1047 | .probe = mbxfb_probe, |
1048 | .remove = mbxfb_remove, | 1048 | .remove = __devexit_p(mbxfb_remove), |
1049 | .suspend = mbxfb_suspend, | 1049 | .suspend = mbxfb_suspend, |
1050 | .resume = mbxfb_resume, | 1050 | .resume = mbxfb_resume, |
1051 | .driver = { | 1051 | .driver = { |
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 | ||
275 | static void mx3fb_dma_done(void *); | 275 | static 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 | ||
701 | static 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 | |||
701 | static int __set_par(struct fb_info *fbi, bool lock) | 721 | static 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/mxsfb.c b/drivers/video/mxsfb.c index abbe691047bd..49619b441500 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c | |||
@@ -41,12 +41,14 @@ | |||
41 | 41 | ||
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
44 | #include <linux/of_device.h> | ||
45 | #include <linux/of_gpio.h> | ||
44 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
45 | #include <linux/clk.h> | 47 | #include <linux/clk.h> |
46 | #include <linux/dma-mapping.h> | 48 | #include <linux/dma-mapping.h> |
47 | #include <linux/io.h> | 49 | #include <linux/io.h> |
48 | #include <linux/pinctrl/consumer.h> | 50 | #include <linux/pinctrl/consumer.h> |
49 | #include <mach/mxsfb.h> | 51 | #include <linux/mxsfb.h> |
50 | 52 | ||
51 | #define REG_SET 4 | 53 | #define REG_SET 4 |
52 | #define REG_CLR 8 | 54 | #define REG_CLR 8 |
@@ -750,16 +752,43 @@ static void __devexit mxsfb_free_videomem(struct mxsfb_info *host) | |||
750 | } | 752 | } |
751 | } | 753 | } |
752 | 754 | ||
755 | static struct platform_device_id mxsfb_devtype[] = { | ||
756 | { | ||
757 | .name = "imx23-fb", | ||
758 | .driver_data = MXSFB_V3, | ||
759 | }, { | ||
760 | .name = "imx28-fb", | ||
761 | .driver_data = MXSFB_V4, | ||
762 | }, { | ||
763 | /* sentinel */ | ||
764 | } | ||
765 | }; | ||
766 | MODULE_DEVICE_TABLE(platform, mxsfb_devtype); | ||
767 | |||
768 | static const struct of_device_id mxsfb_dt_ids[] = { | ||
769 | { .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], }, | ||
770 | { .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], }, | ||
771 | { /* sentinel */ } | ||
772 | }; | ||
773 | MODULE_DEVICE_TABLE(of, mxsfb_dt_ids); | ||
774 | |||
753 | static int __devinit mxsfb_probe(struct platform_device *pdev) | 775 | static int __devinit mxsfb_probe(struct platform_device *pdev) |
754 | { | 776 | { |
777 | const struct of_device_id *of_id = | ||
778 | of_match_device(mxsfb_dt_ids, &pdev->dev); | ||
755 | struct mxsfb_platform_data *pdata = pdev->dev.platform_data; | 779 | struct mxsfb_platform_data *pdata = pdev->dev.platform_data; |
756 | struct resource *res; | 780 | struct resource *res; |
757 | struct mxsfb_info *host; | 781 | struct mxsfb_info *host; |
758 | struct fb_info *fb_info; | 782 | struct fb_info *fb_info; |
759 | struct fb_modelist *modelist; | 783 | struct fb_modelist *modelist; |
760 | struct pinctrl *pinctrl; | 784 | struct pinctrl *pinctrl; |
785 | int panel_enable; | ||
786 | enum of_gpio_flags flags; | ||
761 | int i, ret; | 787 | int i, ret; |
762 | 788 | ||
789 | if (of_id) | ||
790 | pdev->id_entry = of_id->data; | ||
791 | |||
763 | if (!pdata) { | 792 | if (!pdata) { |
764 | dev_err(&pdev->dev, "No platformdata. Giving up\n"); | 793 | dev_err(&pdev->dev, "No platformdata. Giving up\n"); |
765 | return -ENODEV; | 794 | return -ENODEV; |
@@ -807,6 +836,22 @@ static int __devinit mxsfb_probe(struct platform_device *pdev) | |||
807 | goto error_getclock; | 836 | goto error_getclock; |
808 | } | 837 | } |
809 | 838 | ||
839 | panel_enable = of_get_named_gpio_flags(pdev->dev.of_node, | ||
840 | "panel-enable-gpios", 0, &flags); | ||
841 | if (gpio_is_valid(panel_enable)) { | ||
842 | unsigned long f = GPIOF_OUT_INIT_HIGH; | ||
843 | if (flags == OF_GPIO_ACTIVE_LOW) | ||
844 | f = GPIOF_OUT_INIT_LOW; | ||
845 | ret = devm_gpio_request_one(&pdev->dev, panel_enable, | ||
846 | f, "panel-enable"); | ||
847 | if (ret) { | ||
848 | dev_err(&pdev->dev, | ||
849 | "failed to request gpio %d: %d\n", | ||
850 | panel_enable, ret); | ||
851 | goto error_panel_enable; | ||
852 | } | ||
853 | } | ||
854 | |||
810 | fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); | 855 | fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); |
811 | if (!fb_info->pseudo_palette) { | 856 | if (!fb_info->pseudo_palette) { |
812 | ret = -ENOMEM; | 857 | ret = -ENOMEM; |
@@ -854,6 +899,7 @@ error_register: | |||
854 | error_init_fb: | 899 | error_init_fb: |
855 | kfree(fb_info->pseudo_palette); | 900 | kfree(fb_info->pseudo_palette); |
856 | error_pseudo_pallette: | 901 | error_pseudo_pallette: |
902 | error_panel_enable: | ||
857 | clk_put(host->clk); | 903 | clk_put(host->clk); |
858 | error_getclock: | 904 | error_getclock: |
859 | error_getpin: | 905 | error_getpin: |
@@ -901,19 +947,6 @@ static void mxsfb_shutdown(struct platform_device *pdev) | |||
901 | writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); | 947 | writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR); |
902 | } | 948 | } |
903 | 949 | ||
904 | static struct platform_device_id mxsfb_devtype[] = { | ||
905 | { | ||
906 | .name = "imx23-fb", | ||
907 | .driver_data = MXSFB_V3, | ||
908 | }, { | ||
909 | .name = "imx28-fb", | ||
910 | .driver_data = MXSFB_V4, | ||
911 | }, { | ||
912 | /* sentinel */ | ||
913 | } | ||
914 | }; | ||
915 | MODULE_DEVICE_TABLE(platform, mxsfb_devtype); | ||
916 | |||
917 | static struct platform_driver mxsfb_driver = { | 950 | static struct platform_driver mxsfb_driver = { |
918 | .probe = mxsfb_probe, | 951 | .probe = mxsfb_probe, |
919 | .remove = __devexit_p(mxsfb_remove), | 952 | .remove = __devexit_p(mxsfb_remove), |
@@ -921,6 +954,7 @@ static struct platform_driver mxsfb_driver = { | |||
921 | .id_table = mxsfb_devtype, | 954 | .id_table = mxsfb_devtype, |
922 | .driver = { | 955 | .driver = { |
923 | .name = DRIVER_NAME, | 956 | .name = DRIVER_NAME, |
957 | .of_match_table = mxsfb_dt_ids, | ||
924 | }, | 958 | }, |
925 | }; | 959 | }; |
926 | 960 | ||
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index c35a248c5e35..58bd9c27369d 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c | |||
@@ -206,8 +206,7 @@ static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d) | |||
206 | { | 206 | { |
207 | DSSDBG("pm notif %lu\n", v); | 207 | DSSDBG("pm notif %lu\n", v); |
208 | 208 | ||
209 | switch (v) | 209 | switch (v) { |
210 | { | ||
211 | case PM_SUSPEND_PREPARE: | 210 | case PM_SUSPEND_PREPARE: |
212 | DSSDBG("suspending displays\n"); | 211 | DSSDBG("suspending displays\n"); |
213 | return dss_suspend_all_devices(); | 212 | return dss_suspend_all_devices(); |
@@ -221,8 +220,7 @@ static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d) | |||
221 | } | 220 | } |
222 | } | 221 | } |
223 | 222 | ||
224 | static struct notifier_block omap_dss_pm_notif_block = | 223 | static struct notifier_block omap_dss_pm_notif_block = { |
225 | { | ||
226 | .notifier_call = omap_dss_pm_notif, | 224 | .notifier_call = omap_dss_pm_notif, |
227 | }; | 225 | }; |
228 | 226 | ||
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 5f9d8e69029e..69bf9d07c237 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
@@ -189,7 +189,7 @@ struct s3c_fb_vsync { | |||
189 | 189 | ||
190 | /** | 190 | /** |
191 | * struct s3c_fb - overall hardware state of the hardware | 191 | * struct s3c_fb - overall hardware state of the hardware |
192 | * @slock: The spinlock protection for this data sturcture. | 192 | * @slock: The spinlock protection for this data sturucture. |
193 | * @dev: The device that we bound to, for printing, etc. | 193 | * @dev: The device that we bound to, for printing, etc. |
194 | * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. | 194 | * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. |
195 | * @lcd_clk: The clk (sclk) feeding pixclk. | 195 | * @lcd_clk: The clk (sclk) feeding pixclk. |
@@ -361,7 +361,7 @@ static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) | |||
361 | result = (unsigned int)tmp / 1000; | 361 | result = (unsigned int)tmp / 1000; |
362 | 362 | ||
363 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", | 363 | dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", |
364 | pixclk, clk, result, clk / result); | 364 | pixclk, clk, result, result ? clk / result : clk); |
365 | 365 | ||
366 | return result; | 366 | return result; |
367 | } | 367 | } |
@@ -1348,8 +1348,14 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win) | |||
1348 | writel(0, regs + VIDOSD_A(win, sfb->variant)); | 1348 | writel(0, regs + VIDOSD_A(win, sfb->variant)); |
1349 | writel(0, regs + VIDOSD_B(win, sfb->variant)); | 1349 | writel(0, regs + VIDOSD_B(win, sfb->variant)); |
1350 | writel(0, regs + VIDOSD_C(win, sfb->variant)); | 1350 | writel(0, regs + VIDOSD_C(win, sfb->variant)); |
1351 | reg = readl(regs + SHADOWCON); | 1351 | |
1352 | writel(reg & ~SHADOWCON_WINx_PROTECT(win), regs + SHADOWCON); | 1352 | if (sfb->variant.has_shadowcon) { |
1353 | reg = readl(sfb->regs + SHADOWCON); | ||
1354 | reg &= ~(SHADOWCON_WINx_PROTECT(win) | | ||
1355 | SHADOWCON_CHx_ENABLE(win) | | ||
1356 | SHADOWCON_CHx_LOCAL_ENABLE(win)); | ||
1357 | writel(reg, sfb->regs + SHADOWCON); | ||
1358 | } | ||
1353 | } | 1359 | } |
1354 | 1360 | ||
1355 | static int __devinit s3c_fb_probe(struct platform_device *pdev) | 1361 | static int __devinit s3c_fb_probe(struct platform_device *pdev) |
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/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index cee7803a0a1c..0d0f52c18fd8 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c | |||
@@ -662,7 +662,7 @@ static void savage_get_default_par(struct savagefb_par *par, struct savage_reg * | |||
662 | vga_out8(0x3c4, 0x18, par); | 662 | vga_out8(0x3c4, 0x18, par); |
663 | reg->SR18 = vga_in8(0x3c5, par); | 663 | reg->SR18 = vga_in8(0x3c5, par); |
664 | 664 | ||
665 | /* Save flat panel expansion regsters. */ | 665 | /* Save flat panel expansion registers. */ |
666 | if (par->chip == S3_SAVAGE_MX) { | 666 | if (par->chip == S3_SAVAGE_MX) { |
667 | int i; | 667 | int i; |
668 | 668 | ||
@@ -815,7 +815,7 @@ static void savage_set_default_par(struct savagefb_par *par, | |||
815 | vga_out8(0x3c4, 0x18, par); | 815 | vga_out8(0x3c4, 0x18, par); |
816 | vga_out8(0x3c5, reg->SR18, par); | 816 | vga_out8(0x3c5, reg->SR18, par); |
817 | 817 | ||
818 | /* Save flat panel expansion regsters. */ | 818 | /* Save flat panel expansion registers. */ |
819 | if (par->chip == S3_SAVAGE_MX) { | 819 | if (par->chip == S3_SAVAGE_MX) { |
820 | int i; | 820 | int i; |
821 | 821 | ||
@@ -1318,7 +1318,7 @@ static void savagefb_set_par_int(struct savagefb_par *par, struct savage_reg *r | |||
1318 | vga_out8(0x3c4, 0x15, par); | 1318 | vga_out8(0x3c4, 0x15, par); |
1319 | vga_out8(0x3c5, reg->SR15, par); | 1319 | vga_out8(0x3c5, reg->SR15, par); |
1320 | 1320 | ||
1321 | /* Restore flat panel expansion regsters. */ | 1321 | /* Restore flat panel expansion registers. */ |
1322 | if (par->chip == S3_SAVAGE_MX) { | 1322 | if (par->chip == S3_SAVAGE_MX) { |
1323 | int i; | 1323 | int i; |
1324 | 1324 | ||
@@ -1351,7 +1351,7 @@ static void savagefb_set_par_int(struct savagefb_par *par, struct savage_reg *r | |||
1351 | /* following part not present in X11 driver */ | 1351 | /* following part not present in X11 driver */ |
1352 | cr67 = vga_in8(0x3d5, par) & 0xf; | 1352 | cr67 = vga_in8(0x3d5, par) & 0xf; |
1353 | vga_out8(0x3d5, 0x50 | cr67, par); | 1353 | vga_out8(0x3d5, 0x50 | cr67, par); |
1354 | udelay(10000); | 1354 | mdelay(10); |
1355 | vga_out8(0x3d4, 0x67, par); | 1355 | vga_out8(0x3d4, 0x67, par); |
1356 | /* end of part */ | 1356 | /* end of part */ |
1357 | vga_out8(0x3d5, reg->CR67 & ~0x0c, par); | 1357 | vga_out8(0x3d5, reg->CR67 & ~0x0c, par); |
@@ -1904,11 +1904,11 @@ static int savage_init_hw(struct savagefb_par *par) | |||
1904 | vga_out8(0x3d4, 0x66, par); | 1904 | vga_out8(0x3d4, 0x66, par); |
1905 | cr66 = vga_in8(0x3d5, par); | 1905 | cr66 = vga_in8(0x3d5, par); |
1906 | vga_out8(0x3d5, cr66 | 0x02, par); | 1906 | vga_out8(0x3d5, cr66 | 0x02, par); |
1907 | udelay(10000); | 1907 | mdelay(10); |
1908 | 1908 | ||
1909 | vga_out8(0x3d4, 0x66, par); | 1909 | vga_out8(0x3d4, 0x66, par); |
1910 | vga_out8(0x3d5, cr66 & ~0x02, par); /* clear reset flag */ | 1910 | vga_out8(0x3d5, cr66 & ~0x02, par); /* clear reset flag */ |
1911 | udelay(10000); | 1911 | mdelay(10); |
1912 | 1912 | ||
1913 | 1913 | ||
1914 | /* | 1914 | /* |
@@ -1918,11 +1918,11 @@ static int savage_init_hw(struct savagefb_par *par) | |||
1918 | vga_out8(0x3d4, 0x3f, par); | 1918 | vga_out8(0x3d4, 0x3f, par); |
1919 | cr3f = vga_in8(0x3d5, par); | 1919 | cr3f = vga_in8(0x3d5, par); |
1920 | vga_out8(0x3d5, cr3f | 0x08, par); | 1920 | vga_out8(0x3d5, cr3f | 0x08, par); |
1921 | udelay(10000); | 1921 | mdelay(10); |
1922 | 1922 | ||
1923 | vga_out8(0x3d4, 0x3f, par); | 1923 | vga_out8(0x3d4, 0x3f, par); |
1924 | vga_out8(0x3d5, cr3f & ~0x08, par); /* clear reset flags */ | 1924 | vga_out8(0x3d5, cr3f & ~0x08, par); /* clear reset flags */ |
1925 | udelay(10000); | 1925 | mdelay(10); |
1926 | 1926 | ||
1927 | /* Savage ramdac speeds */ | 1927 | /* Savage ramdac speeds */ |
1928 | par->numClocks = 4; | 1928 | par->numClocks = 4; |
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 | ||
130 | static int __init sh_mipi_setup(struct sh_mipi *mipi, | 130 | static 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 | ||
554 | static int __exit sh_mipi_remove(struct platform_device *pdev) | 553 | static 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 | ||
594 | static struct platform_driver sh_mipi_driver = { | 593 | static 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 | ||
142 | enum 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 | */ | ||
174 | struct 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 | |||
41 | struct sh_mobile_lcdc_priv { | 206 | struct 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 | ||
312 | static 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 | |||
144 | static void lcdc_write(struct sh_mobile_lcdc_priv *priv, | 319 | static 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 | ||
387 | static int sh_mobile_check_var(struct fb_var_screeninfo *var, | 562 | static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var, |
388 | struct fb_info *info); | 563 | struct fb_info *info); |
389 | 564 | ||
390 | static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch, | 565 | static 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 | ||
588 | static int sh_mobile_wait_for_vsync(struct sh_mobile_lcdc_chan *ch) | 763 | static 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 | ||
863 | static 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 | ||
1244 | static 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 | |||
1325 | static ssize_t | ||
1326 | overlay_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 | |||
1334 | static ssize_t | ||
1335 | overlay_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 | |||
1363 | static ssize_t | ||
1364 | overlay_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 | |||
1372 | static ssize_t | ||
1373 | overlay_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 | |||
1401 | static ssize_t | ||
1402 | overlay_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 | |||
1411 | static ssize_t | ||
1412 | overlay_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 | |||
1443 | static ssize_t | ||
1444 | overlay_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 | |||
1452 | static ssize_t | ||
1453 | overlay_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 | |||
1481 | static 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 | |||
1492 | static 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 | |||
1503 | static 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 | |||
1551 | static 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 | |||
1565 | static 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 | |||
1571 | static 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. */ | ||
1604 | static 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 | |||
1617 | static 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 | |||
1631 | static void | ||
1632 | sh_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 | |||
1642 | static int __devinit | ||
1643 | sh_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 | |||
1670 | static void | ||
1671 | sh_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 | |||
1681 | static int __devinit | ||
1682 | sh_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 | ||
982 | static int sh_mobile_lcdc_setcolreg(u_int regno, | 1751 | static 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 | ||
1006 | static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { | 1775 | static 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 | ||
1038 | static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var, | 1807 | static 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 | ||
1102 | static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd, | 1866 | static 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 | */ |
1161 | static int sh_mobile_release(struct fb_info *info, int user) | 1926 | static 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 | ||
1182 | static int sh_mobile_open(struct fb_info *info, int user) | 1947 | static 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 | ||
1195 | static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 1960 | static 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 | ||
1316 | static int sh_mobile_set_par(struct fb_info *info) | 2016 | static 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 | ||
1413 | static void | 2113 | static 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 = { | |||
1712 | static int sh_mobile_lcdc_remove(struct platform_device *pdev) | 2417 | static 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 | ||
1798 | static int __devinit | 2518 | static int __devinit |
2519 | sh_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 | |||
2573 | static int __devinit | ||
1799 | sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, | 2574 | sh_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 | |||
201 | static unsigned long meram_alloc(struct sh_mobile_meram_priv *priv, size_t size) | ||
202 | { | ||
203 | return gen_pool_alloc(priv->pool, size); | ||
204 | } | ||
205 | |||
206 | static 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. */ |
201 | static int __meram_alloc(struct sh_mobile_meram_priv *priv, | 217 | static 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. */ |
232 | static void __meram_free(struct sh_mobile_meram_priv *priv, | 248 | static 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. */ | ||
252 | static struct sh_mobile_meram_fb_cache * | ||
253 | meram_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 | |||
291 | error: | ||
292 | kfree(cache); | ||
293 | return ERR_PTR(-ENOMEM); | ||
294 | } | ||
295 | |||
296 | /* Unmark the specified ICB as used. */ | ||
297 | static 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. */ |
308 | static void meram_set_next_addr(struct sh_mobile_meram_priv *priv, | 268 | static 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. */ |
358 | static int meram_init(struct sh_mobile_meram_priv *priv, | 318 | static 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 | ||
430 | static void meram_deinit(struct sh_mobile_meram_priv *priv, | 390 | static 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 | ||
447 | static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata, | 407 | unsigned 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 | } | ||
414 | EXPORT_SYMBOL_GPL(sh_mobile_meram_alloc); | ||
415 | |||
416 | void 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 | } | ||
423 | EXPORT_SYMBOL_GPL(sh_mobile_meram_free); | ||
424 | |||
425 | /* Allocate memory for the ICBs and mark them as used. */ | ||
426 | static struct sh_mobile_meram_fb_cache * | ||
427 | meram_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 | |||
461 | error: | ||
462 | kfree(cache); | ||
463 | return ERR_PTR(-ENOMEM); | ||
464 | } | ||
465 | |||
466 | void *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 | ||
492 | err: | 520 | err: |
493 | mutex_unlock(&priv->lock); | 521 | mutex_unlock(&priv->lock); |
494 | return cache; | 522 | return cache; |
495 | } | 523 | } |
524 | EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_alloc); | ||
496 | 525 | ||
497 | static void | 526 | void |
498 | sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata, void *data) | 527 | sh_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 | 547 | EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_free); | |
515 | static void | 548 | |
516 | sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, void *data, | 549 | void |
517 | unsigned long base_addr_y, unsigned long base_addr_c, | 550 | sh_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 | 566 | EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_update); | |
531 | static 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/sis/init.c b/drivers/video/sis/init.c index 66de832361cc..f082ae55c0c9 100644 --- a/drivers/video/sis/init.c +++ b/drivers/video/sis/init.c | |||
@@ -2628,7 +2628,8 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2628 | else if(VCLK >= 135) data = 0x02; | 2628 | else if(VCLK >= 135) data = 0x02; |
2629 | 2629 | ||
2630 | if(SiS_Pr->ChipType == SIS_540) { | 2630 | if(SiS_Pr->ChipType == SIS_540) { |
2631 | if((VCLK == 203) || (VCLK < 234)) data = 0x02; | 2631 | /* Was == 203 or < 234 which made no sense */ |
2632 | if (VCLK < 234) data = 0x02; | ||
2632 | } | 2633 | } |
2633 | 2634 | ||
2634 | if(SiS_Pr->ChipType < SIS_315H) { | 2635 | if(SiS_Pr->ChipType < SIS_315H) { |
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c index af3ef27ad36c..5533a32c6ca1 100644 --- a/drivers/video/smscufx.c +++ b/drivers/video/smscufx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * smscufx.c -- Framebuffer driver for SMSC UFX USB controller | 2 | * smscufx.c -- Framebuffer driver for SMSC UFX USB controller |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Steve Glendinning <steve.glendinning@smsc.com> | 4 | * Copyright (C) 2011 Steve Glendinning <steve.glendinning@shawell.net> |
5 | * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it> | 5 | * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it> |
6 | * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com> | 6 | * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com> |
7 | * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com> | 7 | * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com> |
@@ -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 | ||
@@ -1002,7 +1002,7 @@ static int ufx_ops_ioctl(struct fb_info *info, unsigned int cmd, | |||
1002 | /* TODO: Help propose a standard fb.h ioctl to report mmap damage */ | 1002 | /* TODO: Help propose a standard fb.h ioctl to report mmap damage */ |
1003 | if (cmd == UFX_IOCTL_REPORT_DAMAGE) { | 1003 | if (cmd == UFX_IOCTL_REPORT_DAMAGE) { |
1004 | /* If we have a damage-aware client, turn fb_defio "off" | 1004 | /* If we have a damage-aware client, turn fb_defio "off" |
1005 | * To avoid perf imact of unecessary page fault handling. | 1005 | * To avoid perf imact of unnecessary page fault handling. |
1006 | * Done by resetting the delay for this fb_info to a very | 1006 | * Done by resetting the delay for this fb_info to a very |
1007 | * long period. Pages will become writable and stay that way. | 1007 | * long period. Pages will become writable and stay that way. |
1008 | * Reset to normal value when all clients have closed this fb. | 1008 | * Reset to normal value when all clients have closed this fb. |
@@ -1466,7 +1466,7 @@ static int ufx_read_edid(struct ufx_data *dev, u8 *edid, int edid_len) | |||
1466 | /* all FF's in the first 16 bytes indicates nothing is connected */ | 1466 | /* all FF's in the first 16 bytes indicates nothing is connected */ |
1467 | for (i = 0; i < 16; i++) { | 1467 | for (i = 0; i < 16; i++) { |
1468 | if (edid[i] != 0xFF) { | 1468 | if (edid[i] != 0xFF) { |
1469 | pr_debug("edid data read succesfully"); | 1469 | pr_debug("edid data read successfully"); |
1470 | return EDID_LENGTH; | 1470 | return EDID_LENGTH; |
1471 | } | 1471 | } |
1472 | } | 1472 | } |
@@ -1972,6 +1972,6 @@ MODULE_PARM_DESC(console, "Allow fbcon to be used on this display"); | |||
1972 | module_param(fb_defio, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); | 1972 | module_param(fb_defio, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); |
1973 | MODULE_PARM_DESC(fb_defio, "Enable fb_defio mmap support"); | 1973 | MODULE_PARM_DESC(fb_defio, "Enable fb_defio mmap support"); |
1974 | 1974 | ||
1975 | MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>"); | 1975 | MODULE_AUTHOR("Steve Glendinning <steve.glendinning@shawell.net>"); |
1976 | MODULE_DESCRIPTION("SMSC UFX kernel framebuffer driver"); | 1976 | MODULE_DESCRIPTION("SMSC UFX kernel framebuffer driver"); |
1977 | MODULE_LICENSE("GPL"); | 1977 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c index b9c2b948d34d..eb931b8626fa 100644 --- a/drivers/video/sunxvr500.c +++ b/drivers/video/sunxvr500.c | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | 14 | ||
15 | /* XXX This device has a 'dev-comm' property which aparently is | 15 | /* XXX This device has a 'dev-comm' property which apparently is |
16 | * XXX a pointer into the openfirmware's address space which is | 16 | * XXX a pointer into the openfirmware's address space which is |
17 | * XXX a shared area the kernel driver can use to keep OBP | 17 | * XXX a shared area the kernel driver can use to keep OBP |
18 | * XXX informed about the current resolution setting. The idea | 18 | * XXX informed about the current resolution setting. The idea |
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 | } |