diff options
55 files changed, 2621 insertions, 1138 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-platform-sh_mobile_lcdc_fb b/Documentation/ABI/testing/sysfs-devices-platform-sh_mobile_lcdc_fb new file mode 100644 index 000000000000..2107082426da --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-platform-sh_mobile_lcdc_fb | |||
@@ -0,0 +1,44 @@ | |||
1 | What: /sys/devices/platform/sh_mobile_lcdc_fb.[0-3]/graphics/fb[0-9]/ovl_alpha | ||
2 | Date: May 2012 | ||
3 | Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
4 | Description: | ||
5 | This file is only available on fb[0-9] devices corresponding | ||
6 | to overlay planes. | ||
7 | |||
8 | Stores the alpha blending value for the overlay. Values range | ||
9 | from 0 (transparent) to 255 (opaque). The value is ignored if | ||
10 | the mode is not set to Alpha Blending. | ||
11 | |||
12 | What: /sys/devices/platform/sh_mobile_lcdc_fb.[0-3]/graphics/fb[0-9]/ovl_mode | ||
13 | Date: May 2012 | ||
14 | Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
15 | Description: | ||
16 | This file is only available on fb[0-9] devices corresponding | ||
17 | to overlay planes. | ||
18 | |||
19 | Selects the composition mode for the overlay. Possible values | ||
20 | are | ||
21 | |||
22 | 0 - Alpha Blending | ||
23 | 1 - ROP3 | ||
24 | |||
25 | What: /sys/devices/platform/sh_mobile_lcdc_fb.[0-3]/graphics/fb[0-9]/ovl_position | ||
26 | Date: May 2012 | ||
27 | Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
28 | Description: | ||
29 | This file is only available on fb[0-9] devices corresponding | ||
30 | to overlay planes. | ||
31 | |||
32 | Stores the x,y overlay position on the display in pixels. The | ||
33 | position format is `[0-9]+,[0-9]+'. | ||
34 | |||
35 | What: /sys/devices/platform/sh_mobile_lcdc_fb.[0-3]/graphics/fb[0-9]/ovl_rop3 | ||
36 | Date: May 2012 | ||
37 | Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
38 | Description: | ||
39 | This file is only available on fb[0-9] devices corresponding | ||
40 | to overlay planes. | ||
41 | |||
42 | Stores the raster operation (ROP3) for the overlay. Values | ||
43 | range from 0 to 255. The value is ignored if the mode is not | ||
44 | set to ROP3. | ||
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index d1624a315c9a..783eab6845c4 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c | |||
@@ -546,6 +546,7 @@ static struct lcd_ctrl_config lcd_cfg = { | |||
546 | .sync_edge = 0, | 546 | .sync_edge = 0, |
547 | .sync_ctrl = 1, | 547 | .sync_ctrl = 1, |
548 | .raster_order = 0, | 548 | .raster_order = 0, |
549 | .fifo_th = 6, | ||
549 | }; | 550 | }; |
550 | 551 | ||
551 | struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = { | 552 | struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = { |
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 5fb47a14f4ba..af1ed7d24a1f 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #define DISPC_CONTROL 0x0040 | 38 | #define DISPC_CONTROL 0x0040 |
39 | #define DISPC_CONTROL2 0x0238 | 39 | #define DISPC_CONTROL2 0x0238 |
40 | #define DISPC_CONTROL3 0x0848 | ||
40 | #define DISPC_IRQSTATUS 0x0018 | 41 | #define DISPC_IRQSTATUS 0x0018 |
41 | 42 | ||
42 | #define DSS_SYSCONFIG 0x10 | 43 | #define DSS_SYSCONFIG 0x10 |
@@ -52,6 +53,7 @@ | |||
52 | #define EVSYNC_EVEN_IRQ_SHIFT 2 | 53 | #define EVSYNC_EVEN_IRQ_SHIFT 2 |
53 | #define EVSYNC_ODD_IRQ_SHIFT 3 | 54 | #define EVSYNC_ODD_IRQ_SHIFT 3 |
54 | #define FRAMEDONE2_IRQ_SHIFT 22 | 55 | #define FRAMEDONE2_IRQ_SHIFT 22 |
56 | #define FRAMEDONE3_IRQ_SHIFT 30 | ||
55 | #define FRAMEDONETV_IRQ_SHIFT 24 | 57 | #define FRAMEDONETV_IRQ_SHIFT 24 |
56 | 58 | ||
57 | /* | 59 | /* |
@@ -376,7 +378,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) | |||
376 | static void dispc_disable_outputs(void) | 378 | static void dispc_disable_outputs(void) |
377 | { | 379 | { |
378 | u32 v, irq_mask = 0; | 380 | u32 v, irq_mask = 0; |
379 | bool lcd_en, digit_en, lcd2_en = false; | 381 | bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false; |
380 | int i; | 382 | int i; |
381 | struct omap_dss_dispc_dev_attr *da; | 383 | struct omap_dss_dispc_dev_attr *da; |
382 | struct omap_hwmod *oh; | 384 | struct omap_hwmod *oh; |
@@ -405,7 +407,13 @@ static void dispc_disable_outputs(void) | |||
405 | lcd2_en = v & LCD_EN_MASK; | 407 | lcd2_en = v & LCD_EN_MASK; |
406 | } | 408 | } |
407 | 409 | ||
408 | if (!(lcd_en | digit_en | lcd2_en)) | 410 | /* store value of LCDENABLE for LCD3 */ |
411 | if (da->manager_count > 3) { | ||
412 | v = omap_hwmod_read(oh, DISPC_CONTROL3); | ||
413 | lcd3_en = v & LCD_EN_MASK; | ||
414 | } | ||
415 | |||
416 | if (!(lcd_en | digit_en | lcd2_en | lcd3_en)) | ||
409 | return; /* no managers currently enabled */ | 417 | return; /* no managers currently enabled */ |
410 | 418 | ||
411 | /* | 419 | /* |
@@ -426,10 +434,12 @@ static void dispc_disable_outputs(void) | |||
426 | 434 | ||
427 | if (lcd2_en) | 435 | if (lcd2_en) |
428 | irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT; | 436 | irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT; |
437 | if (lcd3_en) | ||
438 | irq_mask |= 1 << FRAMEDONE3_IRQ_SHIFT; | ||
429 | 439 | ||
430 | /* | 440 | /* |
431 | * clear any previous FRAMEDONE, FRAMEDONETV, | 441 | * clear any previous FRAMEDONE, FRAMEDONETV, |
432 | * EVSYNC_EVEN/ODD or FRAMEDONE2 interrupts | 442 | * EVSYNC_EVEN/ODD, FRAMEDONE2 or FRAMEDONE3 interrupts |
433 | */ | 443 | */ |
434 | omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS); | 444 | omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS); |
435 | 445 | ||
@@ -445,12 +455,19 @@ static void dispc_disable_outputs(void) | |||
445 | omap_hwmod_write(v, oh, DISPC_CONTROL2); | 455 | omap_hwmod_write(v, oh, DISPC_CONTROL2); |
446 | } | 456 | } |
447 | 457 | ||
458 | /* disable LCD3 manager */ | ||
459 | if (da->manager_count > 3) { | ||
460 | v = omap_hwmod_read(oh, DISPC_CONTROL3); | ||
461 | v &= ~LCD_EN_MASK; | ||
462 | omap_hwmod_write(v, oh, DISPC_CONTROL3); | ||
463 | } | ||
464 | |||
448 | i = 0; | 465 | i = 0; |
449 | while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) != | 466 | while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) != |
450 | irq_mask) { | 467 | irq_mask) { |
451 | i++; | 468 | i++; |
452 | if (i > FRAMEDONE_IRQ_TIMEOUT) { | 469 | if (i > FRAMEDONE_IRQ_TIMEOUT) { |
453 | pr_err("didn't get FRAMEDONE1/2 or TV interrupt\n"); | 470 | pr_err("didn't get FRAMEDONE1/2/3 or TV interrupt\n"); |
454 | break; | 471 | break; |
455 | } | 472 | } |
456 | mdelay(1); | 473 | mdelay(1); |
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/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 bcb0e3ae1e9d..2db5b9aa250a 100644 --- a/drivers/video/exynos/exynos_dp_reg.c +++ b/drivers/video/exynos/exynos_dp_reg.c | |||
@@ -122,7 +122,7 @@ void exynos_dp_reset(struct exynos_dp_device *dp) | |||
122 | LS_CLK_DOMAIN_FUNC_EN_N; | 122 | LS_CLK_DOMAIN_FUNC_EN_N; |
123 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); | 123 | writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); |
124 | 124 | ||
125 | udelay(20); | 125 | usleep_range(20, 30); |
126 | 126 | ||
127 | exynos_dp_lane_swap(dp, 0); | 127 | exynos_dp_lane_swap(dp, 0); |
128 | 128 | ||
@@ -988,7 +988,7 @@ void exynos_dp_reset_macro(struct exynos_dp_device *dp) | |||
988 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); | 988 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); |
989 | 989 | ||
990 | /* 10 us is the minimum reset time. */ | 990 | /* 10 us is the minimum reset time. */ |
991 | udelay(10); | 991 | usleep_range(10, 20); |
992 | 992 | ||
993 | reg &= ~MACRO_RST; | 993 | reg &= ~MACRO_RST; |
994 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); | 994 | writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); |
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c index 9908e75ae761..4bc2b8a5dd8b 100644 --- a/drivers/video/exynos/exynos_mipi_dsi.c +++ b/drivers/video/exynos/exynos_mipi_dsi.c | |||
@@ -154,7 +154,7 @@ static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power) | |||
154 | if (client_drv && client_drv->power_on) | 154 | if (client_drv && client_drv->power_on) |
155 | client_drv->power_on(client_dev, 1); | 155 | client_drv->power_on(client_dev, 1); |
156 | 156 | ||
157 | exynos_mipi_regulator_disable(dsim); | 157 | exynos_mipi_regulator_enable(dsim); |
158 | 158 | ||
159 | /* enable MIPI-DSI PHY. */ | 159 | /* enable MIPI-DSI PHY. */ |
160 | if (dsim->pd->phy_enable) | 160 | if (dsim->pd->phy_enable) |
diff --git a/drivers/video/exynos/s6e8ax0.h b/drivers/video/exynos/s6e8ax0.h deleted file mode 100644 index 1f1b270484b0..000000000000 --- a/drivers/video/exynos/s6e8ax0.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* linux/drivers/video/backlight/s6e8ax0.h | ||
2 | * | ||
3 | * MIPI-DSI based s6e8ax0 AMOLED LCD Panel definitions. | ||
4 | * | ||
5 | * Copyright (c) 2011 Samsung Electronics | ||
6 | * | ||
7 | * Inki Dae, <inki.dae@samsung.com> | ||
8 | * Donghwa Lee <dh09.lee@samsung.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef _S6E8AX0_H | ||
16 | #define _S6E8AX0_H | ||
17 | |||
18 | extern void s6e8ax0_init(void); | ||
19 | |||
20 | #endif | ||
21 | |||
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h index 04c01faaf772..624ee115f129 100644 --- a/drivers/video/fb_draw.h +++ b/drivers/video/fb_draw.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
5 | #include <linux/fb.h> | 5 | #include <linux/fb.h> |
6 | #include <linux/bug.h> | ||
6 | 7 | ||
7 | /* | 8 | /* |
8 | * Compose two values, using a bitmask as decision value | 9 | * Compose two values, using a bitmask as decision value |
@@ -41,7 +42,8 @@ pixel_to_pat( u32 bpp, u32 pixel) | |||
41 | case 32: | 42 | case 32: |
42 | return 0x0000000100000001ul*pixel; | 43 | return 0x0000000100000001ul*pixel; |
43 | default: | 44 | default: |
44 | panic("pixel_to_pat(): unsupported pixelformat\n"); | 45 | WARN(1, "pixel_to_pat(): unsupported pixelformat %d\n", bpp); |
46 | return 0; | ||
45 | } | 47 | } |
46 | } | 48 | } |
47 | #else | 49 | #else |
@@ -66,7 +68,8 @@ pixel_to_pat( u32 bpp, u32 pixel) | |||
66 | case 32: | 68 | case 32: |
67 | return 0x00000001ul*pixel; | 69 | return 0x00000001ul*pixel; |
68 | default: | 70 | default: |
69 | panic("pixel_to_pat(): unsupported pixelformat\n"); | 71 | WARN(1, "pixel_to_pat(): unsupported pixelformat %d\n", bpp); |
72 | return 0; | ||
70 | } | 73 | } |
71 | } | 74 | } |
72 | #endif | 75 | #endif |
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c index da066c210923..5245f9a71892 100644 --- a/drivers/video/grvga.c +++ b/drivers/video/grvga.c | |||
@@ -354,7 +354,7 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
354 | */ | 354 | */ |
355 | if (fb_get_options("grvga", &options)) { | 355 | if (fb_get_options("grvga", &options)) { |
356 | retval = -ENODEV; | 356 | retval = -ENODEV; |
357 | goto err; | 357 | goto free_fb; |
358 | } | 358 | } |
359 | 359 | ||
360 | if (!options || !*options) | 360 | if (!options || !*options) |
@@ -370,7 +370,7 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
370 | if (grvga_parse_custom(this_opt, &info->var) < 0) { | 370 | if (grvga_parse_custom(this_opt, &info->var) < 0) { |
371 | dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt); | 371 | dev_err(&dev->dev, "Failed to parse custom mode (%s).\n", this_opt); |
372 | retval = -EINVAL; | 372 | retval = -EINVAL; |
373 | goto err1; | 373 | goto free_fb; |
374 | } | 374 | } |
375 | } else if (!strncmp(this_opt, "addr", 4)) | 375 | } else if (!strncmp(this_opt, "addr", 4)) |
376 | grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16); | 376 | grvga_fix_addr = simple_strtoul(this_opt + 5, NULL, 16); |
@@ -387,10 +387,11 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
387 | info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN; | 387 | info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN; |
388 | info->fix.smem_len = grvga_mem_size; | 388 | info->fix.smem_len = grvga_mem_size; |
389 | 389 | ||
390 | if (!request_mem_region(dev->resource[0].start, resource_size(&dev->resource[0]), "grlib-svgactrl regs")) { | 390 | if (!devm_request_mem_region(&dev->dev, dev->resource[0].start, |
391 | resource_size(&dev->resource[0]), "grlib-svgactrl regs")) { | ||
391 | dev_err(&dev->dev, "registers already mapped\n"); | 392 | dev_err(&dev->dev, "registers already mapped\n"); |
392 | retval = -EBUSY; | 393 | retval = -EBUSY; |
393 | goto err; | 394 | goto free_fb; |
394 | } | 395 | } |
395 | 396 | ||
396 | par->regs = of_ioremap(&dev->resource[0], 0, | 397 | par->regs = of_ioremap(&dev->resource[0], 0, |
@@ -400,14 +401,14 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
400 | if (!par->regs) { | 401 | if (!par->regs) { |
401 | dev_err(&dev->dev, "failed to map registers\n"); | 402 | dev_err(&dev->dev, "failed to map registers\n"); |
402 | retval = -ENOMEM; | 403 | retval = -ENOMEM; |
403 | goto err1; | 404 | goto free_fb; |
404 | } | 405 | } |
405 | 406 | ||
406 | retval = fb_alloc_cmap(&info->cmap, 256, 0); | 407 | retval = fb_alloc_cmap(&info->cmap, 256, 0); |
407 | if (retval < 0) { | 408 | if (retval < 0) { |
408 | dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n"); | 409 | dev_err(&dev->dev, "failed to allocate mem with fb_alloc_cmap\n"); |
409 | retval = -ENOMEM; | 410 | retval = -ENOMEM; |
410 | goto err2; | 411 | goto unmap_regs; |
411 | } | 412 | } |
412 | 413 | ||
413 | if (mode_opt) { | 414 | if (mode_opt) { |
@@ -415,7 +416,7 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
415 | grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8); | 416 | grvga_modedb, sizeof(grvga_modedb), &grvga_modedb[0], 8); |
416 | if (!retval || retval == 4) { | 417 | if (!retval || retval == 4) { |
417 | retval = -EINVAL; | 418 | retval = -EINVAL; |
418 | goto err3; | 419 | goto dealloc_cmap; |
419 | } | 420 | } |
420 | } | 421 | } |
421 | 422 | ||
@@ -427,10 +428,11 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
427 | 428 | ||
428 | physical_start = grvga_fix_addr; | 429 | physical_start = grvga_fix_addr; |
429 | 430 | ||
430 | if (!request_mem_region(physical_start, grvga_mem_size, dev->name)) { | 431 | if (!devm_request_mem_region(&dev->dev, physical_start, |
432 | grvga_mem_size, dev->name)) { | ||
431 | dev_err(&dev->dev, "failed to request memory region\n"); | 433 | dev_err(&dev->dev, "failed to request memory region\n"); |
432 | retval = -ENOMEM; | 434 | retval = -ENOMEM; |
433 | goto err3; | 435 | goto dealloc_cmap; |
434 | } | 436 | } |
435 | 437 | ||
436 | virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size); | 438 | virtual_start = (unsigned long) ioremap(physical_start, grvga_mem_size); |
@@ -438,7 +440,7 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
438 | if (!virtual_start) { | 440 | if (!virtual_start) { |
439 | dev_err(&dev->dev, "error mapping framebuffer memory\n"); | 441 | dev_err(&dev->dev, "error mapping framebuffer memory\n"); |
440 | retval = -ENOMEM; | 442 | retval = -ENOMEM; |
441 | goto err4; | 443 | goto dealloc_cmap; |
442 | } | 444 | } |
443 | } else { /* Allocate frambuffer memory */ | 445 | } else { /* Allocate frambuffer memory */ |
444 | 446 | ||
@@ -451,7 +453,7 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
451 | "unable to allocate framebuffer memory (%lu bytes)\n", | 453 | "unable to allocate framebuffer memory (%lu bytes)\n", |
452 | grvga_mem_size); | 454 | grvga_mem_size); |
453 | retval = -ENOMEM; | 455 | retval = -ENOMEM; |
454 | goto err3; | 456 | goto dealloc_cmap; |
455 | } | 457 | } |
456 | 458 | ||
457 | physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE); | 459 | physical_start = dma_map_single(&dev->dev, (void *)virtual_start, grvga_mem_size, DMA_TO_DEVICE); |
@@ -484,7 +486,7 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
484 | retval = register_framebuffer(info); | 486 | retval = register_framebuffer(info); |
485 | if (retval < 0) { | 487 | if (retval < 0) { |
486 | dev_err(&dev->dev, "failed to register framebuffer\n"); | 488 | dev_err(&dev->dev, "failed to register framebuffer\n"); |
487 | goto err4; | 489 | goto free_mem; |
488 | } | 490 | } |
489 | 491 | ||
490 | __raw_writel(physical_start, &par->regs->fb_pos); | 492 | __raw_writel(physical_start, &par->regs->fb_pos); |
@@ -493,21 +495,18 @@ static int __devinit grvga_probe(struct platform_device *dev) | |||
493 | 495 | ||
494 | return 0; | 496 | return 0; |
495 | 497 | ||
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/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/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c index ad741c3d1ae1..eaeed4340e04 100644 --- a/drivers/video/omap2/displays/panel-acx565akm.c +++ b/drivers/video/omap2/displays/panel-acx565akm.c | |||
@@ -487,6 +487,13 @@ static struct omap_video_timings acx_panel_timings = { | |||
487 | .vfp = 3, | 487 | .vfp = 3, |
488 | .vsw = 3, | 488 | .vsw = 3, |
489 | .vbp = 4, | 489 | .vbp = 4, |
490 | |||
491 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
492 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
493 | |||
494 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
495 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
496 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
490 | }; | 497 | }; |
491 | 498 | ||
492 | static int acx_panel_probe(struct omap_dss_device *dssdev) | 499 | static int acx_panel_probe(struct omap_dss_device *dssdev) |
@@ -498,8 +505,7 @@ static int acx_panel_probe(struct omap_dss_device *dssdev) | |||
498 | struct backlight_properties props; | 505 | struct backlight_properties props; |
499 | 506 | ||
500 | dev_dbg(&dssdev->dev, "%s\n", __func__); | 507 | dev_dbg(&dssdev->dev, "%s\n", __func__); |
501 | dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | 508 | |
502 | OMAP_DSS_LCD_IHS; | ||
503 | /* FIXME AC bias ? */ | 509 | /* FIXME AC bias ? */ |
504 | dssdev->panel.timings = acx_panel_timings; | 510 | dssdev->panel.timings = acx_panel_timings; |
505 | 511 | ||
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c index e42f9dc22123..bc5af2500eb9 100644 --- a/drivers/video/omap2/displays/panel-generic-dpi.c +++ b/drivers/video/omap2/displays/panel-generic-dpi.c | |||
@@ -40,12 +40,6 @@ | |||
40 | struct panel_config { | 40 | struct panel_config { |
41 | struct omap_video_timings timings; | 41 | struct omap_video_timings timings; |
42 | 42 | ||
43 | int acbi; /* ac-bias pin transitions per interrupt */ | ||
44 | /* Unit: line clocks */ | ||
45 | int acb; /* ac-bias pin frequency */ | ||
46 | |||
47 | enum omap_panel_config config; | ||
48 | |||
49 | int power_on_delay; | 43 | int power_on_delay; |
50 | int power_off_delay; | 44 | int power_off_delay; |
51 | 45 | ||
@@ -73,11 +67,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
73 | .vsw = 11, | 67 | .vsw = 11, |
74 | .vfp = 3, | 68 | .vfp = 3, |
75 | .vbp = 2, | 69 | .vbp = 2, |
70 | |||
71 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
72 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
73 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
74 | .de_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
75 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
76 | }, | 76 | }, |
77 | .acbi = 0x0, | ||
78 | .acb = 0x0, | ||
79 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
80 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO, | ||
81 | .power_on_delay = 50, | 77 | .power_on_delay = 50, |
82 | .power_off_delay = 100, | 78 | .power_off_delay = 100, |
83 | .name = "sharp_lq", | 79 | .name = "sharp_lq", |
@@ -98,11 +94,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
98 | .vsw = 1, | 94 | .vsw = 1, |
99 | .vfp = 1, | 95 | .vfp = 1, |
100 | .vbp = 1, | 96 | .vbp = 1, |
97 | |||
98 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
99 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
100 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
101 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
102 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
101 | }, | 103 | }, |
102 | .acbi = 0x0, | ||
103 | .acb = 0x28, | ||
104 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
105 | OMAP_DSS_LCD_IHS, | ||
106 | .power_on_delay = 50, | 104 | .power_on_delay = 50, |
107 | .power_off_delay = 100, | 105 | .power_off_delay = 100, |
108 | .name = "sharp_ls", | 106 | .name = "sharp_ls", |
@@ -123,12 +121,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
123 | .vfp = 4, | 121 | .vfp = 4, |
124 | .vsw = 2, | 122 | .vsw = 2, |
125 | .vbp = 2, | 123 | .vbp = 2, |
124 | |||
125 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
126 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
127 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
128 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
129 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
126 | }, | 130 | }, |
127 | .acbi = 0x0, | ||
128 | .acb = 0x0, | ||
129 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
130 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC | | ||
131 | OMAP_DSS_LCD_ONOFF, | ||
132 | .power_on_delay = 0, | 131 | .power_on_delay = 0, |
133 | .power_off_delay = 0, | 132 | .power_off_delay = 0, |
134 | .name = "toppoly_tdo35s", | 133 | .name = "toppoly_tdo35s", |
@@ -149,11 +148,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
149 | .vfp = 4, | 148 | .vfp = 4, |
150 | .vsw = 10, | 149 | .vsw = 10, |
151 | .vbp = 12 - 10, | 150 | .vbp = 12 - 10, |
151 | |||
152 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
153 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
154 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
155 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
156 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
152 | }, | 157 | }, |
153 | .acbi = 0x0, | ||
154 | .acb = 0x0, | ||
155 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
156 | OMAP_DSS_LCD_IHS, | ||
157 | .power_on_delay = 0, | 158 | .power_on_delay = 0, |
158 | .power_off_delay = 0, | 159 | .power_off_delay = 0, |
159 | .name = "samsung_lte430wq_f0c", | 160 | .name = "samsung_lte430wq_f0c", |
@@ -174,11 +175,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
174 | .vsw = 2, | 175 | .vsw = 2, |
175 | .vfp = 4, | 176 | .vfp = 4, |
176 | .vbp = 11, | 177 | .vbp = 11, |
178 | |||
179 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
180 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
181 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
182 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
183 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
177 | }, | 184 | }, |
178 | .acbi = 0x0, | ||
179 | .acb = 0x0, | ||
180 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
181 | OMAP_DSS_LCD_IHS, | ||
182 | .power_on_delay = 0, | 185 | .power_on_delay = 0, |
183 | .power_off_delay = 0, | 186 | .power_off_delay = 0, |
184 | .name = "seiko_70wvw1tz3", | 187 | .name = "seiko_70wvw1tz3", |
@@ -199,11 +202,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
199 | .vsw = 10, | 202 | .vsw = 10, |
200 | .vfp = 2, | 203 | .vfp = 2, |
201 | .vbp = 2, | 204 | .vbp = 2, |
205 | |||
206 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
207 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
208 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
209 | .de_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
210 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
202 | }, | 211 | }, |
203 | .acbi = 0x0, | ||
204 | .acb = 0x0, | ||
205 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
206 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO, | ||
207 | .power_on_delay = 0, | 212 | .power_on_delay = 0, |
208 | .power_off_delay = 0, | 213 | .power_off_delay = 0, |
209 | .name = "powertip_ph480272t", | 214 | .name = "powertip_ph480272t", |
@@ -224,11 +229,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
224 | .vsw = 3, | 229 | .vsw = 3, |
225 | .vfp = 12, | 230 | .vfp = 12, |
226 | .vbp = 25, | 231 | .vbp = 25, |
232 | |||
233 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
234 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
235 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
236 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
237 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
227 | }, | 238 | }, |
228 | .acbi = 0x0, | ||
229 | .acb = 0x28, | ||
230 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
231 | OMAP_DSS_LCD_IHS, | ||
232 | .power_on_delay = 0, | 239 | .power_on_delay = 0, |
233 | .power_off_delay = 0, | 240 | .power_off_delay = 0, |
234 | .name = "innolux_at070tn83", | 241 | .name = "innolux_at070tn83", |
@@ -249,9 +256,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
249 | .vsw = 1, | 256 | .vsw = 1, |
250 | .vfp = 2, | 257 | .vfp = 2, |
251 | .vbp = 7, | 258 | .vbp = 7, |
259 | |||
260 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
261 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
262 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
263 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
264 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
252 | }, | 265 | }, |
253 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
254 | OMAP_DSS_LCD_IHS, | ||
255 | .name = "nec_nl2432dr22-11b", | 266 | .name = "nec_nl2432dr22-11b", |
256 | }, | 267 | }, |
257 | 268 | ||
@@ -270,9 +281,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
270 | .vsw = 1, | 281 | .vsw = 1, |
271 | .vfp = 1, | 282 | .vfp = 1, |
272 | .vbp = 1, | 283 | .vbp = 1, |
273 | }, | ||
274 | .config = OMAP_DSS_LCD_TFT, | ||
275 | 284 | ||
285 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
286 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
287 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
288 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
289 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
290 | }, | ||
276 | .name = "h4", | 291 | .name = "h4", |
277 | }, | 292 | }, |
278 | 293 | ||
@@ -291,10 +306,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
291 | .vsw = 10, | 306 | .vsw = 10, |
292 | .vfp = 2, | 307 | .vfp = 2, |
293 | .vbp = 2, | 308 | .vbp = 2, |
294 | }, | ||
295 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
296 | OMAP_DSS_LCD_IHS, | ||
297 | 309 | ||
310 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
311 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
312 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
313 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
314 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
315 | }, | ||
298 | .name = "apollon", | 316 | .name = "apollon", |
299 | }, | 317 | }, |
300 | /* FocalTech ETM070003DH6 */ | 318 | /* FocalTech ETM070003DH6 */ |
@@ -312,9 +330,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
312 | .vsw = 3, | 330 | .vsw = 3, |
313 | .vfp = 13, | 331 | .vfp = 13, |
314 | .vbp = 29, | 332 | .vbp = 29, |
333 | |||
334 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
335 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
336 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
337 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
338 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
315 | }, | 339 | }, |
316 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
317 | OMAP_DSS_LCD_IHS, | ||
318 | .name = "focaltech_etm070003dh6", | 340 | .name = "focaltech_etm070003dh6", |
319 | }, | 341 | }, |
320 | 342 | ||
@@ -333,11 +355,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
333 | .vsw = 23, | 355 | .vsw = 23, |
334 | .vfp = 1, | 356 | .vfp = 1, |
335 | .vbp = 1, | 357 | .vbp = 1, |
358 | |||
359 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
360 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
361 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
362 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
363 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
336 | }, | 364 | }, |
337 | .acbi = 0x0, | ||
338 | .acb = 0x0, | ||
339 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
340 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, | ||
341 | .power_on_delay = 0, | 365 | .power_on_delay = 0, |
342 | .power_off_delay = 0, | 366 | .power_off_delay = 0, |
343 | .name = "microtips_umsh_8173md", | 367 | .name = "microtips_umsh_8173md", |
@@ -358,9 +382,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
358 | .vsw = 10, | 382 | .vsw = 10, |
359 | .vfp = 4, | 383 | .vfp = 4, |
360 | .vbp = 2, | 384 | .vbp = 2, |
361 | }, | ||
362 | .config = OMAP_DSS_LCD_TFT, | ||
363 | 385 | ||
386 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
387 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
388 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
389 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
390 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
391 | }, | ||
364 | .name = "ortustech_com43h4m10xtc", | 392 | .name = "ortustech_com43h4m10xtc", |
365 | }, | 393 | }, |
366 | 394 | ||
@@ -379,11 +407,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
379 | .vsw = 10, | 407 | .vsw = 10, |
380 | .vfp = 12, | 408 | .vfp = 12, |
381 | .vbp = 23, | 409 | .vbp = 23, |
382 | }, | ||
383 | .acb = 0x0, | ||
384 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
385 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO, | ||
386 | 410 | ||
411 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
412 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
413 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
414 | .de_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
415 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
416 | }, | ||
387 | .name = "innolux_at080tn52", | 417 | .name = "innolux_at080tn52", |
388 | }, | 418 | }, |
389 | 419 | ||
@@ -401,8 +431,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
401 | .vsw = 1, | 431 | .vsw = 1, |
402 | .vfp = 26, | 432 | .vfp = 26, |
403 | .vbp = 1, | 433 | .vbp = 1, |
434 | |||
435 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
436 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
437 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
438 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
439 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
404 | }, | 440 | }, |
405 | .config = OMAP_DSS_LCD_TFT, | ||
406 | .name = "mitsubishi_aa084sb01", | 441 | .name = "mitsubishi_aa084sb01", |
407 | }, | 442 | }, |
408 | /* EDT ET0500G0DH6 */ | 443 | /* EDT ET0500G0DH6 */ |
@@ -419,8 +454,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
419 | .vsw = 2, | 454 | .vsw = 2, |
420 | .vfp = 35, | 455 | .vfp = 35, |
421 | .vbp = 10, | 456 | .vbp = 10, |
457 | |||
458 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
459 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
460 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
461 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
462 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
422 | }, | 463 | }, |
423 | .config = OMAP_DSS_LCD_TFT, | ||
424 | .name = "edt_et0500g0dh6", | 464 | .name = "edt_et0500g0dh6", |
425 | }, | 465 | }, |
426 | 466 | ||
@@ -439,9 +479,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
439 | .vsw = 2, | 479 | .vsw = 2, |
440 | .vfp = 10, | 480 | .vfp = 10, |
441 | .vbp = 33, | 481 | .vbp = 33, |
482 | |||
483 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
484 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
485 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
486 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
487 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
442 | }, | 488 | }, |
443 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
444 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, | ||
445 | .name = "primeview_pd050vl1", | 489 | .name = "primeview_pd050vl1", |
446 | }, | 490 | }, |
447 | 491 | ||
@@ -460,9 +504,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
460 | .vsw = 2, | 504 | .vsw = 2, |
461 | .vfp = 10, | 505 | .vfp = 10, |
462 | .vbp = 33, | 506 | .vbp = 33, |
507 | |||
508 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
509 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
510 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
511 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
512 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
463 | }, | 513 | }, |
464 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
465 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, | ||
466 | .name = "primeview_pm070wl4", | 514 | .name = "primeview_pm070wl4", |
467 | }, | 515 | }, |
468 | 516 | ||
@@ -481,9 +529,13 @@ static struct panel_config generic_dpi_panels[] = { | |||
481 | .vsw = 4, | 529 | .vsw = 4, |
482 | .vfp = 1, | 530 | .vfp = 1, |
483 | .vbp = 23, | 531 | .vbp = 23, |
532 | |||
533 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
534 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
535 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
536 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
537 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
484 | }, | 538 | }, |
485 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
486 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC, | ||
487 | .name = "primeview_pd104slf", | 539 | .name = "primeview_pd104slf", |
488 | }, | 540 | }, |
489 | }; | 541 | }; |
@@ -573,10 +625,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev) | |||
573 | if (!panel_config) | 625 | if (!panel_config) |
574 | return -EINVAL; | 626 | return -EINVAL; |
575 | 627 | ||
576 | dssdev->panel.config = panel_config->config; | ||
577 | dssdev->panel.timings = panel_config->timings; | 628 | dssdev->panel.timings = panel_config->timings; |
578 | dssdev->panel.acb = panel_config->acb; | ||
579 | dssdev->panel.acbi = panel_config->acbi; | ||
580 | 629 | ||
581 | drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); | 630 | drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); |
582 | if (!drv_data) | 631 | if (!drv_data) |
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c index 0841cc2b3f77..802807798846 100644 --- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c | |||
@@ -40,6 +40,12 @@ static struct omap_video_timings lb035q02_timings = { | |||
40 | .vsw = 2, | 40 | .vsw = 2, |
41 | .vfp = 4, | 41 | .vfp = 4, |
42 | .vbp = 18, | 42 | .vbp = 18, |
43 | |||
44 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
45 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
46 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
47 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
48 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
43 | }; | 49 | }; |
44 | 50 | ||
45 | static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) | 51 | static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) |
@@ -82,8 +88,6 @@ static int lb035q02_panel_probe(struct omap_dss_device *dssdev) | |||
82 | struct lb035q02_data *ld; | 88 | struct lb035q02_data *ld; |
83 | int r; | 89 | int r; |
84 | 90 | ||
85 | dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
86 | OMAP_DSS_LCD_IHS; | ||
87 | dssdev->panel.timings = lb035q02_timings; | 91 | dssdev->panel.timings = lb035q02_timings; |
88 | 92 | ||
89 | ld = kzalloc(sizeof(*ld), GFP_KERNEL); | 93 | ld = kzalloc(sizeof(*ld), GFP_KERNEL); |
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c index 4a34cdc1371b..e6c115373c00 100644 --- a/drivers/video/omap2/displays/panel-n8x0.c +++ b/drivers/video/omap2/displays/panel-n8x0.c | |||
@@ -473,7 +473,6 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev) | |||
473 | 473 | ||
474 | mutex_init(&ddata->lock); | 474 | mutex_init(&ddata->lock); |
475 | 475 | ||
476 | dssdev->panel.config = OMAP_DSS_LCD_TFT; | ||
477 | dssdev->panel.timings.x_res = 800; | 476 | dssdev->panel.timings.x_res = 800; |
478 | dssdev->panel.timings.y_res = 480; | 477 | dssdev->panel.timings.y_res = 480; |
479 | dssdev->ctrl.pixel_size = 16; | 478 | dssdev->ctrl.pixel_size = 16; |
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c index 8b38b39213f4..b122b0f31c43 100644 --- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c +++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c | |||
@@ -76,6 +76,12 @@ static struct omap_video_timings nec_8048_panel_timings = { | |||
76 | .vfp = 3, | 76 | .vfp = 3, |
77 | .vsw = 1, | 77 | .vsw = 1, |
78 | .vbp = 4, | 78 | .vbp = 4, |
79 | |||
80 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
81 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
82 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
83 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
84 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
79 | }; | 85 | }; |
80 | 86 | ||
81 | static int nec_8048_bl_update_status(struct backlight_device *bl) | 87 | static int nec_8048_bl_update_status(struct backlight_device *bl) |
@@ -116,9 +122,6 @@ static int nec_8048_panel_probe(struct omap_dss_device *dssdev) | |||
116 | struct backlight_properties props; | 122 | struct backlight_properties props; |
117 | int r; | 123 | int r; |
118 | 124 | ||
119 | dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
120 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_RF | | ||
121 | OMAP_DSS_LCD_ONOFF; | ||
122 | dssdev->panel.timings = nec_8048_panel_timings; | 125 | dssdev->panel.timings = nec_8048_panel_timings; |
123 | 126 | ||
124 | necd = kzalloc(sizeof(*necd), GFP_KERNEL); | 127 | necd = kzalloc(sizeof(*necd), GFP_KERNEL); |
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c index 98ebdaddab5a..2d35bd388860 100644 --- a/drivers/video/omap2/displays/panel-picodlp.c +++ b/drivers/video/omap2/displays/panel-picodlp.c | |||
@@ -69,6 +69,12 @@ static struct omap_video_timings pico_ls_timings = { | |||
69 | .vsw = 2, | 69 | .vsw = 2, |
70 | .vfp = 3, | 70 | .vfp = 3, |
71 | .vbp = 14, | 71 | .vbp = 14, |
72 | |||
73 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
74 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
75 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
76 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
77 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
72 | }; | 78 | }; |
73 | 79 | ||
74 | static inline struct picodlp_panel_data | 80 | static inline struct picodlp_panel_data |
@@ -414,9 +420,6 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev) | |||
414 | struct i2c_client *picodlp_i2c_client; | 420 | struct i2c_client *picodlp_i2c_client; |
415 | int r = 0, picodlp_adapter_id; | 421 | int r = 0, picodlp_adapter_id; |
416 | 422 | ||
417 | dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF | | ||
418 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS; | ||
419 | dssdev->panel.acb = 0x0; | ||
420 | dssdev->panel.timings = pico_ls_timings; | 423 | dssdev->panel.timings = pico_ls_timings; |
421 | 424 | ||
422 | picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL); | 425 | picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL); |
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c index ba38b3ad17d6..bd86ba9ccf76 100644 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c | |||
@@ -44,6 +44,12 @@ static struct omap_video_timings sharp_ls_timings = { | |||
44 | .vsw = 1, | 44 | .vsw = 1, |
45 | .vfp = 1, | 45 | .vfp = 1, |
46 | .vbp = 1, | 46 | .vbp = 1, |
47 | |||
48 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
49 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
50 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
51 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
52 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
47 | }; | 53 | }; |
48 | 54 | ||
49 | static int sharp_ls_bl_update_status(struct backlight_device *bl) | 55 | static int sharp_ls_bl_update_status(struct backlight_device *bl) |
@@ -86,9 +92,6 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) | |||
86 | struct sharp_data *sd; | 92 | struct sharp_data *sd; |
87 | int r; | 93 | int r; |
88 | 94 | ||
89 | dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
90 | OMAP_DSS_LCD_IHS; | ||
91 | dssdev->panel.acb = 0x28; | ||
92 | dssdev->panel.timings = sharp_ls_timings; | 95 | dssdev->panel.timings = sharp_ls_timings; |
93 | 96 | ||
94 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); | 97 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); |
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 901576eb5a84..3f5acc7771da 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c | |||
@@ -882,7 +882,6 @@ static int taal_probe(struct omap_dss_device *dssdev) | |||
882 | goto err; | 882 | goto err; |
883 | } | 883 | } |
884 | 884 | ||
885 | dssdev->panel.config = OMAP_DSS_LCD_TFT; | ||
886 | dssdev->panel.timings = panel_config->timings; | 885 | dssdev->panel.timings = panel_config->timings; |
887 | dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; | 886 | dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; |
888 | 887 | ||
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c index bff306e041ca..40cc0cfa5d17 100644 --- a/drivers/video/omap2/displays/panel-tfp410.c +++ b/drivers/video/omap2/displays/panel-tfp410.c | |||
@@ -39,6 +39,12 @@ static const struct omap_video_timings tfp410_default_timings = { | |||
39 | .vfp = 3, | 39 | .vfp = 3, |
40 | .vsw = 4, | 40 | .vsw = 4, |
41 | .vbp = 7, | 41 | .vbp = 7, |
42 | |||
43 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
44 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
45 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
46 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
47 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
42 | }; | 48 | }; |
43 | 49 | ||
44 | struct panel_drv_data { | 50 | struct panel_drv_data { |
@@ -95,7 +101,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev) | |||
95 | return -ENOMEM; | 101 | return -ENOMEM; |
96 | 102 | ||
97 | dssdev->panel.timings = tfp410_default_timings; | 103 | dssdev->panel.timings = tfp410_default_timings; |
98 | dssdev->panel.config = OMAP_DSS_LCD_TFT; | ||
99 | 104 | ||
100 | ddata->dssdev = dssdev; | 105 | ddata->dssdev = dssdev; |
101 | mutex_init(&ddata->lock); | 106 | mutex_init(&ddata->lock); |
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index 4b6448b3c31f..fa7baa650ae0 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c | |||
@@ -267,6 +267,12 @@ static const struct omap_video_timings tpo_td043_timings = { | |||
267 | .vsw = 1, | 267 | .vsw = 1, |
268 | .vfp = 39, | 268 | .vfp = 39, |
269 | .vbp = 34, | 269 | .vbp = 34, |
270 | |||
271 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
272 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
273 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
274 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
275 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
270 | }; | 276 | }; |
271 | 277 | ||
272 | static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) | 278 | static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) |
@@ -423,8 +429,6 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev) | |||
423 | return -ENODEV; | 429 | return -ENODEV; |
424 | } | 430 | } |
425 | 431 | ||
426 | dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS | | ||
427 | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC; | ||
428 | dssdev->panel.timings = tpo_td043_timings; | 432 | dssdev->panel.timings = tpo_td043_timings; |
429 | dssdev->ctrl.pixel_size = 24; | 433 | dssdev->ctrl.pixel_size = 24; |
430 | 434 | ||
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index 43324e5ed25f..b337a8469fd8 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig | |||
@@ -52,7 +52,7 @@ config OMAP2_DSS_RFBI | |||
52 | DBI is a bus between the host processor and a peripheral, | 52 | DBI is a bus between the host processor and a peripheral, |
53 | such as a display or a framebuffer chip. | 53 | such as a display or a framebuffer chip. |
54 | 54 | ||
55 | See http://www.mipi.org/ for DBI spesifications. | 55 | See http://www.mipi.org/ for DBI specifications. |
56 | 56 | ||
57 | config OMAP2_DSS_VENC | 57 | config OMAP2_DSS_VENC |
58 | bool "VENC support" | 58 | bool "VENC support" |
@@ -92,7 +92,7 @@ config OMAP2_DSS_DSI | |||
92 | DSI is a high speed half-duplex serial interface between the host | 92 | DSI is a high speed half-duplex serial interface between the host |
93 | processor and a peripheral, such as a display or a framebuffer chip. | 93 | processor and a peripheral, such as a display or a framebuffer chip. |
94 | 94 | ||
95 | See http://www.mipi.org/ for DSI spesifications. | 95 | See http://www.mipi.org/ for DSI specifications. |
96 | 96 | ||
97 | config OMAP2_DSS_MIN_FCK_PER_PCK | 97 | config OMAP2_DSS_MIN_FCK_PER_PCK |
98 | int "Minimum FCK/PCK ratio (for scaling)" | 98 | int "Minimum FCK/PCK ratio (for scaling)" |
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index ab22cc224f3e..0fefc68372b9 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
@@ -104,6 +104,7 @@ struct mgr_priv_data { | |||
104 | bool shadow_extra_info_dirty; | 104 | bool shadow_extra_info_dirty; |
105 | 105 | ||
106 | struct omap_video_timings timings; | 106 | struct omap_video_timings timings; |
107 | struct dss_lcd_mgr_config lcd_config; | ||
107 | }; | 108 | }; |
108 | 109 | ||
109 | static struct { | 110 | static struct { |
@@ -137,6 +138,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr) | |||
137 | void dss_apply_init(void) | 138 | void dss_apply_init(void) |
138 | { | 139 | { |
139 | const int num_ovls = dss_feat_get_num_ovls(); | 140 | const int num_ovls = dss_feat_get_num_ovls(); |
141 | struct mgr_priv_data *mp; | ||
140 | int i; | 142 | int i; |
141 | 143 | ||
142 | spin_lock_init(&data_lock); | 144 | spin_lock_init(&data_lock); |
@@ -168,16 +170,35 @@ void dss_apply_init(void) | |||
168 | 170 | ||
169 | op->user_info = op->info; | 171 | op->user_info = op->info; |
170 | } | 172 | } |
173 | |||
174 | /* | ||
175 | * Initialize some of the lcd_config fields for TV manager, this lets | ||
176 | * us prevent checking if the manager is LCD or TV at some places | ||
177 | */ | ||
178 | mp = &dss_data.mgr_priv_data_array[OMAP_DSS_CHANNEL_DIGIT]; | ||
179 | |||
180 | mp->lcd_config.video_port_width = 24; | ||
181 | mp->lcd_config.clock_info.lck_div = 1; | ||
182 | mp->lcd_config.clock_info.pck_div = 1; | ||
171 | } | 183 | } |
172 | 184 | ||
185 | /* | ||
186 | * A LCD manager's stallmode decides whether it is in manual or auto update. TV | ||
187 | * manager is always auto update, stallmode field for TV manager is false by | ||
188 | * default | ||
189 | */ | ||
173 | static bool ovl_manual_update(struct omap_overlay *ovl) | 190 | static bool ovl_manual_update(struct omap_overlay *ovl) |
174 | { | 191 | { |
175 | return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; | 192 | struct mgr_priv_data *mp = get_mgr_priv(ovl->manager); |
193 | |||
194 | return mp->lcd_config.stallmode; | ||
176 | } | 195 | } |
177 | 196 | ||
178 | static bool mgr_manual_update(struct omap_overlay_manager *mgr) | 197 | static bool mgr_manual_update(struct omap_overlay_manager *mgr) |
179 | { | 198 | { |
180 | return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; | 199 | struct mgr_priv_data *mp = get_mgr_priv(mgr); |
200 | |||
201 | return mp->lcd_config.stallmode; | ||
181 | } | 202 | } |
182 | 203 | ||
183 | static int dss_check_settings_low(struct omap_overlay_manager *mgr, | 204 | static int dss_check_settings_low(struct omap_overlay_manager *mgr, |
@@ -214,7 +235,7 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr, | |||
214 | ois[ovl->id] = oi; | 235 | ois[ovl->id] = oi; |
215 | } | 236 | } |
216 | 237 | ||
217 | return dss_mgr_check(mgr, mi, &mp->timings, ois); | 238 | return dss_mgr_check(mgr, mi, &mp->timings, &mp->lcd_config, ois); |
218 | } | 239 | } |
219 | 240 | ||
220 | /* | 241 | /* |
@@ -537,7 +558,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) | |||
537 | { | 558 | { |
538 | struct ovl_priv_data *op = get_ovl_priv(ovl); | 559 | struct ovl_priv_data *op = get_ovl_priv(ovl); |
539 | struct omap_overlay_info *oi; | 560 | struct omap_overlay_info *oi; |
540 | bool ilace, replication; | 561 | bool replication; |
541 | struct mgr_priv_data *mp; | 562 | struct mgr_priv_data *mp; |
542 | int r; | 563 | int r; |
543 | 564 | ||
@@ -550,11 +571,9 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) | |||
550 | 571 | ||
551 | mp = get_mgr_priv(ovl->manager); | 572 | mp = get_mgr_priv(ovl->manager); |
552 | 573 | ||
553 | replication = dss_use_replication(ovl->manager->device, oi->color_mode); | 574 | replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode); |
554 | |||
555 | ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; | ||
556 | 575 | ||
557 | r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings); | 576 | r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings); |
558 | if (r) { | 577 | if (r) { |
559 | /* | 578 | /* |
560 | * We can't do much here, as this function can be called from | 579 | * We can't do much here, as this function can be called from |
@@ -635,6 +654,24 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr) | |||
635 | 654 | ||
636 | dispc_mgr_set_timings(mgr->id, &mp->timings); | 655 | dispc_mgr_set_timings(mgr->id, &mp->timings); |
637 | 656 | ||
657 | /* lcd_config parameters */ | ||
658 | if (dss_mgr_is_lcd(mgr->id)) { | ||
659 | dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode); | ||
660 | |||
661 | dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode); | ||
662 | dispc_mgr_enable_fifohandcheck(mgr->id, | ||
663 | mp->lcd_config.fifohandcheck); | ||
664 | |||
665 | dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info); | ||
666 | |||
667 | dispc_mgr_set_tft_data_lines(mgr->id, | ||
668 | mp->lcd_config.video_port_width); | ||
669 | |||
670 | dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity); | ||
671 | |||
672 | dispc_mgr_set_lcd_type_tft(mgr->id); | ||
673 | } | ||
674 | |||
638 | mp->extra_info_dirty = false; | 675 | mp->extra_info_dirty = false; |
639 | if (mp->updating) | 676 | if (mp->updating) |
640 | mp->shadow_extra_info_dirty = true; | 677 | mp->shadow_extra_info_dirty = true; |
@@ -1294,6 +1331,44 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr, | |||
1294 | mutex_unlock(&apply_lock); | 1331 | mutex_unlock(&apply_lock); |
1295 | } | 1332 | } |
1296 | 1333 | ||
1334 | static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr, | ||
1335 | const struct dss_lcd_mgr_config *config) | ||
1336 | { | ||
1337 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | ||
1338 | |||
1339 | mp->lcd_config = *config; | ||
1340 | mp->extra_info_dirty = true; | ||
1341 | } | ||
1342 | |||
1343 | void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, | ||
1344 | const struct dss_lcd_mgr_config *config) | ||
1345 | { | ||
1346 | unsigned long flags; | ||
1347 | struct mgr_priv_data *mp = get_mgr_priv(mgr); | ||
1348 | |||
1349 | mutex_lock(&apply_lock); | ||
1350 | |||
1351 | if (mp->enabled) { | ||
1352 | DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n", | ||
1353 | mgr->name); | ||
1354 | goto out; | ||
1355 | } | ||
1356 | |||
1357 | spin_lock_irqsave(&data_lock, flags); | ||
1358 | |||
1359 | dss_apply_mgr_lcd_config(mgr, config); | ||
1360 | |||
1361 | dss_write_regs(); | ||
1362 | dss_set_go_bits(); | ||
1363 | |||
1364 | spin_unlock_irqrestore(&data_lock, flags); | ||
1365 | |||
1366 | wait_pending_extra_info_updates(); | ||
1367 | |||
1368 | out: | ||
1369 | mutex_unlock(&apply_lock); | ||
1370 | } | ||
1371 | |||
1297 | int dss_ovl_set_info(struct omap_overlay *ovl, | 1372 | int dss_ovl_set_info(struct omap_overlay *ovl, |
1298 | struct omap_overlay_info *info) | 1373 | struct omap_overlay_info *info) |
1299 | { | 1374 | { |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 397d4eee11bb..5b289c5f695b 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -119,6 +119,97 @@ enum omap_color_component { | |||
119 | DISPC_COLOR_COMPONENT_UV = 1 << 1, | 119 | DISPC_COLOR_COMPONENT_UV = 1 << 1, |
120 | }; | 120 | }; |
121 | 121 | ||
122 | enum mgr_reg_fields { | ||
123 | DISPC_MGR_FLD_ENABLE, | ||
124 | DISPC_MGR_FLD_STNTFT, | ||
125 | DISPC_MGR_FLD_GO, | ||
126 | DISPC_MGR_FLD_TFTDATALINES, | ||
127 | DISPC_MGR_FLD_STALLMODE, | ||
128 | DISPC_MGR_FLD_TCKENABLE, | ||
129 | DISPC_MGR_FLD_TCKSELECTION, | ||
130 | DISPC_MGR_FLD_CPR, | ||
131 | DISPC_MGR_FLD_FIFOHANDCHECK, | ||
132 | /* used to maintain a count of the above fields */ | ||
133 | DISPC_MGR_FLD_NUM, | ||
134 | }; | ||
135 | |||
136 | static const struct { | ||
137 | const char *name; | ||
138 | u32 vsync_irq; | ||
139 | u32 framedone_irq; | ||
140 | u32 sync_lost_irq; | ||
141 | struct reg_field reg_desc[DISPC_MGR_FLD_NUM]; | ||
142 | } mgr_desc[] = { | ||
143 | [OMAP_DSS_CHANNEL_LCD] = { | ||
144 | .name = "LCD", | ||
145 | .vsync_irq = DISPC_IRQ_VSYNC, | ||
146 | .framedone_irq = DISPC_IRQ_FRAMEDONE, | ||
147 | .sync_lost_irq = DISPC_IRQ_SYNC_LOST, | ||
148 | .reg_desc = { | ||
149 | [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 0, 0 }, | ||
150 | [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL, 3, 3 }, | ||
151 | [DISPC_MGR_FLD_GO] = { DISPC_CONTROL, 5, 5 }, | ||
152 | [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL, 9, 8 }, | ||
153 | [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL, 11, 11 }, | ||
154 | [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG, 10, 10 }, | ||
155 | [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG, 11, 11 }, | ||
156 | [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG, 15, 15 }, | ||
157 | [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG, 16, 16 }, | ||
158 | }, | ||
159 | }, | ||
160 | [OMAP_DSS_CHANNEL_DIGIT] = { | ||
161 | .name = "DIGIT", | ||
162 | .vsync_irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN, | ||
163 | .framedone_irq = 0, | ||
164 | .sync_lost_irq = DISPC_IRQ_SYNC_LOST_DIGIT, | ||
165 | .reg_desc = { | ||
166 | [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL, 1, 1 }, | ||
167 | [DISPC_MGR_FLD_STNTFT] = { }, | ||
168 | [DISPC_MGR_FLD_GO] = { DISPC_CONTROL, 6, 6 }, | ||
169 | [DISPC_MGR_FLD_TFTDATALINES] = { }, | ||
170 | [DISPC_MGR_FLD_STALLMODE] = { }, | ||
171 | [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG, 12, 12 }, | ||
172 | [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG, 13, 13 }, | ||
173 | [DISPC_MGR_FLD_CPR] = { }, | ||
174 | [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG, 16, 16 }, | ||
175 | }, | ||
176 | }, | ||
177 | [OMAP_DSS_CHANNEL_LCD2] = { | ||
178 | .name = "LCD2", | ||
179 | .vsync_irq = DISPC_IRQ_VSYNC2, | ||
180 | .framedone_irq = DISPC_IRQ_FRAMEDONE2, | ||
181 | .sync_lost_irq = DISPC_IRQ_SYNC_LOST2, | ||
182 | .reg_desc = { | ||
183 | [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL2, 0, 0 }, | ||
184 | [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL2, 3, 3 }, | ||
185 | [DISPC_MGR_FLD_GO] = { DISPC_CONTROL2, 5, 5 }, | ||
186 | [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL2, 9, 8 }, | ||
187 | [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL2, 11, 11 }, | ||
188 | [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG2, 10, 10 }, | ||
189 | [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG2, 11, 11 }, | ||
190 | [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG2, 15, 15 }, | ||
191 | [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG2, 16, 16 }, | ||
192 | }, | ||
193 | }, | ||
194 | [OMAP_DSS_CHANNEL_LCD3] = { | ||
195 | .name = "LCD3", | ||
196 | .vsync_irq = DISPC_IRQ_VSYNC3, | ||
197 | .framedone_irq = DISPC_IRQ_FRAMEDONE3, | ||
198 | .sync_lost_irq = DISPC_IRQ_SYNC_LOST3, | ||
199 | .reg_desc = { | ||
200 | [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL3, 0, 0 }, | ||
201 | [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL3, 3, 3 }, | ||
202 | [DISPC_MGR_FLD_GO] = { DISPC_CONTROL3, 5, 5 }, | ||
203 | [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL3, 9, 8 }, | ||
204 | [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL3, 11, 11 }, | ||
205 | [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG3, 10, 10 }, | ||
206 | [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG3, 11, 11 }, | ||
207 | [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG3, 15, 15 }, | ||
208 | [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG3, 16, 16 }, | ||
209 | }, | ||
210 | }, | ||
211 | }; | ||
212 | |||
122 | static void _omap_dispc_set_irqs(void); | 213 | static void _omap_dispc_set_irqs(void); |
123 | 214 | ||
124 | static inline void dispc_write_reg(const u16 idx, u32 val) | 215 | static inline void dispc_write_reg(const u16 idx, u32 val) |
@@ -131,6 +222,18 @@ static inline u32 dispc_read_reg(const u16 idx) | |||
131 | return __raw_readl(dispc.base + idx); | 222 | return __raw_readl(dispc.base + idx); |
132 | } | 223 | } |
133 | 224 | ||
225 | static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld) | ||
226 | { | ||
227 | const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld]; | ||
228 | return REG_GET(rfld.reg, rfld.high, rfld.low); | ||
229 | } | ||
230 | |||
231 | static void mgr_fld_write(enum omap_channel channel, | ||
232 | enum mgr_reg_fields regfld, int val) { | ||
233 | const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld]; | ||
234 | REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low); | ||
235 | } | ||
236 | |||
134 | #define SR(reg) \ | 237 | #define SR(reg) \ |
135 | dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) | 238 | dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) |
136 | #define RR(reg) \ | 239 | #define RR(reg) \ |
@@ -153,6 +256,10 @@ static void dispc_save_context(void) | |||
153 | SR(CONTROL2); | 256 | SR(CONTROL2); |
154 | SR(CONFIG2); | 257 | SR(CONFIG2); |
155 | } | 258 | } |
259 | if (dss_has_feature(FEAT_MGR_LCD3)) { | ||
260 | SR(CONTROL3); | ||
261 | SR(CONFIG3); | ||
262 | } | ||
156 | 263 | ||
157 | for (i = 0; i < dss_feat_get_num_mgrs(); i++) { | 264 | for (i = 0; i < dss_feat_get_num_mgrs(); i++) { |
158 | SR(DEFAULT_COLOR(i)); | 265 | SR(DEFAULT_COLOR(i)); |
@@ -266,6 +373,8 @@ static void dispc_restore_context(void) | |||
266 | RR(GLOBAL_ALPHA); | 373 | RR(GLOBAL_ALPHA); |
267 | if (dss_has_feature(FEAT_MGR_LCD2)) | 374 | if (dss_has_feature(FEAT_MGR_LCD2)) |
268 | RR(CONFIG2); | 375 | RR(CONFIG2); |
376 | if (dss_has_feature(FEAT_MGR_LCD3)) | ||
377 | RR(CONFIG3); | ||
269 | 378 | ||
270 | for (i = 0; i < dss_feat_get_num_mgrs(); i++) { | 379 | for (i = 0; i < dss_feat_get_num_mgrs(); i++) { |
271 | RR(DEFAULT_COLOR(i)); | 380 | RR(DEFAULT_COLOR(i)); |
@@ -351,6 +460,8 @@ static void dispc_restore_context(void) | |||
351 | RR(CONTROL); | 460 | RR(CONTROL); |
352 | if (dss_has_feature(FEAT_MGR_LCD2)) | 461 | if (dss_has_feature(FEAT_MGR_LCD2)) |
353 | RR(CONTROL2); | 462 | RR(CONTROL2); |
463 | if (dss_has_feature(FEAT_MGR_LCD3)) | ||
464 | RR(CONTROL3); | ||
354 | /* clear spurious SYNC_LOST_DIGIT interrupts */ | 465 | /* clear spurious SYNC_LOST_DIGIT interrupts */ |
355 | dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); | 466 | dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); |
356 | 467 | ||
@@ -387,101 +498,41 @@ void dispc_runtime_put(void) | |||
387 | WARN_ON(r < 0 && r != -ENOSYS); | 498 | WARN_ON(r < 0 && r != -ENOSYS); |
388 | } | 499 | } |
389 | 500 | ||
390 | static inline bool dispc_mgr_is_lcd(enum omap_channel channel) | ||
391 | { | ||
392 | if (channel == OMAP_DSS_CHANNEL_LCD || | ||
393 | channel == OMAP_DSS_CHANNEL_LCD2) | ||
394 | return true; | ||
395 | else | ||
396 | return false; | ||
397 | } | ||
398 | |||
399 | u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) | 501 | u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) |
400 | { | 502 | { |
401 | switch (channel) { | 503 | return mgr_desc[channel].vsync_irq; |
402 | case OMAP_DSS_CHANNEL_LCD: | ||
403 | return DISPC_IRQ_VSYNC; | ||
404 | case OMAP_DSS_CHANNEL_LCD2: | ||
405 | return DISPC_IRQ_VSYNC2; | ||
406 | case OMAP_DSS_CHANNEL_DIGIT: | ||
407 | return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; | ||
408 | default: | ||
409 | BUG(); | ||
410 | return 0; | ||
411 | } | ||
412 | } | 504 | } |
413 | 505 | ||
414 | u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) | 506 | u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) |
415 | { | 507 | { |
416 | switch (channel) { | 508 | return mgr_desc[channel].framedone_irq; |
417 | case OMAP_DSS_CHANNEL_LCD: | ||
418 | return DISPC_IRQ_FRAMEDONE; | ||
419 | case OMAP_DSS_CHANNEL_LCD2: | ||
420 | return DISPC_IRQ_FRAMEDONE2; | ||
421 | case OMAP_DSS_CHANNEL_DIGIT: | ||
422 | return 0; | ||
423 | default: | ||
424 | BUG(); | ||
425 | return 0; | ||
426 | } | ||
427 | } | 509 | } |
428 | 510 | ||
429 | bool dispc_mgr_go_busy(enum omap_channel channel) | 511 | bool dispc_mgr_go_busy(enum omap_channel channel) |
430 | { | 512 | { |
431 | int bit; | 513 | return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; |
432 | |||
433 | if (dispc_mgr_is_lcd(channel)) | ||
434 | bit = 5; /* GOLCD */ | ||
435 | else | ||
436 | bit = 6; /* GODIGIT */ | ||
437 | |||
438 | if (channel == OMAP_DSS_CHANNEL_LCD2) | ||
439 | return REG_GET(DISPC_CONTROL2, bit, bit) == 1; | ||
440 | else | ||
441 | return REG_GET(DISPC_CONTROL, bit, bit) == 1; | ||
442 | } | 514 | } |
443 | 515 | ||
444 | void dispc_mgr_go(enum omap_channel channel) | 516 | void dispc_mgr_go(enum omap_channel channel) |
445 | { | 517 | { |
446 | int bit; | ||
447 | bool enable_bit, go_bit; | 518 | bool enable_bit, go_bit; |
448 | 519 | ||
449 | if (dispc_mgr_is_lcd(channel)) | ||
450 | bit = 0; /* LCDENABLE */ | ||
451 | else | ||
452 | bit = 1; /* DIGITALENABLE */ | ||
453 | |||
454 | /* if the channel is not enabled, we don't need GO */ | 520 | /* if the channel is not enabled, we don't need GO */ |
455 | if (channel == OMAP_DSS_CHANNEL_LCD2) | 521 | enable_bit = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE) == 1; |
456 | enable_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1; | ||
457 | else | ||
458 | enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1; | ||
459 | 522 | ||
460 | if (!enable_bit) | 523 | if (!enable_bit) |
461 | return; | 524 | return; |
462 | 525 | ||
463 | if (dispc_mgr_is_lcd(channel)) | 526 | go_bit = mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; |
464 | bit = 5; /* GOLCD */ | ||
465 | else | ||
466 | bit = 6; /* GODIGIT */ | ||
467 | |||
468 | if (channel == OMAP_DSS_CHANNEL_LCD2) | ||
469 | go_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1; | ||
470 | else | ||
471 | go_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1; | ||
472 | 527 | ||
473 | if (go_bit) { | 528 | if (go_bit) { |
474 | DSSERR("GO bit not down for channel %d\n", channel); | 529 | DSSERR("GO bit not down for channel %d\n", channel); |
475 | return; | 530 | return; |
476 | } | 531 | } |
477 | 532 | ||
478 | DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : | 533 | DSSDBG("GO %s\n", mgr_desc[channel].name); |
479 | (channel == OMAP_DSS_CHANNEL_LCD2 ? "LCD2" : "DIGIT")); | ||
480 | 534 | ||
481 | if (channel == OMAP_DSS_CHANNEL_LCD2) | 535 | mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); |
482 | REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit); | ||
483 | else | ||
484 | REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit); | ||
485 | } | 536 | } |
486 | 537 | ||
487 | static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) | 538 | static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) |
@@ -832,6 +883,15 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) | |||
832 | chan = 0; | 883 | chan = 0; |
833 | chan2 = 1; | 884 | chan2 = 1; |
834 | break; | 885 | break; |
886 | case OMAP_DSS_CHANNEL_LCD3: | ||
887 | if (dss_has_feature(FEAT_MGR_LCD3)) { | ||
888 | chan = 0; | ||
889 | chan2 = 2; | ||
890 | } else { | ||
891 | BUG(); | ||
892 | return; | ||
893 | } | ||
894 | break; | ||
835 | default: | 895 | default: |
836 | BUG(); | 896 | BUG(); |
837 | return; | 897 | return; |
@@ -867,7 +927,14 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) | |||
867 | 927 | ||
868 | val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); | 928 | val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); |
869 | 929 | ||
870 | if (dss_has_feature(FEAT_MGR_LCD2)) { | 930 | if (dss_has_feature(FEAT_MGR_LCD3)) { |
931 | if (FLD_GET(val, 31, 30) == 0) | ||
932 | channel = FLD_GET(val, shift, shift); | ||
933 | else if (FLD_GET(val, 31, 30) == 1) | ||
934 | channel = OMAP_DSS_CHANNEL_LCD2; | ||
935 | else | ||
936 | channel = OMAP_DSS_CHANNEL_LCD3; | ||
937 | } else if (dss_has_feature(FEAT_MGR_LCD2)) { | ||
871 | if (FLD_GET(val, 31, 30) == 0) | 938 | if (FLD_GET(val, 31, 30) == 0) |
872 | channel = FLD_GET(val, shift, shift); | 939 | channel = FLD_GET(val, shift, shift); |
873 | else | 940 | else |
@@ -922,16 +989,10 @@ void dispc_enable_gamma_table(bool enable) | |||
922 | 989 | ||
923 | static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) | 990 | static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) |
924 | { | 991 | { |
925 | u16 reg; | 992 | if (channel == OMAP_DSS_CHANNEL_DIGIT) |
926 | |||
927 | if (channel == OMAP_DSS_CHANNEL_LCD) | ||
928 | reg = DISPC_CONFIG; | ||
929 | else if (channel == OMAP_DSS_CHANNEL_LCD2) | ||
930 | reg = DISPC_CONFIG2; | ||
931 | else | ||
932 | return; | 993 | return; |
933 | 994 | ||
934 | REG_FLD_MOD(reg, enable, 15, 15); | 995 | mgr_fld_write(channel, DISPC_MGR_FLD_CPR, enable); |
935 | } | 996 | } |
936 | 997 | ||
937 | static void dispc_mgr_set_cpr_coef(enum omap_channel channel, | 998 | static void dispc_mgr_set_cpr_coef(enum omap_channel channel, |
@@ -939,7 +1000,7 @@ static void dispc_mgr_set_cpr_coef(enum omap_channel channel, | |||
939 | { | 1000 | { |
940 | u32 coef_r, coef_g, coef_b; | 1001 | u32 coef_r, coef_g, coef_b; |
941 | 1002 | ||
942 | if (!dispc_mgr_is_lcd(channel)) | 1003 | if (!dss_mgr_is_lcd(channel)) |
943 | return; | 1004 | return; |
944 | 1005 | ||
945 | coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) | | 1006 | coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) | |
@@ -1798,7 +1859,7 @@ static int check_horiz_timing_omap3(enum omap_channel channel, | |||
1798 | 1859 | ||
1799 | nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; | 1860 | nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; |
1800 | pclk = dispc_mgr_pclk_rate(channel); | 1861 | pclk = dispc_mgr_pclk_rate(channel); |
1801 | if (dispc_mgr_is_lcd(channel)) | 1862 | if (dss_mgr_is_lcd(channel)) |
1802 | lclk = dispc_mgr_lclk_rate(channel); | 1863 | lclk = dispc_mgr_lclk_rate(channel); |
1803 | else | 1864 | else |
1804 | lclk = dispc_fclk_rate(); | 1865 | lclk = dispc_fclk_rate(); |
@@ -2086,8 +2147,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, | |||
2086 | } | 2147 | } |
2087 | 2148 | ||
2088 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 2149 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, |
2089 | bool ilace, bool replication, | 2150 | bool replication, const struct omap_video_timings *mgr_timings) |
2090 | const struct omap_video_timings *mgr_timings) | ||
2091 | { | 2151 | { |
2092 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); | 2152 | struct omap_overlay *ovl = omap_dss_get_overlay(plane); |
2093 | bool five_taps = true; | 2153 | bool five_taps = true; |
@@ -2103,6 +2163,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | |||
2103 | u16 out_width, out_height; | 2163 | u16 out_width, out_height; |
2104 | enum omap_channel channel; | 2164 | enum omap_channel channel; |
2105 | int x_predecim = 1, y_predecim = 1; | 2165 | int x_predecim = 1, y_predecim = 1; |
2166 | bool ilace = mgr_timings->interlace; | ||
2106 | 2167 | ||
2107 | channel = dispc_ovl_get_channel_out(plane); | 2168 | channel = dispc_ovl_get_channel_out(plane); |
2108 | 2169 | ||
@@ -2254,14 +2315,9 @@ static void dispc_disable_isr(void *data, u32 mask) | |||
2254 | 2315 | ||
2255 | static void _enable_lcd_out(enum omap_channel channel, bool enable) | 2316 | static void _enable_lcd_out(enum omap_channel channel, bool enable) |
2256 | { | 2317 | { |
2257 | if (channel == OMAP_DSS_CHANNEL_LCD2) { | 2318 | mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); |
2258 | REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0); | 2319 | /* flush posted write */ |
2259 | /* flush posted write */ | 2320 | mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); |
2260 | dispc_read_reg(DISPC_CONTROL2); | ||
2261 | } else { | ||
2262 | REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); | ||
2263 | dispc_read_reg(DISPC_CONTROL); | ||
2264 | } | ||
2265 | } | 2321 | } |
2266 | 2322 | ||
2267 | static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable) | 2323 | static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable) |
@@ -2274,12 +2330,9 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable) | |||
2274 | /* When we disable LCD output, we need to wait until frame is done. | 2330 | /* When we disable LCD output, we need to wait until frame is done. |
2275 | * Otherwise the DSS is still working, and turning off the clocks | 2331 | * Otherwise the DSS is still working, and turning off the clocks |
2276 | * prevents DSS from going to OFF mode */ | 2332 | * prevents DSS from going to OFF mode */ |
2277 | is_on = channel == OMAP_DSS_CHANNEL_LCD2 ? | 2333 | is_on = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); |
2278 | REG_GET(DISPC_CONTROL2, 0, 0) : | ||
2279 | REG_GET(DISPC_CONTROL, 0, 0); | ||
2280 | 2334 | ||
2281 | irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 : | 2335 | irq = mgr_desc[channel].framedone_irq; |
2282 | DISPC_IRQ_FRAMEDONE; | ||
2283 | 2336 | ||
2284 | if (!enable && is_on) { | 2337 | if (!enable && is_on) { |
2285 | init_completion(&frame_done_completion); | 2338 | init_completion(&frame_done_completion); |
@@ -2384,21 +2437,12 @@ static void dispc_mgr_enable_digit_out(bool enable) | |||
2384 | 2437 | ||
2385 | bool dispc_mgr_is_enabled(enum omap_channel channel) | 2438 | bool dispc_mgr_is_enabled(enum omap_channel channel) |
2386 | { | 2439 | { |
2387 | if (channel == OMAP_DSS_CHANNEL_LCD) | 2440 | return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); |
2388 | return !!REG_GET(DISPC_CONTROL, 0, 0); | ||
2389 | else if (channel == OMAP_DSS_CHANNEL_DIGIT) | ||
2390 | return !!REG_GET(DISPC_CONTROL, 1, 1); | ||
2391 | else if (channel == OMAP_DSS_CHANNEL_LCD2) | ||
2392 | return !!REG_GET(DISPC_CONTROL2, 0, 0); | ||
2393 | else { | ||
2394 | BUG(); | ||
2395 | return false; | ||
2396 | } | ||
2397 | } | 2441 | } |
2398 | 2442 | ||
2399 | void dispc_mgr_enable(enum omap_channel channel, bool enable) | 2443 | void dispc_mgr_enable(enum omap_channel channel, bool enable) |
2400 | { | 2444 | { |
2401 | if (dispc_mgr_is_lcd(channel)) | 2445 | if (dss_mgr_is_lcd(channel)) |
2402 | dispc_mgr_enable_lcd_out(channel, enable); | 2446 | dispc_mgr_enable_lcd_out(channel, enable); |
2403 | else if (channel == OMAP_DSS_CHANNEL_DIGIT) | 2447 | else if (channel == OMAP_DSS_CHANNEL_DIGIT) |
2404 | dispc_mgr_enable_digit_out(enable); | 2448 | dispc_mgr_enable_digit_out(enable); |
@@ -2432,36 +2476,13 @@ void dispc_pck_free_enable(bool enable) | |||
2432 | 2476 | ||
2433 | void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable) | 2477 | void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable) |
2434 | { | 2478 | { |
2435 | if (channel == OMAP_DSS_CHANNEL_LCD2) | 2479 | mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable); |
2436 | REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16); | ||
2437 | else | ||
2438 | REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); | ||
2439 | } | 2480 | } |
2440 | 2481 | ||
2441 | 2482 | ||
2442 | void dispc_mgr_set_lcd_display_type(enum omap_channel channel, | 2483 | void dispc_mgr_set_lcd_type_tft(enum omap_channel channel) |
2443 | enum omap_lcd_display_type type) | ||
2444 | { | 2484 | { |
2445 | int mode; | 2485 | mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, 1); |
2446 | |||
2447 | switch (type) { | ||
2448 | case OMAP_DSS_LCD_DISPLAY_STN: | ||
2449 | mode = 0; | ||
2450 | break; | ||
2451 | |||
2452 | case OMAP_DSS_LCD_DISPLAY_TFT: | ||
2453 | mode = 1; | ||
2454 | break; | ||
2455 | |||
2456 | default: | ||
2457 | BUG(); | ||
2458 | return; | ||
2459 | } | ||
2460 | |||
2461 | if (channel == OMAP_DSS_CHANNEL_LCD2) | ||
2462 | REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3); | ||
2463 | else | ||
2464 | REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); | ||
2465 | } | 2486 | } |
2466 | 2487 | ||
2467 | void dispc_set_loadmode(enum omap_dss_load_mode mode) | 2488 | void dispc_set_loadmode(enum omap_dss_load_mode mode) |
@@ -2479,24 +2500,14 @@ static void dispc_mgr_set_trans_key(enum omap_channel ch, | |||
2479 | enum omap_dss_trans_key_type type, | 2500 | enum omap_dss_trans_key_type type, |
2480 | u32 trans_key) | 2501 | u32 trans_key) |
2481 | { | 2502 | { |
2482 | if (ch == OMAP_DSS_CHANNEL_LCD) | 2503 | mgr_fld_write(ch, DISPC_MGR_FLD_TCKSELECTION, type); |
2483 | REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); | ||
2484 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) | ||
2485 | REG_FLD_MOD(DISPC_CONFIG, type, 13, 13); | ||
2486 | else /* OMAP_DSS_CHANNEL_LCD2 */ | ||
2487 | REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11); | ||
2488 | 2504 | ||
2489 | dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); | 2505 | dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); |
2490 | } | 2506 | } |
2491 | 2507 | ||
2492 | static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) | 2508 | static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable) |
2493 | { | 2509 | { |
2494 | if (ch == OMAP_DSS_CHANNEL_LCD) | 2510 | mgr_fld_write(ch, DISPC_MGR_FLD_TCKENABLE, enable); |
2495 | REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); | ||
2496 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) | ||
2497 | REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); | ||
2498 | else /* OMAP_DSS_CHANNEL_LCD2 */ | ||
2499 | REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10); | ||
2500 | } | 2511 | } |
2501 | 2512 | ||
2502 | static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, | 2513 | static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, |
@@ -2547,10 +2558,7 @@ void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines) | |||
2547 | return; | 2558 | return; |
2548 | } | 2559 | } |
2549 | 2560 | ||
2550 | if (channel == OMAP_DSS_CHANNEL_LCD2) | 2561 | mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code); |
2551 | REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8); | ||
2552 | else | ||
2553 | REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); | ||
2554 | } | 2562 | } |
2555 | 2563 | ||
2556 | void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode) | 2564 | void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode) |
@@ -2584,10 +2592,7 @@ void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode) | |||
2584 | 2592 | ||
2585 | void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) | 2593 | void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) |
2586 | { | 2594 | { |
2587 | if (channel == OMAP_DSS_CHANNEL_LCD2) | 2595 | mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable); |
2588 | REG_FLD_MOD(DISPC_CONTROL2, enable, 11, 11); | ||
2589 | else | ||
2590 | REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11); | ||
2591 | } | 2596 | } |
2592 | 2597 | ||
2593 | static bool _dispc_mgr_size_ok(u16 width, u16 height) | 2598 | static bool _dispc_mgr_size_ok(u16 width, u16 height) |
@@ -2627,7 +2632,7 @@ bool dispc_mgr_timings_ok(enum omap_channel channel, | |||
2627 | 2632 | ||
2628 | timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); | 2633 | timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); |
2629 | 2634 | ||
2630 | if (dispc_mgr_is_lcd(channel)) | 2635 | if (dss_mgr_is_lcd(channel)) |
2631 | timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, | 2636 | timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, |
2632 | timings->hfp, timings->hbp, | 2637 | timings->hfp, timings->hbp, |
2633 | timings->vsw, timings->vfp, | 2638 | timings->vsw, timings->vfp, |
@@ -2637,9 +2642,16 @@ bool dispc_mgr_timings_ok(enum omap_channel channel, | |||
2637 | } | 2642 | } |
2638 | 2643 | ||
2639 | static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, | 2644 | static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, |
2640 | int hfp, int hbp, int vsw, int vfp, int vbp) | 2645 | int hfp, int hbp, int vsw, int vfp, int vbp, |
2646 | enum omap_dss_signal_level vsync_level, | ||
2647 | enum omap_dss_signal_level hsync_level, | ||
2648 | enum omap_dss_signal_edge data_pclk_edge, | ||
2649 | enum omap_dss_signal_level de_level, | ||
2650 | enum omap_dss_signal_edge sync_pclk_edge) | ||
2651 | |||
2641 | { | 2652 | { |
2642 | u32 timing_h, timing_v; | 2653 | u32 timing_h, timing_v, l; |
2654 | bool onoff, rf, ipc; | ||
2643 | 2655 | ||
2644 | if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { | 2656 | if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { |
2645 | timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) | | 2657 | timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) | |
@@ -2657,6 +2669,44 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw, | |||
2657 | 2669 | ||
2658 | dispc_write_reg(DISPC_TIMING_H(channel), timing_h); | 2670 | dispc_write_reg(DISPC_TIMING_H(channel), timing_h); |
2659 | dispc_write_reg(DISPC_TIMING_V(channel), timing_v); | 2671 | dispc_write_reg(DISPC_TIMING_V(channel), timing_v); |
2672 | |||
2673 | switch (data_pclk_edge) { | ||
2674 | case OMAPDSS_DRIVE_SIG_RISING_EDGE: | ||
2675 | ipc = false; | ||
2676 | break; | ||
2677 | case OMAPDSS_DRIVE_SIG_FALLING_EDGE: | ||
2678 | ipc = true; | ||
2679 | break; | ||
2680 | case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES: | ||
2681 | default: | ||
2682 | BUG(); | ||
2683 | } | ||
2684 | |||
2685 | switch (sync_pclk_edge) { | ||
2686 | case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES: | ||
2687 | onoff = false; | ||
2688 | rf = false; | ||
2689 | break; | ||
2690 | case OMAPDSS_DRIVE_SIG_FALLING_EDGE: | ||
2691 | onoff = true; | ||
2692 | rf = false; | ||
2693 | break; | ||
2694 | case OMAPDSS_DRIVE_SIG_RISING_EDGE: | ||
2695 | onoff = true; | ||
2696 | rf = true; | ||
2697 | break; | ||
2698 | default: | ||
2699 | BUG(); | ||
2700 | }; | ||
2701 | |||
2702 | l = dispc_read_reg(DISPC_POL_FREQ(channel)); | ||
2703 | l |= FLD_VAL(onoff, 17, 17); | ||
2704 | l |= FLD_VAL(rf, 16, 16); | ||
2705 | l |= FLD_VAL(de_level, 15, 15); | ||
2706 | l |= FLD_VAL(ipc, 14, 14); | ||
2707 | l |= FLD_VAL(hsync_level, 13, 13); | ||
2708 | l |= FLD_VAL(vsync_level, 12, 12); | ||
2709 | dispc_write_reg(DISPC_POL_FREQ(channel), l); | ||
2660 | } | 2710 | } |
2661 | 2711 | ||
2662 | /* change name to mode? */ | 2712 | /* change name to mode? */ |
@@ -2674,9 +2724,10 @@ void dispc_mgr_set_timings(enum omap_channel channel, | |||
2674 | return; | 2724 | return; |
2675 | } | 2725 | } |
2676 | 2726 | ||
2677 | if (dispc_mgr_is_lcd(channel)) { | 2727 | if (dss_mgr_is_lcd(channel)) { |
2678 | _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw, | 2728 | _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw, |
2679 | t.vfp, t.vbp); | 2729 | t.vfp, t.vbp, t.vsync_level, t.hsync_level, |
2730 | t.data_pclk_edge, t.de_level, t.sync_pclk_edge); | ||
2680 | 2731 | ||
2681 | xtot = t.x_res + t.hfp + t.hsw + t.hbp; | 2732 | xtot = t.x_res + t.hfp + t.hsw + t.hbp; |
2682 | ytot = t.y_res + t.vfp + t.vsw + t.vbp; | 2733 | ytot = t.y_res + t.vfp + t.vsw + t.vbp; |
@@ -2687,14 +2738,13 @@ void dispc_mgr_set_timings(enum omap_channel channel, | |||
2687 | DSSDBG("pck %u\n", timings->pixel_clock); | 2738 | DSSDBG("pck %u\n", timings->pixel_clock); |
2688 | DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", | 2739 | DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", |
2689 | t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp); | 2740 | t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp); |
2741 | DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n", | ||
2742 | t.vsync_level, t.hsync_level, t.data_pclk_edge, | ||
2743 | t.de_level, t.sync_pclk_edge); | ||
2690 | 2744 | ||
2691 | DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); | 2745 | DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); |
2692 | } else { | 2746 | } else { |
2693 | enum dss_hdmi_venc_clk_source_select source; | 2747 | if (t.interlace == true) |
2694 | |||
2695 | source = dss_get_hdmi_venc_clk_source(); | ||
2696 | |||
2697 | if (source == DSS_VENC_TV_CLK) | ||
2698 | t.y_res /= 2; | 2748 | t.y_res /= 2; |
2699 | } | 2749 | } |
2700 | 2750 | ||
@@ -2780,7 +2830,7 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) | |||
2780 | { | 2830 | { |
2781 | unsigned long r; | 2831 | unsigned long r; |
2782 | 2832 | ||
2783 | if (dispc_mgr_is_lcd(channel)) { | 2833 | if (dss_mgr_is_lcd(channel)) { |
2784 | int pcd; | 2834 | int pcd; |
2785 | u32 l; | 2835 | u32 l; |
2786 | 2836 | ||
@@ -2821,12 +2871,32 @@ unsigned long dispc_core_clk_rate(void) | |||
2821 | return fclk / lcd; | 2871 | return fclk / lcd; |
2822 | } | 2872 | } |
2823 | 2873 | ||
2824 | void dispc_dump_clocks(struct seq_file *s) | 2874 | static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) |
2825 | { | 2875 | { |
2826 | int lcd, pcd; | 2876 | int lcd, pcd; |
2877 | enum omap_dss_clk_source lcd_clk_src; | ||
2878 | |||
2879 | seq_printf(s, "- %s -\n", mgr_desc[channel].name); | ||
2880 | |||
2881 | lcd_clk_src = dss_get_lcd_clk_source(channel); | ||
2882 | |||
2883 | seq_printf(s, "%s clk source = %s (%s)\n", mgr_desc[channel].name, | ||
2884 | dss_get_generic_clk_source_name(lcd_clk_src), | ||
2885 | dss_feat_get_clk_source_name(lcd_clk_src)); | ||
2886 | |||
2887 | dispc_mgr_get_lcd_divisor(channel, &lcd, &pcd); | ||
2888 | |||
2889 | seq_printf(s, "lck\t\t%-16lulck div\t%u\n", | ||
2890 | dispc_mgr_lclk_rate(channel), lcd); | ||
2891 | seq_printf(s, "pck\t\t%-16lupck div\t%u\n", | ||
2892 | dispc_mgr_pclk_rate(channel), pcd); | ||
2893 | } | ||
2894 | |||
2895 | void dispc_dump_clocks(struct seq_file *s) | ||
2896 | { | ||
2897 | int lcd; | ||
2827 | u32 l; | 2898 | u32 l; |
2828 | enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); | 2899 | enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); |
2829 | enum omap_dss_clk_source lcd_clk_src; | ||
2830 | 2900 | ||
2831 | if (dispc_runtime_get()) | 2901 | if (dispc_runtime_get()) |
2832 | return; | 2902 | return; |
@@ -2847,36 +2917,13 @@ void dispc_dump_clocks(struct seq_file *s) | |||
2847 | seq_printf(s, "lck\t\t%-16lulck div\t%u\n", | 2917 | seq_printf(s, "lck\t\t%-16lulck div\t%u\n", |
2848 | (dispc_fclk_rate()/lcd), lcd); | 2918 | (dispc_fclk_rate()/lcd), lcd); |
2849 | } | 2919 | } |
2850 | seq_printf(s, "- LCD1 -\n"); | ||
2851 | |||
2852 | lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD); | ||
2853 | |||
2854 | seq_printf(s, "lcd1_clk source = %s (%s)\n", | ||
2855 | dss_get_generic_clk_source_name(lcd_clk_src), | ||
2856 | dss_feat_get_clk_source_name(lcd_clk_src)); | ||
2857 | |||
2858 | dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); | ||
2859 | |||
2860 | seq_printf(s, "lck\t\t%-16lulck div\t%u\n", | ||
2861 | dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd); | ||
2862 | seq_printf(s, "pck\t\t%-16lupck div\t%u\n", | ||
2863 | dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd); | ||
2864 | if (dss_has_feature(FEAT_MGR_LCD2)) { | ||
2865 | seq_printf(s, "- LCD2 -\n"); | ||
2866 | |||
2867 | lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2); | ||
2868 | 2920 | ||
2869 | seq_printf(s, "lcd2_clk source = %s (%s)\n", | 2921 | dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD); |
2870 | dss_get_generic_clk_source_name(lcd_clk_src), | ||
2871 | dss_feat_get_clk_source_name(lcd_clk_src)); | ||
2872 | 2922 | ||
2873 | dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); | 2923 | if (dss_has_feature(FEAT_MGR_LCD2)) |
2874 | 2924 | dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD2); | |
2875 | seq_printf(s, "lck\t\t%-16lulck div\t%u\n", | 2925 | if (dss_has_feature(FEAT_MGR_LCD3)) |
2876 | dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd); | 2926 | dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3); |
2877 | seq_printf(s, "pck\t\t%-16lupck div\t%u\n", | ||
2878 | dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd); | ||
2879 | } | ||
2880 | 2927 | ||
2881 | dispc_runtime_put(); | 2928 | dispc_runtime_put(); |
2882 | } | 2929 | } |
@@ -2929,6 +2976,12 @@ void dispc_dump_irqs(struct seq_file *s) | |||
2929 | PIS(ACBIAS_COUNT_STAT2); | 2976 | PIS(ACBIAS_COUNT_STAT2); |
2930 | PIS(SYNC_LOST2); | 2977 | PIS(SYNC_LOST2); |
2931 | } | 2978 | } |
2979 | if (dss_has_feature(FEAT_MGR_LCD3)) { | ||
2980 | PIS(FRAMEDONE3); | ||
2981 | PIS(VSYNC3); | ||
2982 | PIS(ACBIAS_COUNT_STAT3); | ||
2983 | PIS(SYNC_LOST3); | ||
2984 | } | ||
2932 | #undef PIS | 2985 | #undef PIS |
2933 | } | 2986 | } |
2934 | #endif | 2987 | #endif |
@@ -2940,6 +2993,7 @@ static void dispc_dump_regs(struct seq_file *s) | |||
2940 | [OMAP_DSS_CHANNEL_LCD] = "LCD", | 2993 | [OMAP_DSS_CHANNEL_LCD] = "LCD", |
2941 | [OMAP_DSS_CHANNEL_DIGIT] = "TV", | 2994 | [OMAP_DSS_CHANNEL_DIGIT] = "TV", |
2942 | [OMAP_DSS_CHANNEL_LCD2] = "LCD2", | 2995 | [OMAP_DSS_CHANNEL_LCD2] = "LCD2", |
2996 | [OMAP_DSS_CHANNEL_LCD3] = "LCD3", | ||
2943 | }; | 2997 | }; |
2944 | const char *ovl_names[] = { | 2998 | const char *ovl_names[] = { |
2945 | [OMAP_DSS_GFX] = "GFX", | 2999 | [OMAP_DSS_GFX] = "GFX", |
@@ -2972,6 +3026,10 @@ static void dispc_dump_regs(struct seq_file *s) | |||
2972 | DUMPREG(DISPC_CONTROL2); | 3026 | DUMPREG(DISPC_CONTROL2); |
2973 | DUMPREG(DISPC_CONFIG2); | 3027 | DUMPREG(DISPC_CONFIG2); |
2974 | } | 3028 | } |
3029 | if (dss_has_feature(FEAT_MGR_LCD3)) { | ||
3030 | DUMPREG(DISPC_CONTROL3); | ||
3031 | DUMPREG(DISPC_CONFIG3); | ||
3032 | } | ||
2975 | 3033 | ||
2976 | #undef DUMPREG | 3034 | #undef DUMPREG |
2977 | 3035 | ||
@@ -3093,41 +3151,8 @@ static void dispc_dump_regs(struct seq_file *s) | |||
3093 | #undef DUMPREG | 3151 | #undef DUMPREG |
3094 | } | 3152 | } |
3095 | 3153 | ||
3096 | static void _dispc_mgr_set_pol_freq(enum omap_channel channel, bool onoff, | ||
3097 | bool rf, bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi, | ||
3098 | u8 acb) | ||
3099 | { | ||
3100 | u32 l = 0; | ||
3101 | |||
3102 | DSSDBG("onoff %d rf %d ieo %d ipc %d ihs %d ivs %d acbi %d acb %d\n", | ||
3103 | onoff, rf, ieo, ipc, ihs, ivs, acbi, acb); | ||
3104 | |||
3105 | l |= FLD_VAL(onoff, 17, 17); | ||
3106 | l |= FLD_VAL(rf, 16, 16); | ||
3107 | l |= FLD_VAL(ieo, 15, 15); | ||
3108 | l |= FLD_VAL(ipc, 14, 14); | ||
3109 | l |= FLD_VAL(ihs, 13, 13); | ||
3110 | l |= FLD_VAL(ivs, 12, 12); | ||
3111 | l |= FLD_VAL(acbi, 11, 8); | ||
3112 | l |= FLD_VAL(acb, 7, 0); | ||
3113 | |||
3114 | dispc_write_reg(DISPC_POL_FREQ(channel), l); | ||
3115 | } | ||
3116 | |||
3117 | void dispc_mgr_set_pol_freq(enum omap_channel channel, | ||
3118 | enum omap_panel_config config, u8 acbi, u8 acb) | ||
3119 | { | ||
3120 | _dispc_mgr_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0, | ||
3121 | (config & OMAP_DSS_LCD_RF) != 0, | ||
3122 | (config & OMAP_DSS_LCD_IEO) != 0, | ||
3123 | (config & OMAP_DSS_LCD_IPC) != 0, | ||
3124 | (config & OMAP_DSS_LCD_IHS) != 0, | ||
3125 | (config & OMAP_DSS_LCD_IVS) != 0, | ||
3126 | acbi, acb); | ||
3127 | } | ||
3128 | |||
3129 | /* with fck as input clock rate, find dispc dividers that produce req_pck */ | 3154 | /* with fck as input clock rate, find dispc dividers that produce req_pck */ |
3130 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | 3155 | void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck, |
3131 | struct dispc_clock_info *cinfo) | 3156 | struct dispc_clock_info *cinfo) |
3132 | { | 3157 | { |
3133 | u16 pcd_min, pcd_max; | 3158 | u16 pcd_min, pcd_max; |
@@ -3138,9 +3163,6 @@ void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | |||
3138 | pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD); | 3163 | pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD); |
3139 | pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD); | 3164 | pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD); |
3140 | 3165 | ||
3141 | if (!is_tft) | ||
3142 | pcd_min = 3; | ||
3143 | |||
3144 | best_pck = 0; | 3166 | best_pck = 0; |
3145 | best_ld = 0; | 3167 | best_ld = 0; |
3146 | best_pd = 0; | 3168 | best_pd = 0; |
@@ -3192,15 +3214,13 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, | |||
3192 | return 0; | 3214 | return 0; |
3193 | } | 3215 | } |
3194 | 3216 | ||
3195 | int dispc_mgr_set_clock_div(enum omap_channel channel, | 3217 | void dispc_mgr_set_clock_div(enum omap_channel channel, |
3196 | struct dispc_clock_info *cinfo) | 3218 | struct dispc_clock_info *cinfo) |
3197 | { | 3219 | { |
3198 | DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); | 3220 | DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); |
3199 | DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); | 3221 | DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); |
3200 | 3222 | ||
3201 | dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div); | 3223 | dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div); |
3202 | |||
3203 | return 0; | ||
3204 | } | 3224 | } |
3205 | 3225 | ||
3206 | int dispc_mgr_get_clock_div(enum omap_channel channel, | 3226 | int dispc_mgr_get_clock_div(enum omap_channel channel, |
@@ -3354,6 +3374,8 @@ static void print_irq_status(u32 status) | |||
3354 | PIS(SYNC_LOST_DIGIT); | 3374 | PIS(SYNC_LOST_DIGIT); |
3355 | if (dss_has_feature(FEAT_MGR_LCD2)) | 3375 | if (dss_has_feature(FEAT_MGR_LCD2)) |
3356 | PIS(SYNC_LOST2); | 3376 | PIS(SYNC_LOST2); |
3377 | if (dss_has_feature(FEAT_MGR_LCD3)) | ||
3378 | PIS(SYNC_LOST3); | ||
3357 | #undef PIS | 3379 | #undef PIS |
3358 | 3380 | ||
3359 | printk("\n"); | 3381 | printk("\n"); |
@@ -3450,12 +3472,6 @@ static void dispc_error_worker(struct work_struct *work) | |||
3450 | DISPC_IRQ_VID3_FIFO_UNDERFLOW, | 3472 | DISPC_IRQ_VID3_FIFO_UNDERFLOW, |
3451 | }; | 3473 | }; |
3452 | 3474 | ||
3453 | static const unsigned sync_lost_bits[] = { | ||
3454 | DISPC_IRQ_SYNC_LOST, | ||
3455 | DISPC_IRQ_SYNC_LOST_DIGIT, | ||
3456 | DISPC_IRQ_SYNC_LOST2, | ||
3457 | }; | ||
3458 | |||
3459 | spin_lock_irqsave(&dispc.irq_lock, flags); | 3475 | spin_lock_irqsave(&dispc.irq_lock, flags); |
3460 | errors = dispc.error_irqs; | 3476 | errors = dispc.error_irqs; |
3461 | dispc.error_irqs = 0; | 3477 | dispc.error_irqs = 0; |
@@ -3484,7 +3500,7 @@ static void dispc_error_worker(struct work_struct *work) | |||
3484 | unsigned bit; | 3500 | unsigned bit; |
3485 | 3501 | ||
3486 | mgr = omap_dss_get_overlay_manager(i); | 3502 | mgr = omap_dss_get_overlay_manager(i); |
3487 | bit = sync_lost_bits[i]; | 3503 | bit = mgr_desc[i].sync_lost_irq; |
3488 | 3504 | ||
3489 | if (bit & errors) { | 3505 | if (bit & errors) { |
3490 | struct omap_dss_device *dssdev = mgr->device; | 3506 | struct omap_dss_device *dssdev = mgr->device; |
@@ -3603,6 +3619,8 @@ static void _omap_dispc_initialize_irq(void) | |||
3603 | dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; | 3619 | dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; |
3604 | if (dss_has_feature(FEAT_MGR_LCD2)) | 3620 | if (dss_has_feature(FEAT_MGR_LCD2)) |
3605 | dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; | 3621 | dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; |
3622 | if (dss_has_feature(FEAT_MGR_LCD3)) | ||
3623 | dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST3; | ||
3606 | if (dss_feat_get_num_ovls() > 3) | 3624 | if (dss_feat_get_num_ovls() > 3) |
3607 | dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW; | 3625 | dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW; |
3608 | 3626 | ||
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h index f278080e1063..92d8a9be86fc 100644 --- a/drivers/video/omap2/dss/dispc.h +++ b/drivers/video/omap2/dss/dispc.h | |||
@@ -36,6 +36,8 @@ | |||
36 | #define DISPC_CONTROL2 0x0238 | 36 | #define DISPC_CONTROL2 0x0238 |
37 | #define DISPC_CONFIG2 0x0620 | 37 | #define DISPC_CONFIG2 0x0620 |
38 | #define DISPC_DIVISOR 0x0804 | 38 | #define DISPC_DIVISOR 0x0804 |
39 | #define DISPC_CONTROL3 0x0848 | ||
40 | #define DISPC_CONFIG3 0x084C | ||
39 | 41 | ||
40 | /* DISPC overlay registers */ | 42 | /* DISPC overlay registers */ |
41 | #define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \ | 43 | #define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \ |
@@ -118,6 +120,8 @@ static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel) | |||
118 | return 0x0050; | 120 | return 0x0050; |
119 | case OMAP_DSS_CHANNEL_LCD2: | 121 | case OMAP_DSS_CHANNEL_LCD2: |
120 | return 0x03AC; | 122 | return 0x03AC; |
123 | case OMAP_DSS_CHANNEL_LCD3: | ||
124 | return 0x0814; | ||
121 | default: | 125 | default: |
122 | BUG(); | 126 | BUG(); |
123 | return 0; | 127 | return 0; |
@@ -133,6 +137,8 @@ static inline u16 DISPC_TRANS_COLOR(enum omap_channel channel) | |||
133 | return 0x0058; | 137 | return 0x0058; |
134 | case OMAP_DSS_CHANNEL_LCD2: | 138 | case OMAP_DSS_CHANNEL_LCD2: |
135 | return 0x03B0; | 139 | return 0x03B0; |
140 | case OMAP_DSS_CHANNEL_LCD3: | ||
141 | return 0x0818; | ||
136 | default: | 142 | default: |
137 | BUG(); | 143 | BUG(); |
138 | return 0; | 144 | return 0; |
@@ -149,6 +155,8 @@ static inline u16 DISPC_TIMING_H(enum omap_channel channel) | |||
149 | return 0; | 155 | return 0; |
150 | case OMAP_DSS_CHANNEL_LCD2: | 156 | case OMAP_DSS_CHANNEL_LCD2: |
151 | return 0x0400; | 157 | return 0x0400; |
158 | case OMAP_DSS_CHANNEL_LCD3: | ||
159 | return 0x0840; | ||
152 | default: | 160 | default: |
153 | BUG(); | 161 | BUG(); |
154 | return 0; | 162 | return 0; |
@@ -165,6 +173,8 @@ static inline u16 DISPC_TIMING_V(enum omap_channel channel) | |||
165 | return 0; | 173 | return 0; |
166 | case OMAP_DSS_CHANNEL_LCD2: | 174 | case OMAP_DSS_CHANNEL_LCD2: |
167 | return 0x0404; | 175 | return 0x0404; |
176 | case OMAP_DSS_CHANNEL_LCD3: | ||
177 | return 0x0844; | ||
168 | default: | 178 | default: |
169 | BUG(); | 179 | BUG(); |
170 | return 0; | 180 | return 0; |
@@ -181,6 +191,8 @@ static inline u16 DISPC_POL_FREQ(enum omap_channel channel) | |||
181 | return 0; | 191 | return 0; |
182 | case OMAP_DSS_CHANNEL_LCD2: | 192 | case OMAP_DSS_CHANNEL_LCD2: |
183 | return 0x0408; | 193 | return 0x0408; |
194 | case OMAP_DSS_CHANNEL_LCD3: | ||
195 | return 0x083C; | ||
184 | default: | 196 | default: |
185 | BUG(); | 197 | BUG(); |
186 | return 0; | 198 | return 0; |
@@ -197,6 +209,8 @@ static inline u16 DISPC_DIVISORo(enum omap_channel channel) | |||
197 | return 0; | 209 | return 0; |
198 | case OMAP_DSS_CHANNEL_LCD2: | 210 | case OMAP_DSS_CHANNEL_LCD2: |
199 | return 0x040C; | 211 | return 0x040C; |
212 | case OMAP_DSS_CHANNEL_LCD3: | ||
213 | return 0x0838; | ||
200 | default: | 214 | default: |
201 | BUG(); | 215 | BUG(); |
202 | return 0; | 216 | return 0; |
@@ -213,6 +227,8 @@ static inline u16 DISPC_SIZE_MGR(enum omap_channel channel) | |||
213 | return 0x0078; | 227 | return 0x0078; |
214 | case OMAP_DSS_CHANNEL_LCD2: | 228 | case OMAP_DSS_CHANNEL_LCD2: |
215 | return 0x03CC; | 229 | return 0x03CC; |
230 | case OMAP_DSS_CHANNEL_LCD3: | ||
231 | return 0x0834; | ||
216 | default: | 232 | default: |
217 | BUG(); | 233 | BUG(); |
218 | return 0; | 234 | return 0; |
@@ -229,6 +245,8 @@ static inline u16 DISPC_DATA_CYCLE1(enum omap_channel channel) | |||
229 | return 0; | 245 | return 0; |
230 | case OMAP_DSS_CHANNEL_LCD2: | 246 | case OMAP_DSS_CHANNEL_LCD2: |
231 | return 0x03C0; | 247 | return 0x03C0; |
248 | case OMAP_DSS_CHANNEL_LCD3: | ||
249 | return 0x0828; | ||
232 | default: | 250 | default: |
233 | BUG(); | 251 | BUG(); |
234 | return 0; | 252 | return 0; |
@@ -245,6 +263,8 @@ static inline u16 DISPC_DATA_CYCLE2(enum omap_channel channel) | |||
245 | return 0; | 263 | return 0; |
246 | case OMAP_DSS_CHANNEL_LCD2: | 264 | case OMAP_DSS_CHANNEL_LCD2: |
247 | return 0x03C4; | 265 | return 0x03C4; |
266 | case OMAP_DSS_CHANNEL_LCD3: | ||
267 | return 0x082C; | ||
248 | default: | 268 | default: |
249 | BUG(); | 269 | BUG(); |
250 | return 0; | 270 | return 0; |
@@ -261,6 +281,8 @@ static inline u16 DISPC_DATA_CYCLE3(enum omap_channel channel) | |||
261 | return 0; | 281 | return 0; |
262 | case OMAP_DSS_CHANNEL_LCD2: | 282 | case OMAP_DSS_CHANNEL_LCD2: |
263 | return 0x03C8; | 283 | return 0x03C8; |
284 | case OMAP_DSS_CHANNEL_LCD3: | ||
285 | return 0x0830; | ||
264 | default: | 286 | default: |
265 | BUG(); | 287 | BUG(); |
266 | return 0; | 288 | return 0; |
@@ -277,6 +299,8 @@ static inline u16 DISPC_CPR_COEF_R(enum omap_channel channel) | |||
277 | return 0; | 299 | return 0; |
278 | case OMAP_DSS_CHANNEL_LCD2: | 300 | case OMAP_DSS_CHANNEL_LCD2: |
279 | return 0x03BC; | 301 | return 0x03BC; |
302 | case OMAP_DSS_CHANNEL_LCD3: | ||
303 | return 0x0824; | ||
280 | default: | 304 | default: |
281 | BUG(); | 305 | BUG(); |
282 | return 0; | 306 | return 0; |
@@ -293,6 +317,8 @@ static inline u16 DISPC_CPR_COEF_G(enum omap_channel channel) | |||
293 | return 0; | 317 | return 0; |
294 | case OMAP_DSS_CHANNEL_LCD2: | 318 | case OMAP_DSS_CHANNEL_LCD2: |
295 | return 0x03B8; | 319 | return 0x03B8; |
320 | case OMAP_DSS_CHANNEL_LCD3: | ||
321 | return 0x0820; | ||
296 | default: | 322 | default: |
297 | BUG(); | 323 | BUG(); |
298 | return 0; | 324 | return 0; |
@@ -309,6 +335,8 @@ static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel) | |||
309 | return 0; | 335 | return 0; |
310 | case OMAP_DSS_CHANNEL_LCD2: | 336 | case OMAP_DSS_CHANNEL_LCD2: |
311 | return 0x03B4; | 337 | return 0x03B4; |
338 | case OMAP_DSS_CHANNEL_LCD3: | ||
339 | return 0x081C; | ||
312 | default: | 340 | default: |
313 | BUG(); | 341 | BUG(); |
314 | return 0; | 342 | return 0; |
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 249010630370..5bd957e85505 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c | |||
@@ -116,7 +116,7 @@ static ssize_t display_timings_store(struct device *dev, | |||
116 | struct device_attribute *attr, const char *buf, size_t size) | 116 | struct device_attribute *attr, const char *buf, size_t size) |
117 | { | 117 | { |
118 | struct omap_dss_device *dssdev = to_dss_device(dev); | 118 | struct omap_dss_device *dssdev = to_dss_device(dev); |
119 | struct omap_video_timings t; | 119 | struct omap_video_timings t = dssdev->panel.timings; |
120 | int r, found; | 120 | int r, found; |
121 | 121 | ||
122 | if (!dssdev->driver->set_timings || !dssdev->driver->check_timings) | 122 | if (!dssdev->driver->set_timings || !dssdev->driver->check_timings) |
@@ -316,44 +316,6 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev, | |||
316 | } | 316 | } |
317 | EXPORT_SYMBOL(omapdss_default_get_timings); | 317 | EXPORT_SYMBOL(omapdss_default_get_timings); |
318 | 318 | ||
319 | /* Checks if replication logic should be used. Only use for active matrix, | ||
320 | * when overlay is in RGB12U or RGB16 mode, and LCD interface is | ||
321 | * 18bpp or 24bpp */ | ||
322 | bool dss_use_replication(struct omap_dss_device *dssdev, | ||
323 | enum omap_color_mode mode) | ||
324 | { | ||
325 | int bpp; | ||
326 | |||
327 | if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16) | ||
328 | return false; | ||
329 | |||
330 | if (dssdev->type == OMAP_DISPLAY_TYPE_DPI && | ||
331 | (dssdev->panel.config & OMAP_DSS_LCD_TFT) == 0) | ||
332 | return false; | ||
333 | |||
334 | switch (dssdev->type) { | ||
335 | case OMAP_DISPLAY_TYPE_DPI: | ||
336 | bpp = dssdev->phy.dpi.data_lines; | ||
337 | break; | ||
338 | case OMAP_DISPLAY_TYPE_HDMI: | ||
339 | case OMAP_DISPLAY_TYPE_VENC: | ||
340 | case OMAP_DISPLAY_TYPE_SDI: | ||
341 | bpp = 24; | ||
342 | break; | ||
343 | case OMAP_DISPLAY_TYPE_DBI: | ||
344 | bpp = dssdev->ctrl.pixel_size; | ||
345 | break; | ||
346 | case OMAP_DISPLAY_TYPE_DSI: | ||
347 | bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | ||
348 | break; | ||
349 | default: | ||
350 | BUG(); | ||
351 | return false; | ||
352 | } | ||
353 | |||
354 | return bpp > 16; | ||
355 | } | ||
356 | |||
357 | void dss_init_device(struct platform_device *pdev, | 319 | void dss_init_device(struct platform_device *pdev, |
358 | struct omap_dss_device *dssdev) | 320 | struct omap_dss_device *dssdev) |
359 | { | 321 | { |
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 8c2056c9537b..3266be23fc0d 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c | |||
@@ -38,6 +38,8 @@ | |||
38 | static struct { | 38 | static struct { |
39 | struct regulator *vdds_dsi_reg; | 39 | struct regulator *vdds_dsi_reg; |
40 | struct platform_device *dsidev; | 40 | struct platform_device *dsidev; |
41 | |||
42 | struct dss_lcd_mgr_config mgr_config; | ||
41 | } dpi; | 43 | } dpi; |
42 | 44 | ||
43 | static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) | 45 | static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) |
@@ -64,7 +66,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev) | |||
64 | return false; | 66 | return false; |
65 | } | 67 | } |
66 | 68 | ||
67 | static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, | 69 | static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, |
68 | unsigned long pck_req, unsigned long *fck, int *lck_div, | 70 | unsigned long pck_req, unsigned long *fck, int *lck_div, |
69 | int *pck_div) | 71 | int *pck_div) |
70 | { | 72 | { |
@@ -72,8 +74,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, | |||
72 | struct dispc_clock_info dispc_cinfo; | 74 | struct dispc_clock_info dispc_cinfo; |
73 | int r; | 75 | int r; |
74 | 76 | ||
75 | r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req, | 77 | r = dsi_pll_calc_clock_div_pck(dpi.dsidev, pck_req, &dsi_cinfo, |
76 | &dsi_cinfo, &dispc_cinfo); | 78 | &dispc_cinfo); |
77 | if (r) | 79 | if (r) |
78 | return r; | 80 | return r; |
79 | 81 | ||
@@ -83,11 +85,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, | |||
83 | 85 | ||
84 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); | 86 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); |
85 | 87 | ||
86 | r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); | 88 | dpi.mgr_config.clock_info = dispc_cinfo; |
87 | if (r) { | ||
88 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | ||
89 | return r; | ||
90 | } | ||
91 | 89 | ||
92 | *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; | 90 | *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; |
93 | *lck_div = dispc_cinfo.lck_div; | 91 | *lck_div = dispc_cinfo.lck_div; |
@@ -96,7 +94,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, | |||
96 | return 0; | 94 | return 0; |
97 | } | 95 | } |
98 | 96 | ||
99 | static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft, | 97 | static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, |
100 | unsigned long pck_req, unsigned long *fck, int *lck_div, | 98 | unsigned long pck_req, unsigned long *fck, int *lck_div, |
101 | int *pck_div) | 99 | int *pck_div) |
102 | { | 100 | { |
@@ -104,7 +102,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft, | |||
104 | struct dispc_clock_info dispc_cinfo; | 102 | struct dispc_clock_info dispc_cinfo; |
105 | int r; | 103 | int r; |
106 | 104 | ||
107 | r = dss_calc_clock_div(is_tft, pck_req, &dss_cinfo, &dispc_cinfo); | 105 | r = dss_calc_clock_div(pck_req, &dss_cinfo, &dispc_cinfo); |
108 | if (r) | 106 | if (r) |
109 | return r; | 107 | return r; |
110 | 108 | ||
@@ -112,9 +110,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft, | |||
112 | if (r) | 110 | if (r) |
113 | return r; | 111 | return r; |
114 | 112 | ||
115 | r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); | 113 | dpi.mgr_config.clock_info = dispc_cinfo; |
116 | if (r) | ||
117 | return r; | ||
118 | 114 | ||
119 | *fck = dss_cinfo.fck; | 115 | *fck = dss_cinfo.fck; |
120 | *lck_div = dispc_cinfo.lck_div; | 116 | *lck_div = dispc_cinfo.lck_div; |
@@ -129,20 +125,14 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) | |||
129 | int lck_div = 0, pck_div = 0; | 125 | int lck_div = 0, pck_div = 0; |
130 | unsigned long fck = 0; | 126 | unsigned long fck = 0; |
131 | unsigned long pck; | 127 | unsigned long pck; |
132 | bool is_tft; | ||
133 | int r = 0; | 128 | int r = 0; |
134 | 129 | ||
135 | dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config, | ||
136 | dssdev->panel.acbi, dssdev->panel.acb); | ||
137 | |||
138 | is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; | ||
139 | |||
140 | if (dpi_use_dsi_pll(dssdev)) | 130 | if (dpi_use_dsi_pll(dssdev)) |
141 | r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000, | 131 | r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck, |
142 | &fck, &lck_div, &pck_div); | 132 | &lck_div, &pck_div); |
143 | else | 133 | else |
144 | r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000, | 134 | r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck, |
145 | &fck, &lck_div, &pck_div); | 135 | &lck_div, &pck_div); |
146 | if (r) | 136 | if (r) |
147 | return r; | 137 | return r; |
148 | 138 | ||
@@ -161,19 +151,18 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) | |||
161 | return 0; | 151 | return 0; |
162 | } | 152 | } |
163 | 153 | ||
164 | static void dpi_basic_init(struct omap_dss_device *dssdev) | 154 | static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) |
165 | { | 155 | { |
166 | bool is_tft; | 156 | dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; |
157 | |||
158 | dpi.mgr_config.stallmode = false; | ||
159 | dpi.mgr_config.fifohandcheck = false; | ||
167 | 160 | ||
168 | is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; | 161 | dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines; |
169 | 162 | ||
170 | dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS); | 163 | dpi.mgr_config.lcden_sig_polarity = 0; |
171 | dispc_mgr_enable_stallmode(dssdev->manager->id, false); | ||
172 | 164 | ||
173 | dispc_mgr_set_lcd_display_type(dssdev->manager->id, is_tft ? | 165 | dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config); |
174 | OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN); | ||
175 | dispc_mgr_set_tft_data_lines(dssdev->manager->id, | ||
176 | dssdev->phy.dpi.data_lines); | ||
177 | } | 166 | } |
178 | 167 | ||
179 | int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | 168 | int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) |
@@ -206,8 +195,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | |||
206 | if (r) | 195 | if (r) |
207 | goto err_get_dispc; | 196 | goto err_get_dispc; |
208 | 197 | ||
209 | dpi_basic_init(dssdev); | ||
210 | |||
211 | if (dpi_use_dsi_pll(dssdev)) { | 198 | if (dpi_use_dsi_pll(dssdev)) { |
212 | r = dsi_runtime_get(dpi.dsidev); | 199 | r = dsi_runtime_get(dpi.dsidev); |
213 | if (r) | 200 | if (r) |
@@ -222,6 +209,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | |||
222 | if (r) | 209 | if (r) |
223 | goto err_set_mode; | 210 | goto err_set_mode; |
224 | 211 | ||
212 | dpi_config_lcd_manager(dssdev); | ||
213 | |||
225 | mdelay(2); | 214 | mdelay(2); |
226 | 215 | ||
227 | r = dss_mgr_enable(dssdev->manager); | 216 | r = dss_mgr_enable(dssdev->manager); |
@@ -292,7 +281,6 @@ EXPORT_SYMBOL(dpi_set_timings); | |||
292 | int dpi_check_timings(struct omap_dss_device *dssdev, | 281 | int dpi_check_timings(struct omap_dss_device *dssdev, |
293 | struct omap_video_timings *timings) | 282 | struct omap_video_timings *timings) |
294 | { | 283 | { |
295 | bool is_tft; | ||
296 | int r; | 284 | int r; |
297 | int lck_div, pck_div; | 285 | int lck_div, pck_div; |
298 | unsigned long fck; | 286 | unsigned long fck; |
@@ -305,11 +293,9 @@ int dpi_check_timings(struct omap_dss_device *dssdev, | |||
305 | if (timings->pixel_clock == 0) | 293 | if (timings->pixel_clock == 0) |
306 | return -EINVAL; | 294 | return -EINVAL; |
307 | 295 | ||
308 | is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; | ||
309 | |||
310 | if (dpi_use_dsi_pll(dssdev)) { | 296 | if (dpi_use_dsi_pll(dssdev)) { |
311 | struct dsi_clock_info dsi_cinfo; | 297 | struct dsi_clock_info dsi_cinfo; |
312 | r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, | 298 | r = dsi_pll_calc_clock_div_pck(dpi.dsidev, |
313 | timings->pixel_clock * 1000, | 299 | timings->pixel_clock * 1000, |
314 | &dsi_cinfo, &dispc_cinfo); | 300 | &dsi_cinfo, &dispc_cinfo); |
315 | 301 | ||
@@ -319,7 +305,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev, | |||
319 | fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; | 305 | fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; |
320 | } else { | 306 | } else { |
321 | struct dss_clock_info dss_cinfo; | 307 | struct dss_clock_info dss_cinfo; |
322 | r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000, | 308 | r = dss_calc_clock_div(timings->pixel_clock * 1000, |
323 | &dss_cinfo, &dispc_cinfo); | 309 | &dss_cinfo, &dispc_cinfo); |
324 | 310 | ||
325 | if (r) | 311 | if (r) |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 14ce8cc079e3..b07e8864f82f 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -331,6 +331,8 @@ struct dsi_data { | |||
331 | unsigned num_lanes_used; | 331 | unsigned num_lanes_used; |
332 | 332 | ||
333 | unsigned scp_clk_refcount; | 333 | unsigned scp_clk_refcount; |
334 | |||
335 | struct dss_lcd_mgr_config mgr_config; | ||
334 | }; | 336 | }; |
335 | 337 | ||
336 | struct dsi_packet_sent_handler_data { | 338 | struct dsi_packet_sent_handler_data { |
@@ -1085,9 +1087,9 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev, | |||
1085 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1087 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1086 | 1088 | ||
1087 | if (enable) | 1089 | if (enable) |
1088 | clk_enable(dsi->sys_clk); | 1090 | clk_prepare_enable(dsi->sys_clk); |
1089 | else | 1091 | else |
1090 | clk_disable(dsi->sys_clk); | 1092 | clk_disable_unprepare(dsi->sys_clk); |
1091 | 1093 | ||
1092 | if (enable && dsi->pll_locked) { | 1094 | if (enable && dsi->pll_locked) { |
1093 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) | 1095 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) |
@@ -1316,7 +1318,7 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev, | |||
1316 | return 0; | 1318 | return 0; |
1317 | } | 1319 | } |
1318 | 1320 | ||
1319 | int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, | 1321 | int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, |
1320 | unsigned long req_pck, struct dsi_clock_info *dsi_cinfo, | 1322 | unsigned long req_pck, struct dsi_clock_info *dsi_cinfo, |
1321 | struct dispc_clock_info *dispc_cinfo) | 1323 | struct dispc_clock_info *dispc_cinfo) |
1322 | { | 1324 | { |
@@ -1335,8 +1337,8 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, | |||
1335 | dsi->cache_cinfo.clkin == dss_sys_clk) { | 1337 | dsi->cache_cinfo.clkin == dss_sys_clk) { |
1336 | DSSDBG("DSI clock info found from cache\n"); | 1338 | DSSDBG("DSI clock info found from cache\n"); |
1337 | *dsi_cinfo = dsi->cache_cinfo; | 1339 | *dsi_cinfo = dsi->cache_cinfo; |
1338 | dispc_find_clk_divs(is_tft, req_pck, | 1340 | dispc_find_clk_divs(req_pck, dsi_cinfo->dsi_pll_hsdiv_dispc_clk, |
1339 | dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); | 1341 | dispc_cinfo); |
1340 | return 0; | 1342 | return 0; |
1341 | } | 1343 | } |
1342 | 1344 | ||
@@ -1402,7 +1404,7 @@ retry: | |||
1402 | 1404 | ||
1403 | match = 1; | 1405 | match = 1; |
1404 | 1406 | ||
1405 | dispc_find_clk_divs(is_tft, req_pck, | 1407 | dispc_find_clk_divs(req_pck, |
1406 | cur.dsi_pll_hsdiv_dispc_clk, | 1408 | cur.dsi_pll_hsdiv_dispc_clk, |
1407 | &cur_dispc); | 1409 | &cur_dispc); |
1408 | 1410 | ||
@@ -3631,17 +3633,14 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev) | |||
3631 | static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) | 3633 | static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) |
3632 | { | 3634 | { |
3633 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3635 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3634 | int de_pol = dssdev->panel.dsi_vm_data.vp_de_pol; | ||
3635 | int hsync_pol = dssdev->panel.dsi_vm_data.vp_hsync_pol; | ||
3636 | int vsync_pol = dssdev->panel.dsi_vm_data.vp_vsync_pol; | ||
3637 | bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end; | 3636 | bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end; |
3638 | bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end; | 3637 | bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end; |
3639 | u32 r; | 3638 | u32 r; |
3640 | 3639 | ||
3641 | r = dsi_read_reg(dsidev, DSI_CTRL); | 3640 | r = dsi_read_reg(dsidev, DSI_CTRL); |
3642 | r = FLD_MOD(r, de_pol, 9, 9); /* VP_DE_POL */ | 3641 | r = FLD_MOD(r, 1, 9, 9); /* VP_DE_POL */ |
3643 | r = FLD_MOD(r, hsync_pol, 10, 10); /* VP_HSYNC_POL */ | 3642 | r = FLD_MOD(r, 1, 10, 10); /* VP_HSYNC_POL */ |
3644 | r = FLD_MOD(r, vsync_pol, 11, 11); /* VP_VSYNC_POL */ | 3643 | r = FLD_MOD(r, 1, 11, 11); /* VP_VSYNC_POL */ |
3645 | r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */ | 3644 | r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */ |
3646 | r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */ | 3645 | r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */ |
3647 | r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */ | 3646 | r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */ |
@@ -4340,52 +4339,101 @@ EXPORT_SYMBOL(omap_dsi_update); | |||
4340 | 4339 | ||
4341 | /* Display funcs */ | 4340 | /* Display funcs */ |
4342 | 4341 | ||
4342 | static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) | ||
4343 | { | ||
4344 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4345 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4346 | struct dispc_clock_info dispc_cinfo; | ||
4347 | int r; | ||
4348 | unsigned long long fck; | ||
4349 | |||
4350 | fck = dsi_get_pll_hsdiv_dispc_rate(dsidev); | ||
4351 | |||
4352 | dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div; | ||
4353 | dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div; | ||
4354 | |||
4355 | r = dispc_calc_clock_rates(fck, &dispc_cinfo); | ||
4356 | if (r) { | ||
4357 | DSSERR("Failed to calc dispc clocks\n"); | ||
4358 | return r; | ||
4359 | } | ||
4360 | |||
4361 | dsi->mgr_config.clock_info = dispc_cinfo; | ||
4362 | |||
4363 | return 0; | ||
4364 | } | ||
4365 | |||
4343 | static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | 4366 | static int dsi_display_init_dispc(struct omap_dss_device *dssdev) |
4344 | { | 4367 | { |
4368 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4369 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4370 | struct omap_video_timings timings; | ||
4345 | int r; | 4371 | int r; |
4372 | u32 irq = 0; | ||
4346 | 4373 | ||
4347 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { | 4374 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { |
4348 | u16 dw, dh; | 4375 | u16 dw, dh; |
4349 | u32 irq; | ||
4350 | struct omap_video_timings timings = { | ||
4351 | .hsw = 1, | ||
4352 | .hfp = 1, | ||
4353 | .hbp = 1, | ||
4354 | .vsw = 1, | ||
4355 | .vfp = 0, | ||
4356 | .vbp = 0, | ||
4357 | }; | ||
4358 | 4376 | ||
4359 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | 4377 | dssdev->driver->get_resolution(dssdev, &dw, &dh); |
4378 | |||
4360 | timings.x_res = dw; | 4379 | timings.x_res = dw; |
4361 | timings.y_res = dh; | 4380 | timings.y_res = dh; |
4381 | timings.hsw = 1; | ||
4382 | timings.hfp = 1; | ||
4383 | timings.hbp = 1; | ||
4384 | timings.vsw = 1; | ||
4385 | timings.vfp = 0; | ||
4386 | timings.vbp = 0; | ||
4362 | 4387 | ||
4363 | irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? | 4388 | irq = dispc_mgr_get_framedone_irq(dssdev->manager->id); |
4364 | DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2; | ||
4365 | 4389 | ||
4366 | r = omap_dispc_register_isr(dsi_framedone_irq_callback, | 4390 | r = omap_dispc_register_isr(dsi_framedone_irq_callback, |
4367 | (void *) dssdev, irq); | 4391 | (void *) dssdev, irq); |
4368 | if (r) { | 4392 | if (r) { |
4369 | DSSERR("can't get FRAMEDONE irq\n"); | 4393 | DSSERR("can't get FRAMEDONE irq\n"); |
4370 | return r; | 4394 | goto err; |
4371 | } | 4395 | } |
4372 | 4396 | ||
4373 | dispc_mgr_enable_stallmode(dssdev->manager->id, true); | 4397 | dsi->mgr_config.stallmode = true; |
4374 | dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); | 4398 | dsi->mgr_config.fifohandcheck = true; |
4375 | |||
4376 | dss_mgr_set_timings(dssdev->manager, &timings); | ||
4377 | } else { | 4399 | } else { |
4378 | dispc_mgr_enable_stallmode(dssdev->manager->id, false); | 4400 | timings = dssdev->panel.timings; |
4379 | dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0); | ||
4380 | 4401 | ||
4381 | dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); | 4402 | dsi->mgr_config.stallmode = false; |
4403 | dsi->mgr_config.fifohandcheck = false; | ||
4382 | } | 4404 | } |
4383 | 4405 | ||
4384 | dispc_mgr_set_lcd_display_type(dssdev->manager->id, | 4406 | /* |
4385 | OMAP_DSS_LCD_DISPLAY_TFT); | 4407 | * override interlace, logic level and edge related parameters in |
4386 | dispc_mgr_set_tft_data_lines(dssdev->manager->id, | 4408 | * omap_video_timings with default values |
4387 | dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)); | 4409 | */ |
4410 | timings.interlace = false; | ||
4411 | timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
4412 | timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
4413 | timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | ||
4414 | timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
4415 | timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | ||
4416 | |||
4417 | dss_mgr_set_timings(dssdev->manager, &timings); | ||
4418 | |||
4419 | r = dsi_configure_dispc_clocks(dssdev); | ||
4420 | if (r) | ||
4421 | goto err1; | ||
4422 | |||
4423 | dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; | ||
4424 | dsi->mgr_config.video_port_width = | ||
4425 | dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | ||
4426 | dsi->mgr_config.lcden_sig_polarity = 0; | ||
4427 | |||
4428 | dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config); | ||
4429 | |||
4388 | return 0; | 4430 | return 0; |
4431 | err1: | ||
4432 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) | ||
4433 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, | ||
4434 | (void *) dssdev, irq); | ||
4435 | err: | ||
4436 | return r; | ||
4389 | } | 4437 | } |
4390 | 4438 | ||
4391 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) | 4439 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) |
@@ -4393,8 +4441,7 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) | |||
4393 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { | 4441 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { |
4394 | u32 irq; | 4442 | u32 irq; |
4395 | 4443 | ||
4396 | irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? | 4444 | irq = dispc_mgr_get_framedone_irq(dssdev->manager->id); |
4397 | DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2; | ||
4398 | 4445 | ||
4399 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, | 4446 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, |
4400 | (void *) dssdev, irq); | 4447 | (void *) dssdev, irq); |
@@ -4426,33 +4473,6 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) | |||
4426 | return 0; | 4473 | return 0; |
4427 | } | 4474 | } |
4428 | 4475 | ||
4429 | static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) | ||
4430 | { | ||
4431 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4432 | struct dispc_clock_info dispc_cinfo; | ||
4433 | int r; | ||
4434 | unsigned long long fck; | ||
4435 | |||
4436 | fck = dsi_get_pll_hsdiv_dispc_rate(dsidev); | ||
4437 | |||
4438 | dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div; | ||
4439 | dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div; | ||
4440 | |||
4441 | r = dispc_calc_clock_rates(fck, &dispc_cinfo); | ||
4442 | if (r) { | ||
4443 | DSSERR("Failed to calc dispc clocks\n"); | ||
4444 | return r; | ||
4445 | } | ||
4446 | |||
4447 | r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); | ||
4448 | if (r) { | ||
4449 | DSSERR("Failed to set dispc clocks\n"); | ||
4450 | return r; | ||
4451 | } | ||
4452 | |||
4453 | return 0; | ||
4454 | } | ||
4455 | |||
4456 | static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | 4476 | static int dsi_display_init_dsi(struct omap_dss_device *dssdev) |
4457 | { | 4477 | { |
4458 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4478 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -4474,10 +4494,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
4474 | 4494 | ||
4475 | DSSDBG("PLL OK\n"); | 4495 | DSSDBG("PLL OK\n"); |
4476 | 4496 | ||
4477 | r = dsi_configure_dispc_clocks(dssdev); | ||
4478 | if (r) | ||
4479 | goto err2; | ||
4480 | |||
4481 | r = dsi_cio_init(dssdev); | 4497 | r = dsi_cio_init(dssdev); |
4482 | if (r) | 4498 | if (r) |
4483 | goto err2; | 4499 | goto err2; |
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index d2b57197b292..04b4586113e3 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
@@ -388,7 +388,8 @@ void dss_select_lcd_clk_source(enum omap_channel channel, | |||
388 | dsi_wait_pll_hsdiv_dispc_active(dsidev); | 388 | dsi_wait_pll_hsdiv_dispc_active(dsidev); |
389 | break; | 389 | break; |
390 | case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: | 390 | case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: |
391 | BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2); | 391 | BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 && |
392 | channel != OMAP_DSS_CHANNEL_LCD3); | ||
392 | b = 1; | 393 | b = 1; |
393 | dsidev = dsi_get_dsidev_from_id(1); | 394 | dsidev = dsi_get_dsidev_from_id(1); |
394 | dsi_wait_pll_hsdiv_dispc_active(dsidev); | 395 | dsi_wait_pll_hsdiv_dispc_active(dsidev); |
@@ -398,10 +399,12 @@ void dss_select_lcd_clk_source(enum omap_channel channel, | |||
398 | return; | 399 | return; |
399 | } | 400 | } |
400 | 401 | ||
401 | pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; | 402 | pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : |
403 | (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19); | ||
402 | REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */ | 404 | REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */ |
403 | 405 | ||
404 | ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; | 406 | ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : |
407 | (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2); | ||
405 | dss.lcd_clk_source[ix] = clk_src; | 408 | dss.lcd_clk_source[ix] = clk_src; |
406 | } | 409 | } |
407 | 410 | ||
@@ -418,7 +421,8 @@ enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module) | |||
418 | enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) | 421 | enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) |
419 | { | 422 | { |
420 | if (dss_has_feature(FEAT_LCD_CLK_SRC)) { | 423 | if (dss_has_feature(FEAT_LCD_CLK_SRC)) { |
421 | int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; | 424 | int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : |
425 | (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2); | ||
422 | return dss.lcd_clk_source[ix]; | 426 | return dss.lcd_clk_source[ix]; |
423 | } else { | 427 | } else { |
424 | /* LCD_CLK source is the same as DISPC_FCLK source for | 428 | /* LCD_CLK source is the same as DISPC_FCLK source for |
@@ -502,8 +506,7 @@ unsigned long dss_get_dpll4_rate(void) | |||
502 | return 0; | 506 | return 0; |
503 | } | 507 | } |
504 | 508 | ||
505 | int dss_calc_clock_div(bool is_tft, unsigned long req_pck, | 509 | int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, |
506 | struct dss_clock_info *dss_cinfo, | ||
507 | struct dispc_clock_info *dispc_cinfo) | 510 | struct dispc_clock_info *dispc_cinfo) |
508 | { | 511 | { |
509 | unsigned long prate; | 512 | unsigned long prate; |
@@ -551,7 +554,7 @@ retry: | |||
551 | fck = clk_get_rate(dss.dss_clk); | 554 | fck = clk_get_rate(dss.dss_clk); |
552 | fck_div = 1; | 555 | fck_div = 1; |
553 | 556 | ||
554 | dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); | 557 | dispc_find_clk_divs(req_pck, fck, &cur_dispc); |
555 | match = 1; | 558 | match = 1; |
556 | 559 | ||
557 | best_dss.fck = fck; | 560 | best_dss.fck = fck; |
@@ -581,7 +584,7 @@ retry: | |||
581 | 584 | ||
582 | match = 1; | 585 | match = 1; |
583 | 586 | ||
584 | dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); | 587 | dispc_find_clk_divs(req_pck, fck, &cur_dispc); |
585 | 588 | ||
586 | if (abs(cur_dispc.pck - req_pck) < | 589 | if (abs(cur_dispc.pck - req_pck) < |
587 | abs(best_dispc.pck - req_pck)) { | 590 | abs(best_dispc.pck - req_pck)) { |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index dd1092ceaeef..f67afe76f217 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
@@ -152,6 +152,25 @@ struct dsi_clock_info { | |||
152 | u16 lp_clk_div; | 152 | u16 lp_clk_div; |
153 | }; | 153 | }; |
154 | 154 | ||
155 | struct reg_field { | ||
156 | u16 reg; | ||
157 | u8 high; | ||
158 | u8 low; | ||
159 | }; | ||
160 | |||
161 | struct dss_lcd_mgr_config { | ||
162 | enum dss_io_pad_mode io_pad_mode; | ||
163 | |||
164 | bool stallmode; | ||
165 | bool fifohandcheck; | ||
166 | |||
167 | struct dispc_clock_info clock_info; | ||
168 | |||
169 | int video_port_width; | ||
170 | |||
171 | int lcden_sig_polarity; | ||
172 | }; | ||
173 | |||
155 | struct seq_file; | 174 | struct seq_file; |
156 | struct platform_device; | 175 | struct platform_device; |
157 | 176 | ||
@@ -188,6 +207,8 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, | |||
188 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr); | 207 | int dss_mgr_unset_device(struct omap_overlay_manager *mgr); |
189 | void dss_mgr_set_timings(struct omap_overlay_manager *mgr, | 208 | void dss_mgr_set_timings(struct omap_overlay_manager *mgr, |
190 | struct omap_video_timings *timings); | 209 | struct omap_video_timings *timings); |
210 | void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, | ||
211 | const struct dss_lcd_mgr_config *config); | ||
191 | const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); | 212 | const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); |
192 | 213 | ||
193 | bool dss_ovl_is_enabled(struct omap_overlay *ovl); | 214 | bool dss_ovl_is_enabled(struct omap_overlay *ovl); |
@@ -210,8 +231,6 @@ void dss_init_device(struct platform_device *pdev, | |||
210 | struct omap_dss_device *dssdev); | 231 | struct omap_dss_device *dssdev); |
211 | void dss_uninit_device(struct platform_device *pdev, | 232 | void dss_uninit_device(struct platform_device *pdev, |
212 | struct omap_dss_device *dssdev); | 233 | struct omap_dss_device *dssdev); |
213 | bool dss_use_replication(struct omap_dss_device *dssdev, | ||
214 | enum omap_color_mode mode); | ||
215 | 234 | ||
216 | /* manager */ | 235 | /* manager */ |
217 | int dss_init_overlay_managers(struct platform_device *pdev); | 236 | int dss_init_overlay_managers(struct platform_device *pdev); |
@@ -223,8 +242,18 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr, | |||
223 | int dss_mgr_check(struct omap_overlay_manager *mgr, | 242 | int dss_mgr_check(struct omap_overlay_manager *mgr, |
224 | struct omap_overlay_manager_info *info, | 243 | struct omap_overlay_manager_info *info, |
225 | const struct omap_video_timings *mgr_timings, | 244 | const struct omap_video_timings *mgr_timings, |
245 | const struct dss_lcd_mgr_config *config, | ||
226 | struct omap_overlay_info **overlay_infos); | 246 | struct omap_overlay_info **overlay_infos); |
227 | 247 | ||
248 | static inline bool dss_mgr_is_lcd(enum omap_channel id) | ||
249 | { | ||
250 | if (id == OMAP_DSS_CHANNEL_LCD || id == OMAP_DSS_CHANNEL_LCD2 || | ||
251 | id == OMAP_DSS_CHANNEL_LCD3) | ||
252 | return true; | ||
253 | else | ||
254 | return false; | ||
255 | } | ||
256 | |||
228 | /* overlay */ | 257 | /* overlay */ |
229 | void dss_init_overlays(struct platform_device *pdev); | 258 | void dss_init_overlays(struct platform_device *pdev); |
230 | void dss_uninit_overlays(struct platform_device *pdev); | 259 | void dss_uninit_overlays(struct platform_device *pdev); |
@@ -234,6 +263,8 @@ int dss_ovl_simple_check(struct omap_overlay *ovl, | |||
234 | const struct omap_overlay_info *info); | 263 | const struct omap_overlay_info *info); |
235 | int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, | 264 | int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, |
236 | const struct omap_video_timings *mgr_timings); | 265 | const struct omap_video_timings *mgr_timings); |
266 | bool dss_ovl_use_replication(struct dss_lcd_mgr_config config, | ||
267 | enum omap_color_mode mode); | ||
237 | 268 | ||
238 | /* DSS */ | 269 | /* DSS */ |
239 | int dss_init_platform_driver(void) __init; | 270 | int dss_init_platform_driver(void) __init; |
@@ -268,8 +299,7 @@ unsigned long dss_get_dpll4_rate(void); | |||
268 | int dss_calc_clock_rates(struct dss_clock_info *cinfo); | 299 | int dss_calc_clock_rates(struct dss_clock_info *cinfo); |
269 | int dss_set_clock_div(struct dss_clock_info *cinfo); | 300 | int dss_set_clock_div(struct dss_clock_info *cinfo); |
270 | int dss_get_clock_div(struct dss_clock_info *cinfo); | 301 | int dss_get_clock_div(struct dss_clock_info *cinfo); |
271 | int dss_calc_clock_div(bool is_tft, unsigned long req_pck, | 302 | int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, |
272 | struct dss_clock_info *dss_cinfo, | ||
273 | struct dispc_clock_info *dispc_cinfo); | 303 | struct dispc_clock_info *dispc_cinfo); |
274 | 304 | ||
275 | /* SDI */ | 305 | /* SDI */ |
@@ -296,7 +326,7 @@ u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); | |||
296 | unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); | 326 | unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); |
297 | int dsi_pll_set_clock_div(struct platform_device *dsidev, | 327 | int dsi_pll_set_clock_div(struct platform_device *dsidev, |
298 | struct dsi_clock_info *cinfo); | 328 | struct dsi_clock_info *cinfo); |
299 | int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, | 329 | int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, |
300 | unsigned long req_pck, struct dsi_clock_info *cinfo, | 330 | unsigned long req_pck, struct dsi_clock_info *cinfo, |
301 | struct dispc_clock_info *dispc_cinfo); | 331 | struct dispc_clock_info *dispc_cinfo); |
302 | int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, | 332 | int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, |
@@ -330,7 +360,7 @@ static inline int dsi_pll_set_clock_div(struct platform_device *dsidev, | |||
330 | return -ENODEV; | 360 | return -ENODEV; |
331 | } | 361 | } |
332 | static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, | 362 | static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, |
333 | bool is_tft, unsigned long req_pck, | 363 | unsigned long req_pck, |
334 | struct dsi_clock_info *dsi_cinfo, | 364 | struct dsi_clock_info *dsi_cinfo, |
335 | struct dispc_clock_info *dispc_cinfo) | 365 | struct dispc_clock_info *dispc_cinfo) |
336 | { | 366 | { |
@@ -387,7 +417,7 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode); | |||
387 | bool dispc_mgr_timings_ok(enum omap_channel channel, | 417 | bool dispc_mgr_timings_ok(enum omap_channel channel, |
388 | const struct omap_video_timings *timings); | 418 | const struct omap_video_timings *timings); |
389 | unsigned long dispc_fclk_rate(void); | 419 | unsigned long dispc_fclk_rate(void); |
390 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | 420 | void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck, |
391 | struct dispc_clock_info *cinfo); | 421 | struct dispc_clock_info *cinfo); |
392 | int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, | 422 | int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, |
393 | struct dispc_clock_info *cinfo); | 423 | struct dispc_clock_info *cinfo); |
@@ -398,8 +428,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, | |||
398 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, | 428 | u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, |
399 | bool manual_update); | 429 | bool manual_update); |
400 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, | 430 | int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, |
401 | bool ilace, bool replication, | 431 | bool replication, const struct omap_video_timings *mgr_timings); |
402 | const struct omap_video_timings *mgr_timings); | ||
403 | int dispc_ovl_enable(enum omap_plane plane, bool enable); | 432 | int dispc_ovl_enable(enum omap_plane plane, bool enable); |
404 | void dispc_ovl_set_channel_out(enum omap_plane plane, | 433 | void dispc_ovl_set_channel_out(enum omap_plane plane, |
405 | enum omap_channel channel); | 434 | enum omap_channel channel); |
@@ -415,16 +444,13 @@ bool dispc_mgr_is_channel_enabled(enum omap_channel channel); | |||
415 | void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode); | 444 | void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode); |
416 | void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable); | 445 | void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable); |
417 | void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); | 446 | void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); |
418 | void dispc_mgr_set_lcd_display_type(enum omap_channel channel, | 447 | void dispc_mgr_set_lcd_type_tft(enum omap_channel channel); |
419 | enum omap_lcd_display_type type); | ||
420 | void dispc_mgr_set_timings(enum omap_channel channel, | 448 | void dispc_mgr_set_timings(enum omap_channel channel, |
421 | struct omap_video_timings *timings); | 449 | struct omap_video_timings *timings); |
422 | void dispc_mgr_set_pol_freq(enum omap_channel channel, | ||
423 | enum omap_panel_config config, u8 acbi, u8 acb); | ||
424 | unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); | 450 | unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); |
425 | unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); | 451 | unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); |
426 | unsigned long dispc_core_clk_rate(void); | 452 | unsigned long dispc_core_clk_rate(void); |
427 | int dispc_mgr_set_clock_div(enum omap_channel channel, | 453 | void dispc_mgr_set_clock_div(enum omap_channel channel, |
428 | struct dispc_clock_info *cinfo); | 454 | struct dispc_clock_info *cinfo); |
429 | int dispc_mgr_get_clock_div(enum omap_channel channel, | 455 | int dispc_mgr_get_clock_div(enum omap_channel channel, |
430 | struct dispc_clock_info *cinfo); | 456 | struct dispc_clock_info *cinfo); |
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index bdf469f080e7..996ffcbfed58 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h | |||
@@ -24,9 +24,9 @@ | |||
24 | #include "ti_hdmi.h" | 24 | #include "ti_hdmi.h" |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #define MAX_DSS_MANAGERS 3 | 27 | #define MAX_DSS_MANAGERS 4 |
28 | #define MAX_DSS_OVERLAYS 4 | 28 | #define MAX_DSS_OVERLAYS 4 |
29 | #define MAX_DSS_LCD_MANAGERS 2 | 29 | #define MAX_DSS_LCD_MANAGERS 3 |
30 | #define MAX_NUM_DSI 2 | 30 | #define MAX_NUM_DSI 2 |
31 | 31 | ||
32 | /* DSS has feature id */ | 32 | /* DSS has feature id */ |
@@ -36,6 +36,7 @@ enum dss_feat_id { | |||
36 | FEAT_PCKFREEENABLE, | 36 | FEAT_PCKFREEENABLE, |
37 | FEAT_FUNCGATED, | 37 | FEAT_FUNCGATED, |
38 | FEAT_MGR_LCD2, | 38 | FEAT_MGR_LCD2, |
39 | FEAT_MGR_LCD3, | ||
39 | FEAT_LINEBUFFERSPLIT, | 40 | FEAT_LINEBUFFERSPLIT, |
40 | FEAT_ROWREPEATENABLE, | 41 | FEAT_ROWREPEATENABLE, |
41 | FEAT_RESIZECONF, | 42 | FEAT_RESIZECONF, |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 26a2430a7028..060216fdc578 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
@@ -78,43 +78,214 @@ static struct { | |||
78 | */ | 78 | */ |
79 | 79 | ||
80 | static const struct hdmi_config cea_timings[] = { | 80 | static const struct hdmi_config cea_timings[] = { |
81 | { {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, | 81 | { |
82 | { {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, | 82 | { 640, 480, 25200, 96, 16, 48, 2, 10, 33, |
83 | { {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, | 83 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, |
84 | { {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} }, | 84 | false, }, |
85 | { {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} }, | 85 | { 1, HDMI_HDMI }, |
86 | { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} }, | 86 | }, |
87 | { {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} }, | 87 | { |
88 | { {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} }, | 88 | { 720, 480, 27027, 62, 16, 60, 6, 9, 30, |
89 | { {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} }, | 89 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, |
90 | { {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} }, | 90 | false, }, |
91 | { {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} }, | 91 | { 2, HDMI_HDMI }, |
92 | { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} }, | 92 | }, |
93 | { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, | 93 | { |
94 | { {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, | 94 | { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, |
95 | { {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, | 95 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, |
96 | false, }, | ||
97 | { 4, HDMI_HDMI }, | ||
98 | }, | ||
99 | { | ||
100 | { 1920, 540, 74250, 44, 88, 148, 5, 2, 15, | ||
101 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
102 | true, }, | ||
103 | { 5, HDMI_HDMI }, | ||
104 | }, | ||
105 | { | ||
106 | { 1440, 240, 27027, 124, 38, 114, 3, 4, 15, | ||
107 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
108 | true, }, | ||
109 | { 6, HDMI_HDMI }, | ||
110 | }, | ||
111 | { | ||
112 | { 1920, 1080, 148500, 44, 88, 148, 5, 4, 36, | ||
113 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
114 | false, }, | ||
115 | { 16, HDMI_HDMI }, | ||
116 | }, | ||
117 | { | ||
118 | { 720, 576, 27000, 64, 12, 68, 5, 5, 39, | ||
119 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
120 | false, }, | ||
121 | { 17, HDMI_HDMI }, | ||
122 | }, | ||
123 | { | ||
124 | { 1280, 720, 74250, 40, 440, 220, 5, 5, 20, | ||
125 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
126 | false, }, | ||
127 | { 19, HDMI_HDMI }, | ||
128 | }, | ||
129 | { | ||
130 | { 1920, 540, 74250, 44, 528, 148, 5, 2, 15, | ||
131 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
132 | true, }, | ||
133 | { 20, HDMI_HDMI }, | ||
134 | }, | ||
135 | { | ||
136 | { 1440, 288, 27000, 126, 24, 138, 3, 2, 19, | ||
137 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
138 | true, }, | ||
139 | { 21, HDMI_HDMI }, | ||
140 | }, | ||
141 | { | ||
142 | { 1440, 576, 54000, 128, 24, 136, 5, 5, 39, | ||
143 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
144 | false, }, | ||
145 | { 29, HDMI_HDMI }, | ||
146 | }, | ||
147 | { | ||
148 | { 1920, 1080, 148500, 44, 528, 148, 5, 4, 36, | ||
149 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
150 | false, }, | ||
151 | { 31, HDMI_HDMI }, | ||
152 | }, | ||
153 | { | ||
154 | { 1920, 1080, 74250, 44, 638, 148, 5, 4, 36, | ||
155 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
156 | false, }, | ||
157 | { 32, HDMI_HDMI }, | ||
158 | }, | ||
159 | { | ||
160 | { 2880, 480, 108108, 248, 64, 240, 6, 9, 30, | ||
161 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
162 | false, }, | ||
163 | { 35, HDMI_HDMI }, | ||
164 | }, | ||
165 | { | ||
166 | { 2880, 576, 108000, 256, 48, 272, 5, 5, 39, | ||
167 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
168 | false, }, | ||
169 | { 37, HDMI_HDMI }, | ||
170 | }, | ||
96 | }; | 171 | }; |
172 | |||
97 | static const struct hdmi_config vesa_timings[] = { | 173 | static const struct hdmi_config vesa_timings[] = { |
98 | /* VESA From Here */ | 174 | /* VESA From Here */ |
99 | { {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, | 175 | { |
100 | { {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, | 176 | { 640, 480, 25175, 96, 16, 48, 2, 11, 31, |
101 | { {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} }, | 177 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, |
102 | { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} }, | 178 | false, }, |
103 | { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} }, | 179 | { 4, HDMI_DVI }, |
104 | { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} }, | 180 | }, |
105 | { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} }, | 181 | { |
106 | { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} }, | 182 | { 800, 600, 40000, 128, 40, 88, 4, 1, 23, |
107 | { {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} }, | 183 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, |
108 | { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} }, | 184 | false, }, |
109 | { {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} }, | 185 | { 9, HDMI_DVI }, |
110 | { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} }, | 186 | }, |
111 | { {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} }, | 187 | { |
112 | { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} }, | 188 | { 848, 480, 33750, 112, 16, 112, 8, 6, 23, |
113 | { {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} }, | 189 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, |
114 | { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} }, | 190 | false, }, |
115 | { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} }, | 191 | { 0xE, HDMI_DVI }, |
116 | { {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} }, | 192 | }, |
117 | { {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } | 193 | { |
194 | { 1280, 768, 79500, 128, 64, 192, 7, 3, 20, | ||
195 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
196 | false, }, | ||
197 | { 0x17, HDMI_DVI }, | ||
198 | }, | ||
199 | { | ||
200 | { 1280, 800, 83500, 128, 72, 200, 6, 3, 22, | ||
201 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
202 | false, }, | ||
203 | { 0x1C, HDMI_DVI }, | ||
204 | }, | ||
205 | { | ||
206 | { 1360, 768, 85500, 112, 64, 256, 6, 3, 18, | ||
207 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
208 | false, }, | ||
209 | { 0x27, HDMI_DVI }, | ||
210 | }, | ||
211 | { | ||
212 | { 1280, 960, 108000, 112, 96, 312, 3, 1, 36, | ||
213 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
214 | false, }, | ||
215 | { 0x20, HDMI_DVI }, | ||
216 | }, | ||
217 | { | ||
218 | { 1280, 1024, 108000, 112, 48, 248, 3, 1, 38, | ||
219 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
220 | false, }, | ||
221 | { 0x23, HDMI_DVI }, | ||
222 | }, | ||
223 | { | ||
224 | { 1024, 768, 65000, 136, 24, 160, 6, 3, 29, | ||
225 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | ||
226 | false, }, | ||
227 | { 0x10, HDMI_DVI }, | ||
228 | }, | ||
229 | { | ||
230 | { 1400, 1050, 121750, 144, 88, 232, 4, 3, 32, | ||
231 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
232 | false, }, | ||
233 | { 0x2A, HDMI_DVI }, | ||
234 | }, | ||
235 | { | ||
236 | { 1440, 900, 106500, 152, 80, 232, 6, 3, 25, | ||
237 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
238 | false, }, | ||
239 | { 0x2F, HDMI_DVI }, | ||
240 | }, | ||
241 | { | ||
242 | { 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, | ||
243 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, | ||
244 | false, }, | ||
245 | { 0x3A, HDMI_DVI }, | ||
246 | }, | ||
247 | { | ||
248 | { 1366, 768, 85500, 143, 70, 213, 3, 3, 24, | ||
249 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
250 | false, }, | ||
251 | { 0x51, HDMI_DVI }, | ||
252 | }, | ||
253 | { | ||
254 | { 1920, 1080, 148500, 44, 148, 80, 5, 4, 36, | ||
255 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
256 | false, }, | ||
257 | { 0x52, HDMI_DVI }, | ||
258 | }, | ||
259 | { | ||
260 | { 1280, 768, 68250, 32, 48, 80, 7, 3, 12, | ||
261 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
262 | false, }, | ||
263 | { 0x16, HDMI_DVI }, | ||
264 | }, | ||
265 | { | ||
266 | { 1400, 1050, 101000, 32, 48, 80, 4, 3, 23, | ||
267 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
268 | false, }, | ||
269 | { 0x29, HDMI_DVI }, | ||
270 | }, | ||
271 | { | ||
272 | { 1680, 1050, 119000, 32, 48, 80, 6, 3, 21, | ||
273 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
274 | false, }, | ||
275 | { 0x39, HDMI_DVI }, | ||
276 | }, | ||
277 | { | ||
278 | { 1280, 800, 79500, 32, 48, 80, 6, 3, 14, | ||
279 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, | ||
280 | false, }, | ||
281 | { 0x1B, HDMI_DVI }, | ||
282 | }, | ||
283 | { | ||
284 | { 1280, 720, 74250, 40, 110, 220, 5, 5, 20, | ||
285 | OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, | ||
286 | false, }, | ||
287 | { 0x55, HDMI_DVI }, | ||
288 | }, | ||
118 | }; | 289 | }; |
119 | 290 | ||
120 | static int hdmi_runtime_get(void) | 291 | static int hdmi_runtime_get(void) |
@@ -179,7 +350,7 @@ static const struct hdmi_config *hdmi_get_timings(void) | |||
179 | } | 350 | } |
180 | 351 | ||
181 | static bool hdmi_timings_compare(struct omap_video_timings *timing1, | 352 | static bool hdmi_timings_compare(struct omap_video_timings *timing1, |
182 | const struct hdmi_video_timings *timing2) | 353 | const struct omap_video_timings *timing2) |
183 | { | 354 | { |
184 | int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; | 355 | int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; |
185 | 356 | ||
@@ -758,6 +929,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev) | |||
758 | hdmi.ip_data.core_av_offset = HDMI_CORE_AV; | 929 | hdmi.ip_data.core_av_offset = HDMI_CORE_AV; |
759 | hdmi.ip_data.pll_offset = HDMI_PLLCTRL; | 930 | hdmi.ip_data.pll_offset = HDMI_PLLCTRL; |
760 | hdmi.ip_data.phy_offset = HDMI_PHY; | 931 | hdmi.ip_data.phy_offset = HDMI_PHY; |
932 | mutex_init(&hdmi.ip_data.lock); | ||
761 | 933 | ||
762 | hdmi_panel_init(); | 934 | hdmi_panel_init(); |
763 | 935 | ||
@@ -785,7 +957,7 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | |||
785 | 957 | ||
786 | static int hdmi_runtime_suspend(struct device *dev) | 958 | static int hdmi_runtime_suspend(struct device *dev) |
787 | { | 959 | { |
788 | clk_disable(hdmi.sys_clk); | 960 | clk_disable_unprepare(hdmi.sys_clk); |
789 | 961 | ||
790 | dispc_runtime_put(); | 962 | dispc_runtime_put(); |
791 | 963 | ||
@@ -800,7 +972,7 @@ static int hdmi_runtime_resume(struct device *dev) | |||
800 | if (r < 0) | 972 | if (r < 0) |
801 | return r; | 973 | return r; |
802 | 974 | ||
803 | clk_enable(hdmi.sys_clk); | 975 | clk_prepare_enable(hdmi.sys_clk); |
804 | 976 | ||
805 | return 0; | 977 | return 0; |
806 | } | 978 | } |
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c index 1179e3c4b1c7..e10844faadf9 100644 --- a/drivers/video/omap2/dss/hdmi_panel.c +++ b/drivers/video/omap2/dss/hdmi_panel.c | |||
@@ -43,10 +43,11 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev) | |||
43 | { | 43 | { |
44 | DSSDBG("ENTER hdmi_panel_probe\n"); | 44 | DSSDBG("ENTER hdmi_panel_probe\n"); |
45 | 45 | ||
46 | dssdev->panel.config = OMAP_DSS_LCD_TFT | | 46 | dssdev->panel.timings = (struct omap_video_timings) |
47 | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; | 47 | { 640, 480, 25175, 96, 16, 48, 2, 11, 31, |
48 | 48 | OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, | |
49 | dssdev->panel.timings = (struct omap_video_timings){640, 480, 25175, 96, 16, 48, 2 , 11, 31}; | 49 | false, |
50 | }; | ||
50 | 51 | ||
51 | DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", | 52 | DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", |
52 | dssdev->panel.timings.x_res, | 53 | dssdev->panel.timings.x_res, |
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 0cbcde4c688a..53710fadc82d 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c | |||
@@ -500,16 +500,12 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) | |||
500 | if (r) | 500 | if (r) |
501 | return r; | 501 | return r; |
502 | 502 | ||
503 | if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { | 503 | if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) |
504 | irq = DISPC_IRQ_EVSYNC_ODD; | 504 | irq = DISPC_IRQ_EVSYNC_ODD; |
505 | } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) { | 505 | else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) |
506 | irq = DISPC_IRQ_EVSYNC_EVEN; | 506 | irq = DISPC_IRQ_EVSYNC_EVEN; |
507 | } else { | 507 | else |
508 | if (mgr->id == OMAP_DSS_CHANNEL_LCD) | 508 | irq = dispc_mgr_get_vsync_irq(mgr->id); |
509 | irq = DISPC_IRQ_VSYNC; | ||
510 | else | ||
511 | irq = DISPC_IRQ_VSYNC2; | ||
512 | } | ||
513 | 509 | ||
514 | r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); | 510 | r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); |
515 | 511 | ||
@@ -545,6 +541,10 @@ int dss_init_overlay_managers(struct platform_device *pdev) | |||
545 | mgr->name = "lcd2"; | 541 | mgr->name = "lcd2"; |
546 | mgr->id = OMAP_DSS_CHANNEL_LCD2; | 542 | mgr->id = OMAP_DSS_CHANNEL_LCD2; |
547 | break; | 543 | break; |
544 | case 3: | ||
545 | mgr->name = "lcd3"; | ||
546 | mgr->id = OMAP_DSS_CHANNEL_LCD3; | ||
547 | break; | ||
548 | } | 548 | } |
549 | 549 | ||
550 | mgr->set_device = &dss_mgr_set_device; | 550 | mgr->set_device = &dss_mgr_set_device; |
@@ -665,9 +665,40 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr, | |||
665 | return 0; | 665 | return 0; |
666 | } | 666 | } |
667 | 667 | ||
668 | static int dss_mgr_check_lcd_config(struct omap_overlay_manager *mgr, | ||
669 | const struct dss_lcd_mgr_config *config) | ||
670 | { | ||
671 | struct dispc_clock_info cinfo = config->clock_info; | ||
672 | int dl = config->video_port_width; | ||
673 | bool stallmode = config->stallmode; | ||
674 | bool fifohandcheck = config->fifohandcheck; | ||
675 | |||
676 | if (cinfo.lck_div < 1 || cinfo.lck_div > 255) | ||
677 | return -EINVAL; | ||
678 | |||
679 | if (cinfo.pck_div < 1 || cinfo.pck_div > 255) | ||
680 | return -EINVAL; | ||
681 | |||
682 | if (dl != 12 && dl != 16 && dl != 18 && dl != 24) | ||
683 | return -EINVAL; | ||
684 | |||
685 | /* fifohandcheck should be used only with stallmode */ | ||
686 | if (stallmode == false && fifohandcheck == true) | ||
687 | return -EINVAL; | ||
688 | |||
689 | /* | ||
690 | * io pad mode can be only checked by using dssdev connected to the | ||
691 | * manager. Ignore checking these for now, add checks when manager | ||
692 | * is capable of holding information related to the connected interface | ||
693 | */ | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
668 | int dss_mgr_check(struct omap_overlay_manager *mgr, | 698 | int dss_mgr_check(struct omap_overlay_manager *mgr, |
669 | struct omap_overlay_manager_info *info, | 699 | struct omap_overlay_manager_info *info, |
670 | const struct omap_video_timings *mgr_timings, | 700 | const struct omap_video_timings *mgr_timings, |
701 | const struct dss_lcd_mgr_config *lcd_config, | ||
671 | struct omap_overlay_info **overlay_infos) | 702 | struct omap_overlay_info **overlay_infos) |
672 | { | 703 | { |
673 | struct omap_overlay *ovl; | 704 | struct omap_overlay *ovl; |
@@ -683,6 +714,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr, | |||
683 | if (r) | 714 | if (r) |
684 | return r; | 715 | return r; |
685 | 716 | ||
717 | r = dss_mgr_check_lcd_config(mgr, lcd_config); | ||
718 | if (r) | ||
719 | return r; | ||
720 | |||
686 | list_for_each_entry(ovl, &mgr->overlays, list) { | 721 | list_for_each_entry(ovl, &mgr->overlays, list) { |
687 | struct omap_overlay_info *oi; | 722 | struct omap_overlay_info *oi; |
688 | int r; | 723 | int r; |
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index b0ba60f88dd2..952c6fad9a81 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c | |||
@@ -528,14 +528,24 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) | |||
528 | struct omap_overlay_manager *lcd_mgr; | 528 | struct omap_overlay_manager *lcd_mgr; |
529 | struct omap_overlay_manager *tv_mgr; | 529 | struct omap_overlay_manager *tv_mgr; |
530 | struct omap_overlay_manager *lcd2_mgr = NULL; | 530 | struct omap_overlay_manager *lcd2_mgr = NULL; |
531 | struct omap_overlay_manager *lcd3_mgr = NULL; | ||
531 | struct omap_overlay_manager *mgr = NULL; | 532 | struct omap_overlay_manager *mgr = NULL; |
532 | 533 | ||
533 | lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); | 534 | lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD); |
534 | tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); | 535 | tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT); |
536 | if (dss_has_feature(FEAT_MGR_LCD3)) | ||
537 | lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3); | ||
535 | if (dss_has_feature(FEAT_MGR_LCD2)) | 538 | if (dss_has_feature(FEAT_MGR_LCD2)) |
536 | lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2); | 539 | lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2); |
537 | 540 | ||
538 | if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { | 541 | if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) { |
542 | if (!lcd3_mgr->device || force) { | ||
543 | if (lcd3_mgr->device) | ||
544 | lcd3_mgr->unset_device(lcd3_mgr); | ||
545 | lcd3_mgr->set_device(lcd3_mgr, dssdev); | ||
546 | mgr = lcd3_mgr; | ||
547 | } | ||
548 | } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { | ||
539 | if (!lcd2_mgr->device || force) { | 549 | if (!lcd2_mgr->device || force) { |
540 | if (lcd2_mgr->device) | 550 | if (lcd2_mgr->device) |
541 | lcd2_mgr->unset_device(lcd2_mgr); | 551 | lcd2_mgr->unset_device(lcd2_mgr); |
@@ -677,3 +687,16 @@ int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, | |||
677 | 687 | ||
678 | return 0; | 688 | return 0; |
679 | } | 689 | } |
690 | |||
691 | /* | ||
692 | * Checks if replication logic should be used. Only use when overlay is in | ||
693 | * RGB12U or RGB16 mode, and video port width interface is 18bpp or 24bpp | ||
694 | */ | ||
695 | bool dss_ovl_use_replication(struct dss_lcd_mgr_config config, | ||
696 | enum omap_color_mode mode) | ||
697 | { | ||
698 | if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16) | ||
699 | return false; | ||
700 | |||
701 | return config.video_port_width > 16; | ||
702 | } | ||
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 7985fa12b9b4..7c087424b634 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c | |||
@@ -300,10 +300,11 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, | |||
300 | } | 300 | } |
301 | EXPORT_SYMBOL(omap_rfbi_write_pixels); | 301 | EXPORT_SYMBOL(omap_rfbi_write_pixels); |
302 | 302 | ||
303 | static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, | 303 | static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, |
304 | u16 height, void (*callback)(void *data), void *data) | 304 | u16 height, void (*callback)(void *data), void *data) |
305 | { | 305 | { |
306 | u32 l; | 306 | u32 l; |
307 | int r; | ||
307 | struct omap_video_timings timings = { | 308 | struct omap_video_timings timings = { |
308 | .hsw = 1, | 309 | .hsw = 1, |
309 | .hfp = 1, | 310 | .hfp = 1, |
@@ -322,7 +323,9 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, | |||
322 | 323 | ||
323 | dss_mgr_set_timings(dssdev->manager, &timings); | 324 | dss_mgr_set_timings(dssdev->manager, &timings); |
324 | 325 | ||
325 | dispc_mgr_enable(dssdev->manager->id, true); | 326 | r = dss_mgr_enable(dssdev->manager); |
327 | if (r) | ||
328 | return r; | ||
326 | 329 | ||
327 | rfbi.framedone_callback = callback; | 330 | rfbi.framedone_callback = callback; |
328 | rfbi.framedone_callback_data = data; | 331 | rfbi.framedone_callback_data = data; |
@@ -335,6 +338,8 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, | |||
335 | l = FLD_MOD(l, 1, 4, 4); /* ITE */ | 338 | l = FLD_MOD(l, 1, 4, 4); /* ITE */ |
336 | 339 | ||
337 | rfbi_write_reg(RFBI_CONTROL, l); | 340 | rfbi_write_reg(RFBI_CONTROL, l); |
341 | |||
342 | return 0; | ||
338 | } | 343 | } |
339 | 344 | ||
340 | static void framedone_callback(void *data, u32 mask) | 345 | static void framedone_callback(void *data, u32 mask) |
@@ -814,8 +819,11 @@ int omap_rfbi_update(struct omap_dss_device *dssdev, | |||
814 | u16 x, u16 y, u16 w, u16 h, | 819 | u16 x, u16 y, u16 w, u16 h, |
815 | void (*callback)(void *), void *data) | 820 | void (*callback)(void *), void *data) |
816 | { | 821 | { |
817 | rfbi_transfer_area(dssdev, w, h, callback, data); | 822 | int r; |
818 | return 0; | 823 | |
824 | r = rfbi_transfer_area(dssdev, w, h, callback, data); | ||
825 | |||
826 | return r; | ||
819 | } | 827 | } |
820 | EXPORT_SYMBOL(omap_rfbi_update); | 828 | EXPORT_SYMBOL(omap_rfbi_update); |
821 | 829 | ||
@@ -859,6 +867,22 @@ static void rfbi_dump_regs(struct seq_file *s) | |||
859 | #undef DUMPREG | 867 | #undef DUMPREG |
860 | } | 868 | } |
861 | 869 | ||
870 | static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) | ||
871 | { | ||
872 | struct dss_lcd_mgr_config mgr_config; | ||
873 | |||
874 | mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI; | ||
875 | |||
876 | mgr_config.stallmode = true; | ||
877 | /* Do we need fifohandcheck for RFBI? */ | ||
878 | mgr_config.fifohandcheck = false; | ||
879 | |||
880 | mgr_config.video_port_width = dssdev->ctrl.pixel_size; | ||
881 | mgr_config.lcden_sig_polarity = 0; | ||
882 | |||
883 | dss_mgr_set_lcd_config(dssdev->manager, &mgr_config); | ||
884 | } | ||
885 | |||
862 | int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) | 886 | int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) |
863 | { | 887 | { |
864 | int r; | 888 | int r; |
@@ -885,13 +909,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) | |||
885 | goto err1; | 909 | goto err1; |
886 | } | 910 | } |
887 | 911 | ||
888 | dispc_mgr_set_lcd_display_type(dssdev->manager->id, | 912 | rfbi_config_lcd_manager(dssdev); |
889 | OMAP_DSS_LCD_DISPLAY_TFT); | ||
890 | |||
891 | dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI); | ||
892 | dispc_mgr_enable_stallmode(dssdev->manager->id, true); | ||
893 | |||
894 | dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size); | ||
895 | 913 | ||
896 | rfbi_configure(dssdev->phy.rfbi.channel, | 914 | rfbi_configure(dssdev->phy.rfbi.channel, |
897 | dssdev->ctrl.pixel_size, | 915 | dssdev->ctrl.pixel_size, |
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 3a43dc2a9b46..5d31699fbd3c 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c | |||
@@ -32,19 +32,21 @@ | |||
32 | static struct { | 32 | static struct { |
33 | bool update_enabled; | 33 | bool update_enabled; |
34 | struct regulator *vdds_sdi_reg; | 34 | struct regulator *vdds_sdi_reg; |
35 | } sdi; | ||
36 | 35 | ||
37 | static void sdi_basic_init(struct omap_dss_device *dssdev) | 36 | struct dss_lcd_mgr_config mgr_config; |
37 | } sdi; | ||
38 | 38 | ||
39 | static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) | ||
39 | { | 40 | { |
40 | dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS); | 41 | sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; |
41 | dispc_mgr_enable_stallmode(dssdev->manager->id, false); | 42 | |
43 | sdi.mgr_config.stallmode = false; | ||
44 | sdi.mgr_config.fifohandcheck = false; | ||
42 | 45 | ||
43 | dispc_mgr_set_lcd_display_type(dssdev->manager->id, | 46 | sdi.mgr_config.video_port_width = 24; |
44 | OMAP_DSS_LCD_DISPLAY_TFT); | 47 | sdi.mgr_config.lcden_sig_polarity = 1; |
45 | 48 | ||
46 | dispc_mgr_set_tft_data_lines(dssdev->manager->id, 24); | 49 | dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config); |
47 | dispc_lcd_enable_signal_polarity(1); | ||
48 | } | 50 | } |
49 | 51 | ||
50 | int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | 52 | int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) |
@@ -52,8 +54,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
52 | struct omap_video_timings *t = &dssdev->panel.timings; | 54 | struct omap_video_timings *t = &dssdev->panel.timings; |
53 | struct dss_clock_info dss_cinfo; | 55 | struct dss_clock_info dss_cinfo; |
54 | struct dispc_clock_info dispc_cinfo; | 56 | struct dispc_clock_info dispc_cinfo; |
55 | u16 lck_div, pck_div; | ||
56 | unsigned long fck; | ||
57 | unsigned long pck; | 57 | unsigned long pck; |
58 | int r; | 58 | int r; |
59 | 59 | ||
@@ -76,24 +76,17 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
76 | if (r) | 76 | if (r) |
77 | goto err_get_dispc; | 77 | goto err_get_dispc; |
78 | 78 | ||
79 | sdi_basic_init(dssdev); | ||
80 | |||
81 | /* 15.5.9.1.2 */ | 79 | /* 15.5.9.1.2 */ |
82 | dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF; | 80 | dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; |
83 | 81 | dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | |
84 | dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config, | ||
85 | dssdev->panel.acbi, dssdev->panel.acb); | ||
86 | 82 | ||
87 | r = dss_calc_clock_div(1, t->pixel_clock * 1000, | 83 | r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); |
88 | &dss_cinfo, &dispc_cinfo); | ||
89 | if (r) | 84 | if (r) |
90 | goto err_calc_clock_div; | 85 | goto err_calc_clock_div; |
91 | 86 | ||
92 | fck = dss_cinfo.fck; | 87 | sdi.mgr_config.clock_info = dispc_cinfo; |
93 | lck_div = dispc_cinfo.lck_div; | ||
94 | pck_div = dispc_cinfo.pck_div; | ||
95 | 88 | ||
96 | pck = fck / lck_div / pck_div / 1000; | 89 | pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000; |
97 | 90 | ||
98 | if (pck != t->pixel_clock) { | 91 | if (pck != t->pixel_clock) { |
99 | DSSWARN("Could not find exact pixel clock. Requested %d kHz, " | 92 | DSSWARN("Could not find exact pixel clock. Requested %d kHz, " |
@@ -110,9 +103,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
110 | if (r) | 103 | if (r) |
111 | goto err_set_dss_clock_div; | 104 | goto err_set_dss_clock_div; |
112 | 105 | ||
113 | r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo); | 106 | sdi_config_lcd_manager(dssdev); |
114 | if (r) | ||
115 | goto err_set_dispc_clock_div; | ||
116 | 107 | ||
117 | dss_sdi_init(dssdev->phy.sdi.datapairs); | 108 | dss_sdi_init(dssdev->phy.sdi.datapairs); |
118 | r = dss_sdi_enable(); | 109 | r = dss_sdi_enable(); |
@@ -129,7 +120,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
129 | err_mgr_enable: | 120 | err_mgr_enable: |
130 | dss_sdi_disable(); | 121 | dss_sdi_disable(); |
131 | err_sdi_enable: | 122 | err_sdi_enable: |
132 | err_set_dispc_clock_div: | ||
133 | err_set_dss_clock_div: | 123 | err_set_dss_clock_div: |
134 | err_calc_clock_div: | 124 | err_calc_clock_div: |
135 | dispc_runtime_put(); | 125 | dispc_runtime_put(); |
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h index e734cb444bc7..b046c208cb97 100644 --- a/drivers/video/omap2/dss/ti_hdmi.h +++ b/drivers/video/omap2/dss/ti_hdmi.h | |||
@@ -42,30 +42,13 @@ enum hdmi_clk_refsel { | |||
42 | HDMI_REFSEL_SYSCLK = 3 | 42 | HDMI_REFSEL_SYSCLK = 3 |
43 | }; | 43 | }; |
44 | 44 | ||
45 | /* HDMI timing structure */ | ||
46 | struct hdmi_video_timings { | ||
47 | u16 x_res; | ||
48 | u16 y_res; | ||
49 | /* Unit: KHz */ | ||
50 | u32 pixel_clock; | ||
51 | u16 hsw; | ||
52 | u16 hfp; | ||
53 | u16 hbp; | ||
54 | u16 vsw; | ||
55 | u16 vfp; | ||
56 | u16 vbp; | ||
57 | bool vsync_pol; | ||
58 | bool hsync_pol; | ||
59 | bool interlace; | ||
60 | }; | ||
61 | |||
62 | struct hdmi_cm { | 45 | struct hdmi_cm { |
63 | int code; | 46 | int code; |
64 | int mode; | 47 | int mode; |
65 | }; | 48 | }; |
66 | 49 | ||
67 | struct hdmi_config { | 50 | struct hdmi_config { |
68 | struct hdmi_video_timings timings; | 51 | struct omap_video_timings timings; |
69 | struct hdmi_cm cm; | 52 | struct hdmi_cm cm; |
70 | }; | 53 | }; |
71 | 54 | ||
@@ -177,7 +160,7 @@ struct hdmi_ip_data { | |||
177 | 160 | ||
178 | /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ | 161 | /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ |
179 | int hpd_gpio; | 162 | int hpd_gpio; |
180 | bool phy_tx_enabled; | 163 | struct mutex lock; |
181 | }; | 164 | }; |
182 | int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); | 165 | int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); |
183 | void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); | 166 | void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); |
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index 4dae1b291079..c23b85a20cdc 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | |||
@@ -157,6 +157,10 @@ static int hdmi_pll_init(struct hdmi_ip_data *ip_data) | |||
157 | /* PHY_PWR_CMD */ | 157 | /* PHY_PWR_CMD */ |
158 | static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val) | 158 | static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val) |
159 | { | 159 | { |
160 | /* Return if already the state */ | ||
161 | if (REG_GET(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, 5, 4) == val) | ||
162 | return 0; | ||
163 | |||
160 | /* Command for power control of HDMI PHY */ | 164 | /* Command for power control of HDMI PHY */ |
161 | REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6); | 165 | REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6); |
162 | 166 | ||
@@ -231,21 +235,13 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data) | |||
231 | 235 | ||
232 | static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data) | 236 | static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data) |
233 | { | 237 | { |
234 | unsigned long flags; | ||
235 | bool hpd; | 238 | bool hpd; |
236 | int r; | 239 | int r; |
237 | /* this should be in ti_hdmi_4xxx_ip private data */ | ||
238 | static DEFINE_SPINLOCK(phy_tx_lock); | ||
239 | 240 | ||
240 | spin_lock_irqsave(&phy_tx_lock, flags); | 241 | mutex_lock(&ip_data->lock); |
241 | 242 | ||
242 | hpd = gpio_get_value(ip_data->hpd_gpio); | 243 | hpd = gpio_get_value(ip_data->hpd_gpio); |
243 | 244 | ||
244 | if (hpd == ip_data->phy_tx_enabled) { | ||
245 | spin_unlock_irqrestore(&phy_tx_lock, flags); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | if (hpd) | 245 | if (hpd) |
250 | r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); | 246 | r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); |
251 | else | 247 | else |
@@ -257,9 +253,8 @@ static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data) | |||
257 | goto err; | 253 | goto err; |
258 | } | 254 | } |
259 | 255 | ||
260 | ip_data->phy_tx_enabled = hpd; | ||
261 | err: | 256 | err: |
262 | spin_unlock_irqrestore(&phy_tx_lock, flags); | 257 | mutex_unlock(&ip_data->lock); |
263 | return r; | 258 | return r; |
264 | } | 259 | } |
265 | 260 | ||
@@ -327,7 +322,6 @@ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) | |||
327 | free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data); | 322 | free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data); |
328 | 323 | ||
329 | hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); | 324 | hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); |
330 | ip_data->phy_tx_enabled = false; | ||
331 | } | 325 | } |
332 | 326 | ||
333 | static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) | 327 | static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) |
@@ -747,11 +741,15 @@ static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, | |||
747 | static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) | 741 | static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) |
748 | { | 742 | { |
749 | u32 r; | 743 | u32 r; |
744 | bool vsync_pol, hsync_pol; | ||
750 | pr_debug("Enter hdmi_wp_video_config_interface\n"); | 745 | pr_debug("Enter hdmi_wp_video_config_interface\n"); |
751 | 746 | ||
747 | vsync_pol = ip_data->cfg.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; | ||
748 | hsync_pol = ip_data->cfg.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; | ||
749 | |||
752 | r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); | 750 | r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); |
753 | r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7); | 751 | r = FLD_MOD(r, vsync_pol, 7, 7); |
754 | r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6); | 752 | r = FLD_MOD(r, hsync_pol, 6, 6); |
755 | r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); | 753 | r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); |
756 | r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ | 754 | r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ |
757 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); | 755 | hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); |
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 3907c8b6ecbc..3a220877461a 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c | |||
@@ -272,6 +272,8 @@ const struct omap_video_timings omap_dss_pal_timings = { | |||
272 | .vsw = 5, | 272 | .vsw = 5, |
273 | .vfp = 5, | 273 | .vfp = 5, |
274 | .vbp = 41, | 274 | .vbp = 41, |
275 | |||
276 | .interlace = true, | ||
275 | }; | 277 | }; |
276 | EXPORT_SYMBOL(omap_dss_pal_timings); | 278 | EXPORT_SYMBOL(omap_dss_pal_timings); |
277 | 279 | ||
@@ -285,6 +287,8 @@ const struct omap_video_timings omap_dss_ntsc_timings = { | |||
285 | .vsw = 6, | 287 | .vsw = 6, |
286 | .vfp = 6, | 288 | .vfp = 6, |
287 | .vbp = 31, | 289 | .vbp = 31, |
290 | |||
291 | .interlace = true, | ||
288 | }; | 292 | }; |
289 | EXPORT_SYMBOL(omap_dss_ntsc_timings); | 293 | EXPORT_SYMBOL(omap_dss_ntsc_timings); |
290 | 294 | ||
@@ -930,7 +934,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev) | |||
930 | static int venc_runtime_suspend(struct device *dev) | 934 | static int venc_runtime_suspend(struct device *dev) |
931 | { | 935 | { |
932 | if (venc.tv_dac_clk) | 936 | if (venc.tv_dac_clk) |
933 | clk_disable(venc.tv_dac_clk); | 937 | clk_disable_unprepare(venc.tv_dac_clk); |
934 | 938 | ||
935 | dispc_runtime_put(); | 939 | dispc_runtime_put(); |
936 | 940 | ||
@@ -946,7 +950,7 @@ static int venc_runtime_resume(struct device *dev) | |||
946 | return r; | 950 | return r; |
947 | 951 | ||
948 | if (venc.tv_dac_clk) | 952 | if (venc.tv_dac_clk) |
949 | clk_enable(venc.tv_dac_clk); | 953 | clk_prepare_enable(venc.tv_dac_clk); |
950 | 954 | ||
951 | return 0; | 955 | return 0; |
952 | } | 956 | } |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 3450ea0966c9..08ec1a7103f2 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
@@ -733,6 +733,12 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) | |||
733 | var->lower_margin = timings.vfp; | 733 | var->lower_margin = timings.vfp; |
734 | var->hsync_len = timings.hsw; | 734 | var->hsync_len = timings.hsw; |
735 | var->vsync_len = timings.vsw; | 735 | var->vsync_len = timings.vsw; |
736 | var->sync |= timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH ? | ||
737 | FB_SYNC_HOR_HIGH_ACT : 0; | ||
738 | var->sync |= timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH ? | ||
739 | FB_SYNC_VERT_HIGH_ACT : 0; | ||
740 | var->vmode = timings.interlace ? | ||
741 | FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED; | ||
736 | } else { | 742 | } else { |
737 | var->pixclock = 0; | 743 | var->pixclock = 0; |
738 | var->left_margin = 0; | 744 | var->left_margin = 0; |
@@ -741,12 +747,10 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) | |||
741 | var->lower_margin = 0; | 747 | var->lower_margin = 0; |
742 | var->hsync_len = 0; | 748 | var->hsync_len = 0; |
743 | var->vsync_len = 0; | 749 | var->vsync_len = 0; |
750 | var->sync = 0; | ||
751 | var->vmode = FB_VMODE_NONINTERLACED; | ||
744 | } | 752 | } |
745 | 753 | ||
746 | /* TODO: get these from panel->config */ | ||
747 | var->vmode = FB_VMODE_NONINTERLACED; | ||
748 | var->sync = 0; | ||
749 | |||
750 | return 0; | 754 | return 0; |
751 | } | 755 | } |
752 | 756 | ||
@@ -1993,6 +1997,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) | |||
1993 | } | 1997 | } |
1994 | 1998 | ||
1995 | static int omapfb_mode_to_timings(const char *mode_str, | 1999 | static int omapfb_mode_to_timings(const char *mode_str, |
2000 | struct omap_dss_device *display, | ||
1996 | struct omap_video_timings *timings, u8 *bpp) | 2001 | struct omap_video_timings *timings, u8 *bpp) |
1997 | { | 2002 | { |
1998 | struct fb_info *fbi; | 2003 | struct fb_info *fbi; |
@@ -2046,6 +2051,14 @@ static int omapfb_mode_to_timings(const char *mode_str, | |||
2046 | goto err; | 2051 | goto err; |
2047 | } | 2052 | } |
2048 | 2053 | ||
2054 | if (display->driver->get_timings) { | ||
2055 | display->driver->get_timings(display, timings); | ||
2056 | } else { | ||
2057 | timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | ||
2058 | timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
2059 | timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | ||
2060 | } | ||
2061 | |||
2049 | timings->pixel_clock = PICOS2KHZ(var->pixclock); | 2062 | timings->pixel_clock = PICOS2KHZ(var->pixclock); |
2050 | timings->hbp = var->left_margin; | 2063 | timings->hbp = var->left_margin; |
2051 | timings->hfp = var->right_margin; | 2064 | timings->hfp = var->right_margin; |
@@ -2055,6 +2068,13 @@ static int omapfb_mode_to_timings(const char *mode_str, | |||
2055 | timings->vsw = var->vsync_len; | 2068 | timings->vsw = var->vsync_len; |
2056 | timings->x_res = var->xres; | 2069 | timings->x_res = var->xres; |
2057 | timings->y_res = var->yres; | 2070 | timings->y_res = var->yres; |
2071 | timings->hsync_level = var->sync & FB_SYNC_HOR_HIGH_ACT ? | ||
2072 | OMAPDSS_SIG_ACTIVE_HIGH : | ||
2073 | OMAPDSS_SIG_ACTIVE_LOW; | ||
2074 | timings->vsync_level = var->sync & FB_SYNC_VERT_HIGH_ACT ? | ||
2075 | OMAPDSS_SIG_ACTIVE_HIGH : | ||
2076 | OMAPDSS_SIG_ACTIVE_LOW; | ||
2077 | timings->interlace = var->vmode & FB_VMODE_INTERLACED; | ||
2058 | 2078 | ||
2059 | switch (var->bits_per_pixel) { | 2079 | switch (var->bits_per_pixel) { |
2060 | case 16: | 2080 | case 16: |
@@ -2085,7 +2105,7 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev, | |||
2085 | struct omap_video_timings timings, temp_timings; | 2105 | struct omap_video_timings timings, temp_timings; |
2086 | struct omapfb_display_data *d; | 2106 | struct omapfb_display_data *d; |
2087 | 2107 | ||
2088 | r = omapfb_mode_to_timings(mode_str, &timings, &bpp); | 2108 | r = omapfb_mode_to_timings(mode_str, display, &timings, &bpp); |
2089 | if (r) | 2109 | if (r) |
2090 | return r; | 2110 | return r; |
2091 | 2111 | ||
@@ -2178,8 +2198,17 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) | |||
2178 | } | 2198 | } |
2179 | 2199 | ||
2180 | static void fb_videomode_to_omap_timings(struct fb_videomode *m, | 2200 | static void fb_videomode_to_omap_timings(struct fb_videomode *m, |
2201 | struct omap_dss_device *display, | ||
2181 | struct omap_video_timings *t) | 2202 | struct omap_video_timings *t) |
2182 | { | 2203 | { |
2204 | if (display->driver->get_timings) { | ||
2205 | display->driver->get_timings(display, t); | ||
2206 | } else { | ||
2207 | t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | ||
2208 | t->de_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
2209 | t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | ||
2210 | } | ||
2211 | |||
2183 | t->x_res = m->xres; | 2212 | t->x_res = m->xres; |
2184 | t->y_res = m->yres; | 2213 | t->y_res = m->yres; |
2185 | t->pixel_clock = PICOS2KHZ(m->pixclock); | 2214 | t->pixel_clock = PICOS2KHZ(m->pixclock); |
@@ -2189,6 +2218,13 @@ static void fb_videomode_to_omap_timings(struct fb_videomode *m, | |||
2189 | t->vsw = m->vsync_len; | 2218 | t->vsw = m->vsync_len; |
2190 | t->vfp = m->lower_margin; | 2219 | t->vfp = m->lower_margin; |
2191 | t->vbp = m->upper_margin; | 2220 | t->vbp = m->upper_margin; |
2221 | t->hsync_level = m->sync & FB_SYNC_HOR_HIGH_ACT ? | ||
2222 | OMAPDSS_SIG_ACTIVE_HIGH : | ||
2223 | OMAPDSS_SIG_ACTIVE_LOW; | ||
2224 | t->vsync_level = m->sync & FB_SYNC_VERT_HIGH_ACT ? | ||
2225 | OMAPDSS_SIG_ACTIVE_HIGH : | ||
2226 | OMAPDSS_SIG_ACTIVE_LOW; | ||
2227 | t->interlace = m->vmode & FB_VMODE_INTERLACED; | ||
2192 | } | 2228 | } |
2193 | 2229 | ||
2194 | static int omapfb_find_best_mode(struct omap_dss_device *display, | 2230 | static int omapfb_find_best_mode(struct omap_dss_device *display, |
@@ -2231,7 +2267,7 @@ static int omapfb_find_best_mode(struct omap_dss_device *display, | |||
2231 | if (m->xres == 2880 || m->xres == 1440) | 2267 | if (m->xres == 2880 || m->xres == 1440) |
2232 | continue; | 2268 | continue; |
2233 | 2269 | ||
2234 | fb_videomode_to_omap_timings(m, &t); | 2270 | fb_videomode_to_omap_timings(m, display, &t); |
2235 | 2271 | ||
2236 | r = display->driver->check_timings(display, &t); | 2272 | r = display->driver->check_timings(display, &t); |
2237 | if (r == 0 && best_xres < m->xres) { | 2273 | if (r == 0 && best_xres < m->xres) { |
@@ -2245,7 +2281,8 @@ static int omapfb_find_best_mode(struct omap_dss_device *display, | |||
2245 | goto err2; | 2281 | goto err2; |
2246 | } | 2282 | } |
2247 | 2283 | ||
2248 | fb_videomode_to_omap_timings(&specs->modedb[best_idx], timings); | 2284 | fb_videomode_to_omap_timings(&specs->modedb[best_idx], display, |
2285 | timings); | ||
2249 | 2286 | ||
2250 | r = 0; | 2287 | r = 0; |
2251 | 2288 | ||
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index 2c80246b18b8..1d007366b917 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c | |||
@@ -84,7 +84,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", | |||
84 | "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", | 84 | "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", |
85 | "S3 Virge/GX2", "S3 Virge/GX2+", "", | 85 | "S3 Virge/GX2", "S3 Virge/GX2+", "", |
86 | "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X", | 86 | "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X", |
87 | "S3 Trio3D"}; | 87 | "S3 Trio3D", "S3 Virge/MX"}; |
88 | 88 | ||
89 | #define CHIP_UNKNOWN 0x00 | 89 | #define CHIP_UNKNOWN 0x00 |
90 | #define CHIP_732_TRIO32 0x01 | 90 | #define CHIP_732_TRIO32 0x01 |
@@ -105,6 +105,7 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", | |||
105 | #define CHIP_362_TRIO3D_2X 0x11 | 105 | #define CHIP_362_TRIO3D_2X 0x11 |
106 | #define CHIP_368_TRIO3D_2X 0x12 | 106 | #define CHIP_368_TRIO3D_2X 0x12 |
107 | #define CHIP_365_TRIO3D 0x13 | 107 | #define CHIP_365_TRIO3D 0x13 |
108 | #define CHIP_260_VIRGE_MX 0x14 | ||
108 | 109 | ||
109 | #define CHIP_XXX_TRIO 0x80 | 110 | #define CHIP_XXX_TRIO 0x80 |
110 | #define CHIP_XXX_TRIO64V2_DXGX 0x81 | 111 | #define CHIP_XXX_TRIO64V2_DXGX 0x81 |
@@ -280,7 +281,8 @@ static int __devinit s3fb_setup_ddc_bus(struct fb_info *info) | |||
280 | */ | 281 | */ |
281 | /* vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */ | 282 | /* vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */ |
282 | if (par->chip == CHIP_357_VIRGE_GX2 || | 283 | if (par->chip == CHIP_357_VIRGE_GX2 || |
283 | par->chip == CHIP_359_VIRGE_GX2P) | 284 | par->chip == CHIP_359_VIRGE_GX2P || |
285 | par->chip == CHIP_260_VIRGE_MX) | ||
284 | svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03); | 286 | svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03); |
285 | else | 287 | else |
286 | svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03); | 288 | svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03); |
@@ -487,7 +489,8 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock) | |||
487 | par->chip == CHIP_359_VIRGE_GX2P || | 489 | par->chip == CHIP_359_VIRGE_GX2P || |
488 | par->chip == CHIP_360_TRIO3D_1X || | 490 | par->chip == CHIP_360_TRIO3D_1X || |
489 | par->chip == CHIP_362_TRIO3D_2X || | 491 | par->chip == CHIP_362_TRIO3D_2X || |
490 | par->chip == CHIP_368_TRIO3D_2X) { | 492 | par->chip == CHIP_368_TRIO3D_2X || |
493 | par->chip == CHIP_260_VIRGE_MX) { | ||
491 | vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ | 494 | vga_wseq(par->state.vgabase, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ |
492 | vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */ | 495 | vga_wseq(par->state.vgabase, 0x29, r >> 2); /* remaining highest bit of r */ |
493 | } else | 496 | } else |
@@ -690,7 +693,8 @@ static int s3fb_set_par(struct fb_info *info) | |||
690 | par->chip != CHIP_359_VIRGE_GX2P && | 693 | par->chip != CHIP_359_VIRGE_GX2P && |
691 | par->chip != CHIP_360_TRIO3D_1X && | 694 | par->chip != CHIP_360_TRIO3D_1X && |
692 | par->chip != CHIP_362_TRIO3D_2X && | 695 | par->chip != CHIP_362_TRIO3D_2X && |
693 | par->chip != CHIP_368_TRIO3D_2X) { | 696 | par->chip != CHIP_368_TRIO3D_2X && |
697 | par->chip != CHIP_260_VIRGE_MX) { | ||
694 | vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */ | 698 | vga_wcrt(par->state.vgabase, 0x54, 0x18); /* M parameter */ |
695 | vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */ | 699 | vga_wcrt(par->state.vgabase, 0x60, 0xff); /* N parameter */ |
696 | vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */ | 700 | vga_wcrt(par->state.vgabase, 0x61, 0xff); /* L parameter */ |
@@ -739,7 +743,8 @@ static int s3fb_set_par(struct fb_info *info) | |||
739 | par->chip == CHIP_368_TRIO3D_2X || | 743 | par->chip == CHIP_368_TRIO3D_2X || |
740 | par->chip == CHIP_365_TRIO3D || | 744 | par->chip == CHIP_365_TRIO3D || |
741 | par->chip == CHIP_375_VIRGE_DX || | 745 | par->chip == CHIP_375_VIRGE_DX || |
742 | par->chip == CHIP_385_VIRGE_GX) { | 746 | par->chip == CHIP_385_VIRGE_GX || |
747 | par->chip == CHIP_260_VIRGE_MX) { | ||
743 | dbytes = info->var.xres * ((bpp+7)/8); | 748 | dbytes = info->var.xres * ((bpp+7)/8); |
744 | vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8); | 749 | vga_wcrt(par->state.vgabase, 0x91, (dbytes + 7) / 8); |
745 | vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); | 750 | vga_wcrt(par->state.vgabase, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); |
@@ -751,7 +756,8 @@ static int s3fb_set_par(struct fb_info *info) | |||
751 | par->chip == CHIP_359_VIRGE_GX2P || | 756 | par->chip == CHIP_359_VIRGE_GX2P || |
752 | par->chip == CHIP_360_TRIO3D_1X || | 757 | par->chip == CHIP_360_TRIO3D_1X || |
753 | par->chip == CHIP_362_TRIO3D_2X || | 758 | par->chip == CHIP_362_TRIO3D_2X || |
754 | par->chip == CHIP_368_TRIO3D_2X) | 759 | par->chip == CHIP_368_TRIO3D_2X || |
760 | par->chip == CHIP_260_VIRGE_MX) | ||
755 | vga_wcrt(par->state.vgabase, 0x34, 0x00); | 761 | vga_wcrt(par->state.vgabase, 0x34, 0x00); |
756 | else /* enable Data Transfer Position Control (DTPC) */ | 762 | else /* enable Data Transfer Position Control (DTPC) */ |
757 | vga_wcrt(par->state.vgabase, 0x34, 0x10); | 763 | vga_wcrt(par->state.vgabase, 0x34, 0x10); |
@@ -807,7 +813,8 @@ static int s3fb_set_par(struct fb_info *info) | |||
807 | par->chip == CHIP_359_VIRGE_GX2P || | 813 | par->chip == CHIP_359_VIRGE_GX2P || |
808 | par->chip == CHIP_360_TRIO3D_1X || | 814 | par->chip == CHIP_360_TRIO3D_1X || |
809 | par->chip == CHIP_362_TRIO3D_2X || | 815 | par->chip == CHIP_362_TRIO3D_2X || |
810 | par->chip == CHIP_368_TRIO3D_2X) | 816 | par->chip == CHIP_368_TRIO3D_2X || |
817 | par->chip == CHIP_260_VIRGE_MX) | ||
811 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); | 818 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x00, 0xF0); |
812 | else { | 819 | else { |
813 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0); | 820 | svga_wcrt_mask(par->state.vgabase, 0x67, 0x10, 0xF0); |
@@ -837,7 +844,8 @@ static int s3fb_set_par(struct fb_info *info) | |||
837 | par->chip != CHIP_359_VIRGE_GX2P && | 844 | par->chip != CHIP_359_VIRGE_GX2P && |
838 | par->chip != CHIP_360_TRIO3D_1X && | 845 | par->chip != CHIP_360_TRIO3D_1X && |
839 | par->chip != CHIP_362_TRIO3D_2X && | 846 | par->chip != CHIP_362_TRIO3D_2X && |
840 | par->chip != CHIP_368_TRIO3D_2X) | 847 | par->chip != CHIP_368_TRIO3D_2X && |
848 | par->chip != CHIP_260_VIRGE_MX) | ||
841 | hmul = 2; | 849 | hmul = 2; |
842 | } | 850 | } |
843 | break; | 851 | break; |
@@ -864,7 +872,8 @@ static int s3fb_set_par(struct fb_info *info) | |||
864 | par->chip != CHIP_359_VIRGE_GX2P && | 872 | par->chip != CHIP_359_VIRGE_GX2P && |
865 | par->chip != CHIP_360_TRIO3D_1X && | 873 | par->chip != CHIP_360_TRIO3D_1X && |
866 | par->chip != CHIP_362_TRIO3D_2X && | 874 | par->chip != CHIP_362_TRIO3D_2X && |
867 | par->chip != CHIP_368_TRIO3D_2X) | 875 | par->chip != CHIP_368_TRIO3D_2X && |
876 | par->chip != CHIP_260_VIRGE_MX) | ||
868 | hmul = 2; | 877 | hmul = 2; |
869 | } | 878 | } |
870 | break; | 879 | break; |
@@ -1208,7 +1217,8 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i | |||
1208 | break; | 1217 | break; |
1209 | } | 1218 | } |
1210 | } else if (par->chip == CHIP_357_VIRGE_GX2 || | 1219 | } else if (par->chip == CHIP_357_VIRGE_GX2 || |
1211 | par->chip == CHIP_359_VIRGE_GX2P) { | 1220 | par->chip == CHIP_359_VIRGE_GX2P || |
1221 | par->chip == CHIP_260_VIRGE_MX) { | ||
1212 | switch ((regval & 0xC0) >> 6) { | 1222 | switch ((regval & 0xC0) >> 6) { |
1213 | case 1: /* 4MB */ | 1223 | case 1: /* 4MB */ |
1214 | info->screen_size = 4 << 20; | 1224 | info->screen_size = 4 << 20; |
@@ -1515,6 +1525,7 @@ static struct pci_device_id s3_devices[] __devinitdata = { | |||
1515 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, | 1525 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, |
1516 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, | 1526 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, |
1517 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D}, | 1527 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8904), .driver_data = CHIP_365_TRIO3D}, |
1528 | {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8C01), .driver_data = CHIP_260_VIRGE_MX}, | ||
1518 | 1529 | ||
1519 | {0, 0, 0, 0, 0, 0, 0} | 1530 | {0, 0, 0, 0, 0, 0, 0} |
1520 | }; | 1531 | }; |
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 4c6b84488561..3951fdae5f68 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c | |||
@@ -127,8 +127,7 @@ static void sh_mipi_shutdown(struct platform_device *pdev) | |||
127 | sh_mipi_dsi_enable(mipi, false); | 127 | sh_mipi_dsi_enable(mipi, false); |
128 | } | 128 | } |
129 | 129 | ||
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/smscufx.c b/drivers/video/smscufx.c index 26f864289498..5533a32c6ca1 100644 --- a/drivers/video/smscufx.c +++ b/drivers/video/smscufx.c | |||
@@ -904,7 +904,7 @@ static ssize_t ufx_ops_write(struct fb_info *info, const char __user *buf, | |||
904 | result = fb_sys_write(info, buf, count, ppos); | 904 | result = fb_sys_write(info, buf, count, ppos); |
905 | 905 | ||
906 | if (result > 0) { | 906 | if (result > 0) { |
907 | int start = max((int)(offset / info->fix.line_length) - 1, 0); | 907 | int start = max((int)(offset / info->fix.line_length), 0); |
908 | int lines = min((u32)((result / info->fix.line_length) + 1), | 908 | int lines = min((u32)((result / info->fix.line_length) + 1), |
909 | (u32)info->var.yres); | 909 | (u32)info->var.yres); |
910 | 910 | ||
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index 90a2e30272ad..2f6b2b835f88 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c | |||
@@ -1567,6 +1567,18 @@ static void w100_suspend(u32 mode) | |||
1567 | val = readl(remapped_regs + mmPLL_CNTL); | 1567 | val = readl(remapped_regs + mmPLL_CNTL); |
1568 | val |= 0x00000004; /* bit2=1 */ | 1568 | val |= 0x00000004; /* bit2=1 */ |
1569 | writel(val, remapped_regs + mmPLL_CNTL); | 1569 | writel(val, remapped_regs + mmPLL_CNTL); |
1570 | |||
1571 | writel(0x00000000, remapped_regs + mmLCDD_CNTL1); | ||
1572 | writel(0x00000000, remapped_regs + mmLCDD_CNTL2); | ||
1573 | writel(0x00000000, remapped_regs + mmGENLCD_CNTL1); | ||
1574 | writel(0x00000000, remapped_regs + mmGENLCD_CNTL2); | ||
1575 | writel(0x00000000, remapped_regs + mmGENLCD_CNTL3); | ||
1576 | |||
1577 | val = readl(remapped_regs + mmMEM_EXT_CNTL); | ||
1578 | val |= 0xF0000000; | ||
1579 | val &= ~(0x00000001); | ||
1580 | writel(val, remapped_regs + mmMEM_EXT_CNTL); | ||
1581 | |||
1570 | writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL); | 1582 | writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL); |
1571 | } | 1583 | } |
1572 | } | 1584 | } |
diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h index 89d43b3d4cb9..5a0e4f9efb53 100644 --- a/include/video/da8xx-fb.h +++ b/include/video/da8xx-fb.h | |||
@@ -82,6 +82,9 @@ struct lcd_ctrl_config { | |||
82 | 82 | ||
83 | /* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */ | 83 | /* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */ |
84 | unsigned char raster_order; | 84 | unsigned char raster_order; |
85 | |||
86 | /* DMA FIFO threshold */ | ||
87 | int fifo_th; | ||
85 | }; | 88 | }; |
86 | 89 | ||
87 | struct lcd_sync_arg { | 90 | struct lcd_sync_arg { |
diff --git a/include/video/omapdss.h b/include/video/omapdss.h index c8e59b4a3364..a6267a2d292b 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h | |||
@@ -48,6 +48,10 @@ | |||
48 | #define DISPC_IRQ_FRAMEDONEWB (1 << 23) | 48 | #define DISPC_IRQ_FRAMEDONEWB (1 << 23) |
49 | #define DISPC_IRQ_FRAMEDONETV (1 << 24) | 49 | #define DISPC_IRQ_FRAMEDONETV (1 << 24) |
50 | #define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25) | 50 | #define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25) |
51 | #define DISPC_IRQ_FRAMEDONE3 (1 << 26) | ||
52 | #define DISPC_IRQ_VSYNC3 (1 << 27) | ||
53 | #define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 28) | ||
54 | #define DISPC_IRQ_SYNC_LOST3 (1 << 29) | ||
51 | 55 | ||
52 | struct omap_dss_device; | 56 | struct omap_dss_device; |
53 | struct omap_overlay_manager; | 57 | struct omap_overlay_manager; |
@@ -75,6 +79,7 @@ enum omap_channel { | |||
75 | OMAP_DSS_CHANNEL_LCD = 0, | 79 | OMAP_DSS_CHANNEL_LCD = 0, |
76 | OMAP_DSS_CHANNEL_DIGIT = 1, | 80 | OMAP_DSS_CHANNEL_DIGIT = 1, |
77 | OMAP_DSS_CHANNEL_LCD2 = 2, | 81 | OMAP_DSS_CHANNEL_LCD2 = 2, |
82 | OMAP_DSS_CHANNEL_LCD3 = 3, | ||
78 | }; | 83 | }; |
79 | 84 | ||
80 | enum omap_color_mode { | 85 | enum omap_color_mode { |
@@ -99,11 +104,6 @@ enum omap_color_mode { | |||
99 | OMAP_DSS_COLOR_XRGB16_1555 = 1 << 18, /* xRGB16 - 1555 */ | 104 | OMAP_DSS_COLOR_XRGB16_1555 = 1 << 18, /* xRGB16 - 1555 */ |
100 | }; | 105 | }; |
101 | 106 | ||
102 | enum omap_lcd_display_type { | ||
103 | OMAP_DSS_LCD_DISPLAY_STN, | ||
104 | OMAP_DSS_LCD_DISPLAY_TFT, | ||
105 | }; | ||
106 | |||
107 | enum omap_dss_load_mode { | 107 | enum omap_dss_load_mode { |
108 | OMAP_DSS_LOAD_CLUT_AND_FRAME = 0, | 108 | OMAP_DSS_LOAD_CLUT_AND_FRAME = 0, |
109 | OMAP_DSS_LOAD_CLUT_ONLY = 1, | 109 | OMAP_DSS_LOAD_CLUT_ONLY = 1, |
@@ -121,15 +121,15 @@ enum omap_rfbi_te_mode { | |||
121 | OMAP_DSS_RFBI_TE_MODE_2 = 2, | 121 | OMAP_DSS_RFBI_TE_MODE_2 = 2, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | enum omap_panel_config { | 124 | enum omap_dss_signal_level { |
125 | OMAP_DSS_LCD_IVS = 1<<0, | 125 | OMAPDSS_SIG_ACTIVE_HIGH = 0, |
126 | OMAP_DSS_LCD_IHS = 1<<1, | 126 | OMAPDSS_SIG_ACTIVE_LOW = 1, |
127 | OMAP_DSS_LCD_IPC = 1<<2, | 127 | }; |
128 | OMAP_DSS_LCD_IEO = 1<<3, | ||
129 | OMAP_DSS_LCD_RF = 1<<4, | ||
130 | OMAP_DSS_LCD_ONOFF = 1<<5, | ||
131 | 128 | ||
132 | OMAP_DSS_LCD_TFT = 1<<20, | 129 | enum omap_dss_signal_edge { |
130 | OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
131 | OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
132 | OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
133 | }; | 133 | }; |
134 | 134 | ||
135 | enum omap_dss_venc_type { | 135 | enum omap_dss_venc_type { |
@@ -167,13 +167,6 @@ enum omap_dss_audio_state { | |||
167 | OMAP_DSS_AUDIO_PLAYING, | 167 | OMAP_DSS_AUDIO_PLAYING, |
168 | }; | 168 | }; |
169 | 169 | ||
170 | /* XXX perhaps this should be removed */ | ||
171 | enum omap_dss_overlay_managers { | ||
172 | OMAP_DSS_OVL_MGR_LCD, | ||
173 | OMAP_DSS_OVL_MGR_TV, | ||
174 | OMAP_DSS_OVL_MGR_LCD2, | ||
175 | }; | ||
176 | |||
177 | enum omap_dss_rotation_type { | 170 | enum omap_dss_rotation_type { |
178 | OMAP_DSS_ROT_DMA = 1 << 0, | 171 | OMAP_DSS_ROT_DMA = 1 << 0, |
179 | OMAP_DSS_ROT_VRFB = 1 << 1, | 172 | OMAP_DSS_ROT_VRFB = 1 << 1, |
@@ -268,9 +261,6 @@ struct omap_dss_dsi_videomode_data { | |||
268 | int hfp_blanking_mode; | 261 | int hfp_blanking_mode; |
269 | 262 | ||
270 | /* Video port sync events */ | 263 | /* Video port sync events */ |
271 | int vp_de_pol; | ||
272 | int vp_hsync_pol; | ||
273 | int vp_vsync_pol; | ||
274 | bool vp_vsync_end; | 264 | bool vp_vsync_end; |
275 | bool vp_hsync_end; | 265 | bool vp_hsync_end; |
276 | 266 | ||
@@ -346,6 +336,19 @@ struct omap_video_timings { | |||
346 | u16 vfp; /* Vertical front porch */ | 336 | u16 vfp; /* Vertical front porch */ |
347 | /* Unit: line clocks */ | 337 | /* Unit: line clocks */ |
348 | u16 vbp; /* Vertical back porch */ | 338 | u16 vbp; /* Vertical back porch */ |
339 | |||
340 | /* Vsync logic level */ | ||
341 | enum omap_dss_signal_level vsync_level; | ||
342 | /* Hsync logic level */ | ||
343 | enum omap_dss_signal_level hsync_level; | ||
344 | /* Interlaced or Progressive timings */ | ||
345 | bool interlace; | ||
346 | /* Pixel clock edge to drive LCD data */ | ||
347 | enum omap_dss_signal_edge data_pclk_edge; | ||
348 | /* Data enable logic level */ | ||
349 | enum omap_dss_signal_level de_level; | ||
350 | /* Pixel clock edges to drive HSYNC and VSYNC signals */ | ||
351 | enum omap_dss_signal_edge sync_pclk_edge; | ||
349 | }; | 352 | }; |
350 | 353 | ||
351 | #ifdef CONFIG_OMAP2_DSS_VENC | 354 | #ifdef CONFIG_OMAP2_DSS_VENC |
@@ -559,8 +562,6 @@ struct omap_dss_device { | |||
559 | /* Unit: line clocks */ | 562 | /* Unit: line clocks */ |
560 | int acb; /* ac-bias pin frequency */ | 563 | int acb; /* ac-bias pin frequency */ |
561 | 564 | ||
562 | enum omap_panel_config config; | ||
563 | |||
564 | enum omap_dss_dsi_pixel_format dsi_pix_fmt; | 565 | enum omap_dss_dsi_pixel_format dsi_pix_fmt; |
565 | enum omap_dss_dsi_mode dsi_mode; | 566 | enum omap_dss_dsi_mode dsi_mode; |
566 | struct omap_dss_dsi_videomode_data dsi_vm_data; | 567 | struct omap_dss_dsi_videomode_data dsi_vm_data; |
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index 7571b27a0ba1..ff43ffc1aab2 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h | |||
@@ -166,6 +166,12 @@ struct sh_mobile_lcdc_bl_info { | |||
166 | int (*get_brightness)(void); | 166 | int (*get_brightness)(void); |
167 | }; | 167 | }; |
168 | 168 | ||
169 | struct sh_mobile_lcdc_overlay_cfg { | ||
170 | int fourcc; | ||
171 | unsigned int max_xres; | ||
172 | unsigned int max_yres; | ||
173 | }; | ||
174 | |||
169 | struct sh_mobile_lcdc_chan_cfg { | 175 | struct sh_mobile_lcdc_chan_cfg { |
170 | int chan; | 176 | int chan; |
171 | int fourcc; | 177 | int fourcc; |
@@ -186,6 +192,7 @@ struct sh_mobile_lcdc_chan_cfg { | |||
186 | struct sh_mobile_lcdc_info { | 192 | struct sh_mobile_lcdc_info { |
187 | int clock_source; | 193 | int clock_source; |
188 | struct sh_mobile_lcdc_chan_cfg ch[2]; | 194 | struct sh_mobile_lcdc_chan_cfg ch[2]; |
195 | struct sh_mobile_lcdc_overlay_cfg overlays[4]; | ||
189 | struct sh_mobile_meram_info *meram_dev; | 196 | struct sh_mobile_meram_info *meram_dev; |
190 | }; | 197 | }; |
191 | 198 | ||
diff --git a/include/video/sh_mobile_meram.h b/include/video/sh_mobile_meram.h index 29b2fd3b147e..062e6e7f955c 100644 --- a/include/video/sh_mobile_meram.h +++ b/include/video/sh_mobile_meram.h | |||
@@ -15,7 +15,6 @@ enum { | |||
15 | 15 | ||
16 | 16 | ||
17 | struct sh_mobile_meram_priv; | 17 | struct sh_mobile_meram_priv; |
18 | struct sh_mobile_meram_ops; | ||
19 | 18 | ||
20 | /* | 19 | /* |
21 | * struct sh_mobile_meram_info - MERAM platform data | 20 | * struct sh_mobile_meram_info - MERAM platform data |
@@ -24,7 +23,6 @@ struct sh_mobile_meram_ops; | |||
24 | struct sh_mobile_meram_info { | 23 | struct sh_mobile_meram_info { |
25 | int addr_mode; | 24 | int addr_mode; |
26 | u32 reserved_icbs; | 25 | u32 reserved_icbs; |
27 | struct sh_mobile_meram_ops *ops; | ||
28 | struct sh_mobile_meram_priv *priv; | 26 | struct sh_mobile_meram_priv *priv; |
29 | struct platform_device *pdev; | 27 | struct platform_device *pdev; |
30 | }; | 28 | }; |
@@ -38,26 +36,59 @@ struct sh_mobile_meram_cfg { | |||
38 | struct sh_mobile_meram_icb_cfg icb[2]; | 36 | struct sh_mobile_meram_icb_cfg icb[2]; |
39 | }; | 37 | }; |
40 | 38 | ||
41 | struct module; | 39 | #if defined(CONFIG_FB_SH_MOBILE_MERAM) || \ |
42 | struct sh_mobile_meram_ops { | 40 | defined(CONFIG_FB_SH_MOBILE_MERAM_MODULE) |
43 | struct module *module; | 41 | unsigned long sh_mobile_meram_alloc(struct sh_mobile_meram_info *meram_dev, |
44 | /* register usage of meram */ | 42 | size_t size); |
45 | void *(*meram_register)(struct sh_mobile_meram_info *meram_dev, | 43 | void sh_mobile_meram_free(struct sh_mobile_meram_info *meram_dev, |
46 | const struct sh_mobile_meram_cfg *cfg, | 44 | unsigned long mem, size_t size); |
47 | unsigned int xres, unsigned int yres, | 45 | void *sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *dev, |
48 | unsigned int pixelformat, | 46 | const struct sh_mobile_meram_cfg *cfg, |
49 | unsigned int *pitch); | 47 | unsigned int xres, unsigned int yres, |
50 | 48 | unsigned int pixelformat, | |
51 | /* unregister usage of meram */ | 49 | unsigned int *pitch); |
52 | void (*meram_unregister)(struct sh_mobile_meram_info *meram_dev, | 50 | void sh_mobile_meram_cache_free(struct sh_mobile_meram_info *dev, void *data); |
53 | void *data); | 51 | void sh_mobile_meram_cache_update(struct sh_mobile_meram_info *dev, void *data, |
54 | 52 | unsigned long base_addr_y, | |
55 | /* update meram settings */ | 53 | unsigned long base_addr_c, |
56 | void (*meram_update)(struct sh_mobile_meram_info *meram_dev, void *data, | 54 | unsigned long *icb_addr_y, |
55 | unsigned long *icb_addr_c); | ||
56 | #else | ||
57 | static inline unsigned long | ||
58 | sh_mobile_meram_alloc(struct sh_mobile_meram_info *meram_dev, size_t size) | ||
59 | { | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static inline void | ||
64 | sh_mobile_meram_free(struct sh_mobile_meram_info *meram_dev, | ||
65 | unsigned long mem, size_t size) | ||
66 | { | ||
67 | } | ||
68 | |||
69 | static inline void * | ||
70 | sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *dev, | ||
71 | const struct sh_mobile_meram_cfg *cfg, | ||
72 | unsigned int xres, unsigned int yres, | ||
73 | unsigned int pixelformat, | ||
74 | unsigned int *pitch) | ||
75 | { | ||
76 | return ERR_PTR(-ENODEV); | ||
77 | } | ||
78 | |||
79 | static inline void | ||
80 | sh_mobile_meram_cache_free(struct sh_mobile_meram_info *dev, void *data) | ||
81 | { | ||
82 | } | ||
83 | |||
84 | static inline void | ||
85 | sh_mobile_meram_cache_update(struct sh_mobile_meram_info *dev, void *data, | ||
57 | unsigned long base_addr_y, | 86 | unsigned long base_addr_y, |
58 | unsigned long base_addr_c, | 87 | unsigned long base_addr_c, |
59 | unsigned long *icb_addr_y, | 88 | unsigned long *icb_addr_y, |
60 | unsigned long *icb_addr_c); | 89 | unsigned long *icb_addr_c) |
61 | }; | 90 | { |
91 | } | ||
92 | #endif | ||
62 | 93 | ||
63 | #endif /* __VIDEO_SH_MOBILE_MERAM_H__ */ | 94 | #endif /* __VIDEO_SH_MOBILE_MERAM_H__ */ |