From patchwork Tue Dec 1 17:18:59 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: m-karicheri2@ti.com X-Patchwork-Id: 2229 Return-path: Envelope-to: mchehab@infradead.org Delivery-date: Tue, 01 Dec 2009 17:19:21 +0000 Received: from bombadil.infradead.org [18.85.46.34] by pedra with IMAP (fetchmail-6.3.6) for (single-drop); Tue, 01 Dec 2009 15:22:55 -0200 (BRST) Received: from vger.kernel.org ([209.132.176.167]) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1NFWNk-00041s-UB; Tue, 01 Dec 2009 17:19:21 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753710AbZLARTI (ORCPT + 1 other); Tue, 1 Dec 2009 12:19:08 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753653AbZLARTH (ORCPT ); Tue, 1 Dec 2009 12:19:07 -0500 Received: from arroyo.ext.ti.com ([192.94.94.40]:44547 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753421AbZLARTF (ORCPT ); Tue, 1 Dec 2009 12:19:05 -0500 Received: from dlep33.itg.ti.com ([157.170.170.112]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id nB1HJ7tL010891 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 1 Dec 2009 11:19:08 -0600 Received: from legion.dal.design.ti.com (localhost [127.0.0.1]) by dlep33.itg.ti.com (8.13.7/8.13.7) with ESMTP id nB1HJ4KF015251; Tue, 1 Dec 2009 11:19:05 -0600 (CST) Received: from gt516km11.gt.design.ti.com (gt516km11.gt.design.ti.com [158.218.100.179]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id nB1HJ4Z18094; Tue, 1 Dec 2009 11:19:04 -0600 (CST) Received: from gt516km11.gt.design.ti.com (localhost.localdomain [127.0.0.1]) by gt516km11.gt.design.ti.com (8.13.1/8.13.1) with ESMTP id nB1HJ32S031461; Tue, 1 Dec 2009 12:19:03 -0500 Received: (from a0868495@localhost) by gt516km11.gt.design.ti.com (8.13.1/8.13.1/Submit) id nB1HJ147031456; Tue, 1 Dec 2009 12:19:01 -0500 From: m-karicheri2@ti.com To: linux-media@vger.kernel.org, hverkuil@xs4all.nl, khilman@deeprootsystems.com Cc: davinci-linux-open-source@linux.davincidsp.com, hvaibhav@ti.com, Muralidharan Karicheri Subject: [PATCH - v1 1/2] V4L - vpfe capture - make clocks configurable Date: Tue, 1 Dec 2009 12:18:59 -0500 Message-Id: <1259687940-31435-1-git-send-email-m-karicheri2@ti.com> X-Mailer: git-send-email 1.6.0.4 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Muralidharan Karicheri v1 - updated based on comments from Vaibhav Hiremath. On DM365 we use only vpss master clock, where as on DM355 and DM6446, we use vpss master and slave clocks for vpfe capture and AM3517 we use internal clock and pixel clock. So this patch makes it configurable on a per platform basis. This is needed for supporting DM365 for which patches will be available soon. Tested-by: Vaibhav Hiremath , Muralidharan Karicheri Acked-by: Vaibhav Hiremath Signed-off-by: Muralidharan Karicheri --- drivers/media/video/davinci/vpfe_capture.c | 98 +++++++++++++++++---------- include/media/davinci/vpfe_capture.h | 11 ++- 2 files changed, 70 insertions(+), 39 deletions(-) diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 12a1b3d..c3468ee 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -1787,61 +1787,87 @@ static struct vpfe_device *vpfe_initialize(void) return vpfe_dev; } +/** + * vpfe_disable_clock() - Disable clocks for vpfe capture driver + * @vpfe_dev - ptr to vpfe capture device + * + * Disables clocks defined in vpfe configuration. + */ static void vpfe_disable_clock(struct vpfe_device *vpfe_dev) { struct vpfe_config *vpfe_cfg = vpfe_dev->cfg; + int i; - clk_disable(vpfe_cfg->vpssclk); - clk_put(vpfe_cfg->vpssclk); - clk_disable(vpfe_cfg->slaveclk); - clk_put(vpfe_cfg->slaveclk); - v4l2_info(vpfe_dev->pdev->driver, - "vpfe vpss master & slave clocks disabled\n"); + for (i = 0; i < vpfe_cfg->num_clocks; i++) { + clk_disable(vpfe_dev->clks[i]); + clk_put(vpfe_dev->clks[i]); + } + kfree(vpfe_dev->clks); + v4l2_info(vpfe_dev->pdev->driver, "vpfe capture clocks disabled\n"); } +/** + * vpfe_enable_clock() - Enable clocks for vpfe capture driver + * @vpfe_dev - ptr to vpfe capture device + * + * Enables clocks defined in vpfe configuration. The function + * assumes that at least one clock is to be defined which is + * true as of now. re-visit this if this assumption is not true + */ static int vpfe_enable_clock(struct vpfe_device *vpfe_dev) { struct vpfe_config *vpfe_cfg = vpfe_dev->cfg; - int ret = -ENOENT; + int i; - vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master"); - if (NULL == vpfe_cfg->vpssclk) { - v4l2_err(vpfe_dev->pdev->driver, "No clock defined for" - "vpss_master\n"); - return ret; - } + if (!vpfe_cfg->num_clocks) + return 0; - if (clk_enable(vpfe_cfg->vpssclk)) { - v4l2_err(vpfe_dev->pdev->driver, - "vpfe vpss master clock not enabled\n"); - goto out; - } - v4l2_info(vpfe_dev->pdev->driver, - "vpfe vpss master clock enabled\n"); + vpfe_dev->clks = kzalloc(vpfe_cfg->num_clocks * + sizeof(struct clock *), GFP_KERNEL); - vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave"); - if (NULL == vpfe_cfg->slaveclk) { - v4l2_err(vpfe_dev->pdev->driver, - "No clock defined for vpss slave\n"); - goto out; + if (NULL == vpfe_dev->clks) { + v4l2_err(vpfe_dev->pdev->driver, "Memory allocation failed\n"); + return -ENOMEM; } - if (clk_enable(vpfe_cfg->slaveclk)) { - v4l2_err(vpfe_dev->pdev->driver, - "vpfe vpss slave clock not enabled\n"); - goto out; + for (i = 0; i < vpfe_cfg->num_clocks; i++) { + if (NULL == vpfe_cfg->clocks[i]) { + v4l2_err(vpfe_dev->pdev->driver, + "clock %s is not defined in vpfe config\n", + vpfe_cfg->clocks[i]); + goto out; + } + + vpfe_dev->clks[i] = clk_get(vpfe_dev->pdev, + vpfe_cfg->clocks[i]); + if (NULL == vpfe_dev->clks[i]) { + v4l2_err(vpfe_dev->pdev->driver, + "Failed to get clock %s\n", + vpfe_cfg->clocks[i]); + goto out; + } + + if (clk_enable(vpfe_dev->clks[i])) { + v4l2_err(vpfe_dev->pdev->driver, + "vpfe clock %s not enabled\n", + vpfe_cfg->clocks[i]); + goto out; + } + + v4l2_info(vpfe_dev->pdev->driver, "vpss clock %s enabled", + vpfe_cfg->clocks[i]); } - v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n"); return 0; out: - if (vpfe_cfg->vpssclk) - clk_put(vpfe_cfg->vpssclk); - if (vpfe_cfg->slaveclk) - clk_put(vpfe_cfg->slaveclk); - - return -1; + for (i = 0; i < vpfe_cfg->num_clocks; i++) { + if (vpfe_dev->clks[i]) + clk_put(vpfe_dev->clks[i]); + } + kfree(vpfe_dev->clks); + return -EFAULT; } + /* * vpfe_probe : This function creates device entries by register * itself to the V4L2 driver and initializes fields of each diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h index d863e5e..7b62a5c 100644 --- a/include/media/davinci/vpfe_capture.h +++ b/include/media/davinci/vpfe_capture.h @@ -31,8 +31,6 @@ #include #include -#define VPFE_CAPTURE_NUM_DECODERS 5 - /* Macros */ #define VPFE_MAJOR_RELEASE 0 #define VPFE_MINOR_RELEASE 0 @@ -91,9 +89,14 @@ struct vpfe_config { char *card_name; /* ccdc name */ char *ccdc; - /* vpfe clock */ + /* vpfe clock. Obsolete! Will be removed in next patch */ struct clk *vpssclk; + /* Obsolete! Will be removed in next patch */ struct clk *slaveclk; + /* number of clocks */ + int num_clocks; + /* clocks used for vpfe capture */ + char *clocks[]; }; struct vpfe_device { @@ -104,6 +107,8 @@ struct vpfe_device { struct v4l2_subdev **sd; /* vpfe cfg */ struct vpfe_config *cfg; + /* clock ptrs for vpfe capture */ + struct clk **clks; /* V4l2 device */ struct v4l2_device v4l2_dev; /* parent device */