aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/s3c-fb.c88
2 files changed, 85 insertions, 5 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960667c8..963b8b767b83 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2027,7 +2027,7 @@ config FB_TMIO_ACCELL
2027 2027
2028config FB_S3C 2028config FB_S3C
2029 tristate "Samsung S3C framebuffer support" 2029 tristate "Samsung S3C framebuffer support"
2030 depends on FB && S3C_DEV_FB 2030 depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0)
2031 select FB_CFB_FILLRECT 2031 select FB_CFB_FILLRECT
2032 select FB_CFB_COPYAREA 2032 select FB_CFB_COPYAREA
2033 select FB_CFB_IMAGEBLIT 2033 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index fd9f20df912f..170029e7cba8 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -81,6 +81,7 @@ struct s3c_fb;
81 * @palette: Address of palette memory, or 0 if none. 81 * @palette: Address of palette memory, or 0 if none.
82 * @has_prtcon: Set if has PRTCON register. 82 * @has_prtcon: Set if has PRTCON register.
83 * @has_shadowcon: Set if has SHADOWCON register. 83 * @has_shadowcon: Set if has SHADOWCON register.
84 * @has_clksel: Set if VIDCON0 register has CLKSEL bit.
84 */ 85 */
85struct s3c_fb_variant { 86struct s3c_fb_variant {
86 unsigned int is_2443:1; 87 unsigned int is_2443:1;
@@ -98,6 +99,7 @@ struct s3c_fb_variant {
98 99
99 unsigned int has_prtcon:1; 100 unsigned int has_prtcon:1;
100 unsigned int has_shadowcon:1; 101 unsigned int has_shadowcon:1;
102 unsigned int has_clksel:1;
101}; 103};
102 104
103/** 105/**
@@ -186,6 +188,7 @@ struct s3c_fb_vsync {
186 * @dev: The device that we bound to, for printing, etc. 188 * @dev: The device that we bound to, for printing, etc.
187 * @regs_res: The resource we claimed for the IO registers. 189 * @regs_res: The resource we claimed for the IO registers.
188 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. 190 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
191 * @lcd_clk: The clk (sclk) feeding pixclk.
189 * @regs: The mapped hardware registers. 192 * @regs: The mapped hardware registers.
190 * @variant: Variant information for this hardware. 193 * @variant: Variant information for this hardware.
191 * @enabled: A bitmask of enabled hardware windows. 194 * @enabled: A bitmask of enabled hardware windows.
@@ -200,6 +203,7 @@ struct s3c_fb {
200 struct device *dev; 203 struct device *dev;
201 struct resource *regs_res; 204 struct resource *regs_res;
202 struct clk *bus_clk; 205 struct clk *bus_clk;
206 struct clk *lcd_clk;
203 void __iomem *regs; 207 void __iomem *regs;
204 struct s3c_fb_variant variant; 208 struct s3c_fb_variant variant;
205 209
@@ -336,10 +340,15 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
336 */ 340 */
337static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) 341static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
338{ 342{
339 unsigned long clk = clk_get_rate(sfb->bus_clk); 343 unsigned long clk;
340 unsigned long long tmp; 344 unsigned long long tmp;
341 unsigned int result; 345 unsigned int result;
342 346
347 if (sfb->variant.has_clksel)
348 clk = clk_get_rate(sfb->bus_clk);
349 else
350 clk = clk_get_rate(sfb->lcd_clk);
351
343 tmp = (unsigned long long)clk; 352 tmp = (unsigned long long)clk;
344 tmp *= pixclk; 353 tmp *= pixclk;
345 354
@@ -1354,13 +1363,24 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1354 1363
1355 clk_enable(sfb->bus_clk); 1364 clk_enable(sfb->bus_clk);
1356 1365
1366 if (!sfb->variant.has_clksel) {
1367 sfb->lcd_clk = clk_get(dev, "sclk_fimd");
1368 if (IS_ERR(sfb->lcd_clk)) {
1369 dev_err(dev, "failed to get lcd clock\n");
1370 ret = PTR_ERR(sfb->lcd_clk);
1371 goto err_bus_clk;
1372 }
1373
1374 clk_enable(sfb->lcd_clk);
1375 }
1376
1357 pm_runtime_enable(sfb->dev); 1377 pm_runtime_enable(sfb->dev);
1358 1378
1359 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1379 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1360 if (!res) { 1380 if (!res) {
1361 dev_err(dev, "failed to find registers\n"); 1381 dev_err(dev, "failed to find registers\n");
1362 ret = -ENOENT; 1382 ret = -ENOENT;
1363 goto err_clk; 1383 goto err_lcd_clk;
1364 } 1384 }
1365 1385
1366 sfb->regs_res = request_mem_region(res->start, resource_size(res), 1386 sfb->regs_res = request_mem_region(res->start, resource_size(res),
@@ -1368,7 +1388,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1368 if (!sfb->regs_res) { 1388 if (!sfb->regs_res) {
1369 dev_err(dev, "failed to claim register region\n"); 1389 dev_err(dev, "failed to claim register region\n");
1370 ret = -ENOENT; 1390 ret = -ENOENT;
1371 goto err_clk; 1391 goto err_lcd_clk;
1372 } 1392 }
1373 1393
1374 sfb->regs = ioremap(res->start, resource_size(res)); 1394 sfb->regs = ioremap(res->start, resource_size(res));
@@ -1450,7 +1470,13 @@ err_ioremap:
1450err_req_region: 1470err_req_region:
1451 release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); 1471 release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
1452 1472
1453err_clk: 1473err_lcd_clk:
1474 if (!sfb->variant.has_clksel) {
1475 clk_disable(sfb->lcd_clk);
1476 clk_put(sfb->lcd_clk);
1477 }
1478
1479err_bus_clk:
1454 clk_disable(sfb->bus_clk); 1480 clk_disable(sfb->bus_clk);
1455 clk_put(sfb->bus_clk); 1481 clk_put(sfb->bus_clk);
1456 1482
@@ -1481,6 +1507,11 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
1481 1507
1482 iounmap(sfb->regs); 1508 iounmap(sfb->regs);
1483 1509
1510 if (!sfb->variant.has_clksel) {
1511 clk_disable(sfb->lcd_clk);
1512 clk_put(sfb->lcd_clk);
1513 }
1514
1484 clk_disable(sfb->bus_clk); 1515 clk_disable(sfb->bus_clk);
1485 clk_put(sfb->bus_clk); 1516 clk_put(sfb->bus_clk);
1486 1517
@@ -1510,6 +1541,9 @@ static int s3c_fb_suspend(struct device *dev)
1510 s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo); 1541 s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
1511 } 1542 }
1512 1543
1544 if (!sfb->variant.has_clksel)
1545 clk_disable(sfb->lcd_clk);
1546
1513 clk_disable(sfb->bus_clk); 1547 clk_disable(sfb->bus_clk);
1514 return 0; 1548 return 0;
1515} 1549}
@@ -1524,6 +1558,9 @@ static int s3c_fb_resume(struct device *dev)
1524 1558
1525 clk_enable(sfb->bus_clk); 1559 clk_enable(sfb->bus_clk);
1526 1560
1561 if (!sfb->variant.has_clksel)
1562 clk_enable(sfb->lcd_clk);
1563
1527 /* setup gpio and output polarity controls */ 1564 /* setup gpio and output polarity controls */
1528 pd->setup_gpio(); 1565 pd->setup_gpio();
1529 writel(pd->vidcon1, sfb->regs + VIDCON1); 1566 writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1569,6 +1606,9 @@ static int s3c_fb_runtime_suspend(struct device *dev)
1569 s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo); 1606 s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
1570 } 1607 }
1571 1608
1609 if (!sfb->variant.has_clksel)
1610 clk_disable(sfb->lcd_clk);
1611
1572 clk_disable(sfb->bus_clk); 1612 clk_disable(sfb->bus_clk);
1573 return 0; 1613 return 0;
1574} 1614}
@@ -1583,6 +1623,9 @@ static int s3c_fb_runtime_resume(struct device *dev)
1583 1623
1584 clk_enable(sfb->bus_clk); 1624 clk_enable(sfb->bus_clk);
1585 1625
1626 if (!sfb->variant.has_clksel)
1627 clk_enable(sfb->lcd_clk);
1628
1586 /* setup gpio and output polarity controls */ 1629 /* setup gpio and output polarity controls */
1587 pd->setup_gpio(); 1630 pd->setup_gpio();
1588 writel(pd->vidcon1, sfb->regs + VIDCON1); 1631 writel(pd->vidcon1, sfb->regs + VIDCON1);
@@ -1755,6 +1798,7 @@ static struct s3c_fb_driverdata s3c_fb_data_64xx = {
1755 }, 1798 },
1756 1799
1757 .has_prtcon = 1, 1800 .has_prtcon = 1,
1801 .has_clksel = 1,
1758 }, 1802 },
1759 .win[0] = &s3c_fb_data_64xx_wins[0], 1803 .win[0] = &s3c_fb_data_64xx_wins[0],
1760 .win[1] = &s3c_fb_data_64xx_wins[1], 1804 .win[1] = &s3c_fb_data_64xx_wins[1],
@@ -1785,6 +1829,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
1785 }, 1829 },
1786 1830
1787 .has_prtcon = 1, 1831 .has_prtcon = 1,
1832 .has_clksel = 1,
1788 }, 1833 },
1789 .win[0] = &s3c_fb_data_s5p_wins[0], 1834 .win[0] = &s3c_fb_data_s5p_wins[0],
1790 .win[1] = &s3c_fb_data_s5p_wins[1], 1835 .win[1] = &s3c_fb_data_s5p_wins[1],
@@ -1815,6 +1860,37 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
1815 }, 1860 },
1816 1861
1817 .has_shadowcon = 1, 1862 .has_shadowcon = 1,
1863 .has_clksel = 1,
1864 },
1865 .win[0] = &s3c_fb_data_s5p_wins[0],
1866 .win[1] = &s3c_fb_data_s5p_wins[1],
1867 .win[2] = &s3c_fb_data_s5p_wins[2],
1868 .win[3] = &s3c_fb_data_s5p_wins[3],
1869 .win[4] = &s3c_fb_data_s5p_wins[4],
1870};
1871
1872static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
1873 .variant = {
1874 .nr_windows = 5,
1875 .vidtcon = VIDTCON0,
1876 .wincon = WINCON(0),
1877 .winmap = WINxMAP(0),
1878 .keycon = WKEYCON,
1879 .osd = VIDOSD_BASE,
1880 .osd_stride = 16,
1881 .buf_start = VIDW_BUF_START(0),
1882 .buf_size = VIDW_BUF_SIZE(0),
1883 .buf_end = VIDW_BUF_END(0),
1884
1885 .palette = {
1886 [0] = 0x2400,
1887 [1] = 0x2800,
1888 [2] = 0x2c00,
1889 [3] = 0x3000,
1890 [4] = 0x3400,
1891 },
1892
1893 .has_shadowcon = 1,
1818 }, 1894 },
1819 .win[0] = &s3c_fb_data_s5p_wins[0], 1895 .win[0] = &s3c_fb_data_s5p_wins[0],
1820 .win[1] = &s3c_fb_data_s5p_wins[1], 1896 .win[1] = &s3c_fb_data_s5p_wins[1],
@@ -1843,6 +1919,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = {
1843 [0] = 0x400, 1919 [0] = 0x400,
1844 [1] = 0x800, 1920 [1] = 0x800,
1845 }, 1921 },
1922 .has_clksel = 1,
1846 }, 1923 },
1847 .win[0] = &(struct s3c_fb_win_variant) { 1924 .win[0] = &(struct s3c_fb_win_variant) {
1848 .palette_sz = 256, 1925 .palette_sz = 256,
@@ -1870,6 +1947,9 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
1870 .name = "s5pv210-fb", 1947 .name = "s5pv210-fb",
1871 .driver_data = (unsigned long)&s3c_fb_data_s5pv210, 1948 .driver_data = (unsigned long)&s3c_fb_data_s5pv210,
1872 }, { 1949 }, {
1950 .name = "exynos4-fb",
1951 .driver_data = (unsigned long)&s3c_fb_data_exynos4,
1952 }, {
1873 .name = "s3c2443-fb", 1953 .name = "s3c2443-fb",
1874 .driver_data = (unsigned long)&s3c_fb_data_s3c2443, 1954 .driver_data = (unsigned long)&s3c_fb_data_s3c2443,
1875 }, 1955 },