diff options
Diffstat (limited to 'drivers/video/s3c-fb.c')
-rw-r--r-- | drivers/video/s3c-fb.c | 121 |
1 files changed, 95 insertions, 26 deletions
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 3b6cdcac8f1a..0352afa49a39 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c | |||
@@ -182,6 +182,7 @@ struct s3c_fb_vsync { | |||
182 | 182 | ||
183 | /** | 183 | /** |
184 | * struct s3c_fb - overall hardware state of the hardware | 184 | * struct s3c_fb - overall hardware state of the hardware |
185 | * @slock: The spinlock protection for this data sturcture. | ||
185 | * @dev: The device that we bound to, for printing, etc. | 186 | * @dev: The device that we bound to, for printing, etc. |
186 | * @regs_res: The resource we claimed for the IO registers. | 187 | * @regs_res: The resource we claimed for the IO registers. |
187 | * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. | 188 | * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. |
@@ -195,6 +196,7 @@ struct s3c_fb_vsync { | |||
195 | * @vsync_info: VSYNC-related information (count, queues...) | 196 | * @vsync_info: VSYNC-related information (count, queues...) |
196 | */ | 197 | */ |
197 | struct s3c_fb { | 198 | struct s3c_fb { |
199 | spinlock_t slock; | ||
198 | struct device *dev; | 200 | struct device *dev; |
199 | struct resource *regs_res; | 201 | struct resource *regs_res; |
200 | struct clk *bus_clk; | 202 | struct clk *bus_clk; |
@@ -300,6 +302,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, | |||
300 | var->blue.length = 5; | 302 | var->blue.length = 5; |
301 | break; | 303 | break; |
302 | 304 | ||
305 | case 32: | ||
303 | case 28: | 306 | case 28: |
304 | case 25: | 307 | case 25: |
305 | var->transp.length = var->bits_per_pixel - 24; | 308 | var->transp.length = var->bits_per_pixel - 24; |
@@ -308,7 +311,6 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, | |||
308 | case 24: | 311 | case 24: |
309 | /* our 24bpp is unpacked, so 32bpp */ | 312 | /* our 24bpp is unpacked, so 32bpp */ |
310 | var->bits_per_pixel = 32; | 313 | var->bits_per_pixel = 32; |
311 | case 32: | ||
312 | var->red.offset = 16; | 314 | var->red.offset = 16; |
313 | var->red.length = 8; | 315 | var->red.length = 8; |
314 | var->green.offset = 8; | 316 | var->green.offset = 8; |
@@ -947,6 +949,8 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id) | |||
947 | void __iomem *regs = sfb->regs; | 949 | void __iomem *regs = sfb->regs; |
948 | u32 irq_sts_reg; | 950 | u32 irq_sts_reg; |
949 | 951 | ||
952 | spin_lock(&sfb->slock); | ||
953 | |||
950 | irq_sts_reg = readl(regs + VIDINTCON1); | 954 | irq_sts_reg = readl(regs + VIDINTCON1); |
951 | 955 | ||
952 | if (irq_sts_reg & VIDINTCON1_INT_FRAME) { | 956 | if (irq_sts_reg & VIDINTCON1_INT_FRAME) { |
@@ -963,6 +967,7 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id) | |||
963 | */ | 967 | */ |
964 | s3c_fb_disable_irq(sfb); | 968 | s3c_fb_disable_irq(sfb); |
965 | 969 | ||
970 | spin_unlock(&sfb->slock); | ||
966 | return IRQ_HANDLED; | 971 | return IRQ_HANDLED; |
967 | } | 972 | } |
968 | 973 | ||
@@ -1339,6 +1344,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) | |||
1339 | sfb->pdata = pd; | 1344 | sfb->pdata = pd; |
1340 | sfb->variant = fbdrv->variant; | 1345 | sfb->variant = fbdrv->variant; |
1341 | 1346 | ||
1347 | spin_lock_init(&sfb->slock); | ||
1348 | |||
1342 | sfb->bus_clk = clk_get(dev, "lcd"); | 1349 | sfb->bus_clk = clk_get(dev, "lcd"); |
1343 | if (IS_ERR(sfb->bus_clk)) { | 1350 | if (IS_ERR(sfb->bus_clk)) { |
1344 | dev_err(dev, "failed to get bus clock\n"); | 1351 | dev_err(dev, "failed to get bus clock\n"); |
@@ -1442,8 +1449,7 @@ err_ioremap: | |||
1442 | iounmap(sfb->regs); | 1449 | iounmap(sfb->regs); |
1443 | 1450 | ||
1444 | err_req_region: | 1451 | err_req_region: |
1445 | release_resource(sfb->regs_res); | 1452 | release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); |
1446 | kfree(sfb->regs_res); | ||
1447 | 1453 | ||
1448 | err_clk: | 1454 | err_clk: |
1449 | clk_disable(sfb->bus_clk); | 1455 | clk_disable(sfb->bus_clk); |
@@ -1479,8 +1485,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) | |||
1479 | clk_disable(sfb->bus_clk); | 1485 | clk_disable(sfb->bus_clk); |
1480 | clk_put(sfb->bus_clk); | 1486 | clk_put(sfb->bus_clk); |
1481 | 1487 | ||
1482 | release_resource(sfb->regs_res); | 1488 | release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); |
1483 | kfree(sfb->regs_res); | ||
1484 | 1489 | ||
1485 | kfree(sfb); | 1490 | kfree(sfb); |
1486 | 1491 | ||
@@ -1521,7 +1526,8 @@ static int s3c_fb_resume(struct device *dev) | |||
1521 | 1526 | ||
1522 | clk_enable(sfb->bus_clk); | 1527 | clk_enable(sfb->bus_clk); |
1523 | 1528 | ||
1524 | /* setup registers */ | 1529 | /* setup gpio and output polarity controls */ |
1530 | pd->setup_gpio(); | ||
1525 | writel(pd->vidcon1, sfb->regs + VIDCON1); | 1531 | writel(pd->vidcon1, sfb->regs + VIDCON1); |
1526 | 1532 | ||
1527 | /* zero all windows before we do anything */ | 1533 | /* zero all windows before we do anything */ |
@@ -1549,7 +1555,7 @@ static int s3c_fb_resume(struct device *dev) | |||
1549 | return 0; | 1555 | return 0; |
1550 | } | 1556 | } |
1551 | 1557 | ||
1552 | int s3c_fb_runtime_suspend(struct device *dev) | 1558 | static int s3c_fb_runtime_suspend(struct device *dev) |
1553 | { | 1559 | { |
1554 | struct platform_device *pdev = to_platform_device(dev); | 1560 | struct platform_device *pdev = to_platform_device(dev); |
1555 | struct s3c_fb *sfb = platform_get_drvdata(pdev); | 1561 | struct s3c_fb *sfb = platform_get_drvdata(pdev); |
@@ -1569,7 +1575,7 @@ int s3c_fb_runtime_suspend(struct device *dev) | |||
1569 | return 0; | 1575 | return 0; |
1570 | } | 1576 | } |
1571 | 1577 | ||
1572 | int s3c_fb_runtime_resume(struct device *dev) | 1578 | static int s3c_fb_runtime_resume(struct device *dev) |
1573 | { | 1579 | { |
1574 | struct platform_device *pdev = to_platform_device(dev); | 1580 | struct platform_device *pdev = to_platform_device(dev); |
1575 | struct s3c_fb *sfb = platform_get_drvdata(pdev); | 1581 | struct s3c_fb *sfb = platform_get_drvdata(pdev); |
@@ -1579,7 +1585,8 @@ int s3c_fb_runtime_resume(struct device *dev) | |||
1579 | 1585 | ||
1580 | clk_enable(sfb->bus_clk); | 1586 | clk_enable(sfb->bus_clk); |
1581 | 1587 | ||
1582 | /* setup registers */ | 1588 | /* setup gpio and output polarity controls */ |
1589 | pd->setup_gpio(); | ||
1583 | writel(pd->vidcon1, sfb->regs + VIDCON1); | 1590 | writel(pd->vidcon1, sfb->regs + VIDCON1); |
1584 | 1591 | ||
1585 | /* zero all windows before we do anything */ | 1592 | /* zero all windows before we do anything */ |
@@ -1623,28 +1630,31 @@ static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = { | |||
1623 | .has_osd_c = 1, | 1630 | .has_osd_c = 1, |
1624 | .osd_size_off = 0x8, | 1631 | .osd_size_off = 0x8, |
1625 | .palette_sz = 256, | 1632 | .palette_sz = 256, |
1626 | .valid_bpp = VALID_BPP1248 | VALID_BPP(16) | VALID_BPP(24), | 1633 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | |
1634 | VALID_BPP(18) | VALID_BPP(24)), | ||
1627 | }, | 1635 | }, |
1628 | [1] = { | 1636 | [1] = { |
1629 | .has_osd_c = 1, | 1637 | .has_osd_c = 1, |
1630 | .has_osd_d = 1, | 1638 | .has_osd_d = 1, |
1631 | .osd_size_off = 0x12, | 1639 | .osd_size_off = 0xc, |
1632 | .has_osd_alpha = 1, | 1640 | .has_osd_alpha = 1, |
1633 | .palette_sz = 256, | 1641 | .palette_sz = 256, |
1634 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | | 1642 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | |
1635 | VALID_BPP(18) | VALID_BPP(19) | | 1643 | VALID_BPP(18) | VALID_BPP(19) | |
1636 | VALID_BPP(24) | VALID_BPP(25)), | 1644 | VALID_BPP(24) | VALID_BPP(25) | |
1645 | VALID_BPP(28)), | ||
1637 | }, | 1646 | }, |
1638 | [2] = { | 1647 | [2] = { |
1639 | .has_osd_c = 1, | 1648 | .has_osd_c = 1, |
1640 | .has_osd_d = 1, | 1649 | .has_osd_d = 1, |
1641 | .osd_size_off = 0x12, | 1650 | .osd_size_off = 0xc, |
1642 | .has_osd_alpha = 1, | 1651 | .has_osd_alpha = 1, |
1643 | .palette_sz = 16, | 1652 | .palette_sz = 16, |
1644 | .palette_16bpp = 1, | 1653 | .palette_16bpp = 1, |
1645 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | | 1654 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | |
1646 | VALID_BPP(18) | VALID_BPP(19) | | 1655 | VALID_BPP(18) | VALID_BPP(19) | |
1647 | VALID_BPP(24) | VALID_BPP(25)), | 1656 | VALID_BPP(24) | VALID_BPP(25) | |
1657 | VALID_BPP(28)), | ||
1648 | }, | 1658 | }, |
1649 | [3] = { | 1659 | [3] = { |
1650 | .has_osd_c = 1, | 1660 | .has_osd_c = 1, |
@@ -1653,7 +1663,8 @@ static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = { | |||
1653 | .palette_16bpp = 1, | 1663 | .palette_16bpp = 1, |
1654 | .valid_bpp = (VALID_BPP124 | VALID_BPP(16) | | 1664 | .valid_bpp = (VALID_BPP124 | VALID_BPP(16) | |
1655 | VALID_BPP(18) | VALID_BPP(19) | | 1665 | VALID_BPP(18) | VALID_BPP(19) | |
1656 | VALID_BPP(24) | VALID_BPP(25)), | 1666 | VALID_BPP(24) | VALID_BPP(25) | |
1667 | VALID_BPP(28)), | ||
1657 | }, | 1668 | }, |
1658 | [4] = { | 1669 | [4] = { |
1659 | .has_osd_c = 1, | 1670 | .has_osd_c = 1, |
@@ -1662,7 +1673,65 @@ static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = { | |||
1662 | .palette_16bpp = 1, | 1673 | .palette_16bpp = 1, |
1663 | .valid_bpp = (VALID_BPP(1) | VALID_BPP(2) | | 1674 | .valid_bpp = (VALID_BPP(1) | VALID_BPP(2) | |
1664 | VALID_BPP(16) | VALID_BPP(18) | | 1675 | VALID_BPP(16) | VALID_BPP(18) | |
1665 | VALID_BPP(24) | VALID_BPP(25)), | 1676 | VALID_BPP(19) | VALID_BPP(24) | |
1677 | VALID_BPP(25) | VALID_BPP(28)), | ||
1678 | }, | ||
1679 | }; | ||
1680 | |||
1681 | static struct s3c_fb_win_variant s3c_fb_data_s5p_wins[] = { | ||
1682 | [0] = { | ||
1683 | .has_osd_c = 1, | ||
1684 | .osd_size_off = 0x8, | ||
1685 | .palette_sz = 256, | ||
1686 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | | ||
1687 | VALID_BPP(15) | VALID_BPP(16) | | ||
1688 | VALID_BPP(18) | VALID_BPP(19) | | ||
1689 | VALID_BPP(24) | VALID_BPP(25) | | ||
1690 | VALID_BPP(32)), | ||
1691 | }, | ||
1692 | [1] = { | ||
1693 | .has_osd_c = 1, | ||
1694 | .has_osd_d = 1, | ||
1695 | .osd_size_off = 0xc, | ||
1696 | .has_osd_alpha = 1, | ||
1697 | .palette_sz = 256, | ||
1698 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | | ||
1699 | VALID_BPP(15) | VALID_BPP(16) | | ||
1700 | VALID_BPP(18) | VALID_BPP(19) | | ||
1701 | VALID_BPP(24) | VALID_BPP(25) | | ||
1702 | VALID_BPP(32)), | ||
1703 | }, | ||
1704 | [2] = { | ||
1705 | .has_osd_c = 1, | ||
1706 | .has_osd_d = 1, | ||
1707 | .osd_size_off = 0xc, | ||
1708 | .has_osd_alpha = 1, | ||
1709 | .palette_sz = 256, | ||
1710 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | | ||
1711 | VALID_BPP(15) | VALID_BPP(16) | | ||
1712 | VALID_BPP(18) | VALID_BPP(19) | | ||
1713 | VALID_BPP(24) | VALID_BPP(25) | | ||
1714 | VALID_BPP(32)), | ||
1715 | }, | ||
1716 | [3] = { | ||
1717 | .has_osd_c = 1, | ||
1718 | .has_osd_alpha = 1, | ||
1719 | .palette_sz = 256, | ||
1720 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | | ||
1721 | VALID_BPP(15) | VALID_BPP(16) | | ||
1722 | VALID_BPP(18) | VALID_BPP(19) | | ||
1723 | VALID_BPP(24) | VALID_BPP(25) | | ||
1724 | VALID_BPP(32)), | ||
1725 | }, | ||
1726 | [4] = { | ||
1727 | .has_osd_c = 1, | ||
1728 | .has_osd_alpha = 1, | ||
1729 | .palette_sz = 256, | ||
1730 | .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) | | ||
1731 | VALID_BPP(15) | VALID_BPP(16) | | ||
1732 | VALID_BPP(18) | VALID_BPP(19) | | ||
1733 | VALID_BPP(24) | VALID_BPP(25) | | ||
1734 | VALID_BPP(32)), | ||
1666 | }, | 1735 | }, |
1667 | }; | 1736 | }; |
1668 | 1737 | ||
@@ -1719,11 +1788,11 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = { | |||
1719 | 1788 | ||
1720 | .has_prtcon = 1, | 1789 | .has_prtcon = 1, |
1721 | }, | 1790 | }, |
1722 | .win[0] = &s3c_fb_data_64xx_wins[0], | 1791 | .win[0] = &s3c_fb_data_s5p_wins[0], |
1723 | .win[1] = &s3c_fb_data_64xx_wins[1], | 1792 | .win[1] = &s3c_fb_data_s5p_wins[1], |
1724 | .win[2] = &s3c_fb_data_64xx_wins[2], | 1793 | .win[2] = &s3c_fb_data_s5p_wins[2], |
1725 | .win[3] = &s3c_fb_data_64xx_wins[3], | 1794 | .win[3] = &s3c_fb_data_s5p_wins[3], |
1726 | .win[4] = &s3c_fb_data_64xx_wins[4], | 1795 | .win[4] = &s3c_fb_data_s5p_wins[4], |
1727 | }; | 1796 | }; |
1728 | 1797 | ||
1729 | static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { | 1798 | static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { |
@@ -1749,11 +1818,11 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { | |||
1749 | 1818 | ||
1750 | .has_shadowcon = 1, | 1819 | .has_shadowcon = 1, |
1751 | }, | 1820 | }, |
1752 | .win[0] = &s3c_fb_data_64xx_wins[0], | 1821 | .win[0] = &s3c_fb_data_s5p_wins[0], |
1753 | .win[1] = &s3c_fb_data_64xx_wins[1], | 1822 | .win[1] = &s3c_fb_data_s5p_wins[1], |
1754 | .win[2] = &s3c_fb_data_64xx_wins[2], | 1823 | .win[2] = &s3c_fb_data_s5p_wins[2], |
1755 | .win[3] = &s3c_fb_data_64xx_wins[3], | 1824 | .win[3] = &s3c_fb_data_s5p_wins[3], |
1756 | .win[4] = &s3c_fb_data_64xx_wins[4], | 1825 | .win[4] = &s3c_fb_data_s5p_wins[4], |
1757 | }; | 1826 | }; |
1758 | 1827 | ||
1759 | /* S3C2443/S3C2416 style hardware */ | 1828 | /* S3C2443/S3C2416 style hardware */ |