From patchwork Tue Jan 4 08:05:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kim Kukjin X-Patchwork-Id: 450011 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p048UgiO004144 for ; Tue, 4 Jan 2011 08:30:42 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751206Ab1ADIaf (ORCPT ); Tue, 4 Jan 2011 03:30:35 -0500 Received: from ganesha.gnumonks.org ([213.95.27.120]:52675 "EHLO ganesha.gnumonks.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751170Ab1ADIad (ORCPT ); Tue, 4 Jan 2011 03:30:33 -0500 Received: from uucp by ganesha.gnumonks.org with local-bsmtp (Exim 4.69) (envelope-from ) id 1Pa2Hi-0000oK-IX; Tue, 04 Jan 2011 09:30:26 +0100 Received: from [12.23.102.184] (helo=localhost.localdomain) by jackpot.kr.gnumonks.org with esmtp (Exim 4.69) (envelope-from ) id 1Pa1Bw-0007rG-1t; Tue, 04 Jan 2011 16:20:24 +0900 From: Kukjin Kim To: linux-samsung-soc@vger.kernel.org, linux-fbdev@vger.kernel.org Cc: ben-linux@fluff.org, akpm@linux-foundation.org, lethal@linux-sh.org, Jonghun Han , Sangbeom Kim , InKi Dae , Kukjin Kim Subject: [PATCH RE-SEND] s3c-fb: Add support S5PV310 FIMD Date: Tue, 4 Jan 2011 17:05:33 +0900 Message-Id: <1294128333-28736-1-git-send-email-kgene.kim@samsung.com> X-Mailer: git-send-email 1.6.2.5 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 04 Jan 2011 08:30:43 +0000 (UTC) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index e231041..dea54c7 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2043,7 +2043,7 @@ config FB_TMIO_ACCELL config FB_S3C tristate "Samsung S3C framebuffer support" - depends on FB && S3C_DEV_FB + depends on FB && (S3C_DEV_FB || S5P_DEV_FIMD0) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 83ce9a0..6d478dd 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -66,6 +66,9 @@ struct s3c_fb; #define VIDOSD_C(win, variant) (OSD_BASE(win, variant) + 0x08) #define VIDOSD_D(win, variant) (OSD_BASE(win, variant) + 0x0C) +#define FIMD_CLK_TYPE0 0 +#define FIMD_CLK_TYPE1 1 + /** * struct s3c_fb_variant - fb variant information * @is_2443: Set if S3C2443/S3C2416 style hardware. @@ -98,6 +101,7 @@ struct s3c_fb_variant { unsigned int has_prtcon:1; unsigned int has_shadowcon:1; + unsigned int clk_type:1; }; /** @@ -184,7 +188,8 @@ struct s3c_fb_vsync { * struct s3c_fb - overall hardware state of the hardware * @dev: The device that we bound to, for printing, etc. * @regs_res: The resource we claimed for the IO registers. - * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. + * @bus_clk: The clk (hclk) feeding FIMD IP core. + * @lcd_clk: The clk (sclk) feeding our interface and possibly pixclk. * @regs: The mapped hardware registers. * @variant: Variant information for this hardware. * @enabled: A bitmask of enabled hardware windows. @@ -198,6 +203,7 @@ struct s3c_fb { struct device *dev; struct resource *regs_res; struct clk *bus_clk; + struct clk *lcd_clk; void __iomem *regs; struct s3c_fb_variant variant; @@ -335,7 +341,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, */ static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) { - unsigned long clk = clk_get_rate(sfb->bus_clk); + unsigned long clk = clk_get_rate(sfb->lcd_clk); unsigned long long tmp; unsigned int result; @@ -518,7 +524,7 @@ static int s3c_fb_set_par(struct fb_info *info) data = VIDTCON2_LINEVAL(var->yres - 1) | VIDTCON2_HOZVAL(var->xres - 1); - writel(data, regs +sfb->variant.vidtcon + 8 ); + writel(data, regs + sfb->variant.vidtcon + 8); } /* write the buffer address */ @@ -1309,8 +1315,10 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) struct s3c_fb_platdata *pd; struct s3c_fb *sfb; struct resource *res; + struct clk *mout_mpll = NULL; int win; int ret = 0; + u32 rate = 134000000; fbdrv = (struct s3c_fb_driverdata *)platform_get_device_id(pdev)->driver_data; @@ -1337,9 +1345,48 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) sfb->pdata = pd; sfb->variant = fbdrv->variant; - sfb->bus_clk = clk_get(dev, "lcd"); - if (IS_ERR(sfb->bus_clk)) { - dev_err(dev, "failed to get bus clock\n"); + switch (sfb->variant.clk_type) { + case FIMD_CLK_TYPE0: + sfb->bus_clk = clk_get(dev, "lcd"); + if (IS_ERR(sfb->bus_clk)) { + dev_err(dev, "failed to get bus clock\n"); + goto err_sfb; + } + + clk_enable(sfb->bus_clk); + + sfb->lcd_clk = sfb->bus_clk; + break; + + case FIMD_CLK_TYPE1: + sfb->bus_clk = clk_get(&pdev->dev, "fimd"); + if (IS_ERR(sfb->bus_clk)) { + dev_err(&pdev->dev, "failed to get clock for fimd\n"); + goto err_sfb; + } + clk_enable(sfb->bus_clk); + + sfb->lcd_clk = clk_get(&pdev->dev, "sclk_fimd"); + if (IS_ERR(sfb->lcd_clk)) { + dev_err(&pdev->dev, "failed to get sclk for fimd\n"); + goto err_bus_clk; + } + + mout_mpll = clk_get(&pdev->dev, "mout_mpll"); + if (IS_ERR(mout_mpll)) { + dev_err(&pdev->dev, "failed to get mout_mpll\n"); + goto err_lcd_clk; + } + clk_set_parent(sfb->lcd_clk, mout_mpll); + clk_put(mout_mpll); + + clk_set_rate(sfb->lcd_clk, rate); + clk_enable(sfb->lcd_clk); + dev_dbg(&pdev->dev, "set fimd sclk rate to %d\n", rate); + break; + + default: + dev_err(dev, "failed to enable clock for FIMD\n"); goto err_sfb; } @@ -1351,7 +1398,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) if (!res) { dev_err(dev, "failed to find registers\n"); ret = -ENOENT; - goto err_clk; + goto err_lcd_clk; } sfb->regs_res = request_mem_region(res->start, resource_size(res), @@ -1359,7 +1406,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) if (!sfb->regs_res) { dev_err(dev, "failed to claim register region\n"); ret = -ENOENT; - goto err_clk; + goto err_lcd_clk; } sfb->regs = ioremap(res->start, resource_size(res)); @@ -1442,9 +1489,15 @@ err_req_region: release_resource(sfb->regs_res); kfree(sfb->regs_res); -err_clk: - clk_disable(sfb->bus_clk); - clk_put(sfb->bus_clk); +err_lcd_clk: + clk_disable(sfb->lcd_clk); + clk_put(sfb->lcd_clk); + +err_bus_clk: + if (sfb->variant.clk_type != FIMD_CLK_TYPE0) { + clk_disable(sfb->bus_clk); + clk_put(sfb->bus_clk); + } err_sfb: kfree(sfb); @@ -1473,8 +1526,20 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) iounmap(sfb->regs); - clk_disable(sfb->bus_clk); - clk_put(sfb->bus_clk); + switch (sfb->variant.clk_type) { + case FIMD_CLK_TYPE1: + clk_disable(sfb->lcd_clk); + clk_put(sfb->lcd_clk); + /* fall through to default case */ + case FIMD_CLK_TYPE0: + clk_disable(sfb->bus_clk); + clk_put(sfb->bus_clk); + break; + default: + dev_err(sfb->dev, "invalid clock type(%d)\n", + sfb->variant.clk_type); + break; + } release_resource(sfb->regs_res); kfree(sfb->regs_res); @@ -1753,6 +1818,37 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { .win[4] = &s3c_fb_data_64xx_wins[4], }; +static struct s3c_fb_driverdata s3c_fb_data_s5pv310 = { + .variant = { + .nr_windows = 5, + .vidtcon = VIDTCON0, + .wincon = WINCON(0), + .winmap = WINxMAP(0), + .keycon = WKEYCON, + .osd = VIDOSD_BASE, + .osd_stride = 16, + .buf_start = VIDW_BUF_START(0), + .buf_size = VIDW_BUF_SIZE(0), + .buf_end = VIDW_BUF_END(0), + + .palette = { + [0] = 0x2400, + [1] = 0x2800, + [2] = 0x2c00, + [3] = 0x3000, + [4] = 0x3400, + }, + + .has_shadowcon = 1, + .clk_type = FIMD_CLK_TYPE1, + }, + .win[0] = &s3c_fb_data_64xx_wins[0], + .win[1] = &s3c_fb_data_64xx_wins[1], + .win[2] = &s3c_fb_data_64xx_wins[2], + .win[3] = &s3c_fb_data_64xx_wins[3], + .win[4] = &s3c_fb_data_64xx_wins[4], +}; + /* S3C2443/S3C2416 style hardware */ static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = { .variant = { @@ -1800,6 +1896,9 @@ static struct platform_device_id s3c_fb_driver_ids[] = { .name = "s5pv210-fb", .driver_data = (unsigned long)&s3c_fb_data_s5pv210, }, { + .name = "s5pv310-fb", + .driver_data = (unsigned long)&s3c_fb_data_s5pv310, + }, { .name = "s3c2443-fb", .driver_data = (unsigned long)&s3c_fb_data_s3c2443, },