aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/s3c-fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/s3c-fb.c')
-rw-r--r--drivers/video/s3c-fb.c121
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 */
197struct s3c_fb { 198struct 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
1444err_req_region: 1451err_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
1448err_clk: 1454err_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
1552int s3c_fb_runtime_suspend(struct device *dev) 1558static 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
1572int s3c_fb_runtime_resume(struct device *dev) 1578static 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
1681static 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
1729static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { 1798static 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 */