From patchwork Tue Mar 26 17:29:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sylwester Nawrocki/Kernel \\(PLT\\) /SRPOL/Staff Engineer/Samsung Electronics" X-Patchwork-Id: 2341761 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 0757C3FD40 for ; Tue, 26 Mar 2013 17:30:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753354Ab3CZRaY (ORCPT ); Tue, 26 Mar 2013 13:30:24 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:62484 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753332Ab3CZRaW (ORCPT ); Tue, 26 Mar 2013 13:30:22 -0400 Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MKA00D1V3ACS190@mailout4.samsung.com>; Wed, 27 Mar 2013 02:30:21 +0900 (KST) X-AuditID: cbfee61a-b7fa86d0000045ae-41-5151db2d3446 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 84.DA.17838.D2BD1515; Wed, 27 Mar 2013 02:30:21 +0900 (KST) Received: from amdc1344.digital.local ([106.116.147.32]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MKA004BH39YZW90@mmp1.samsung.com>; Wed, 27 Mar 2013 02:30:21 +0900 (KST) From: Sylwester Nawrocki To: linux-media@vger.kernel.org Cc: kyungmin.park@samsung.com, myungjoo.ham@samsung.com, dh09.lee@samsung.com, shaik.samsung@gmail.com, arun.kk@samsung.com, a.hajda@samsung.com, linux-samsung-soc@vger.kernel.org, Sylwester Nawrocki Subject: [PATCH v2 04/10] s5p-fimc: Add support for PIXELASYNCMx clocks Date: Tue, 26 Mar 2013 18:29:46 +0100 Message-id: <1364318992-20562-5-git-send-email-s.nawrocki@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1364318992-20562-1-git-send-email-s.nawrocki@samsung.com> References: <1364318992-20562-1-git-send-email-s.nawrocki@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprMLMWRmVeSWpSXmKPExsVy+t9jAV3d24GBBs2/FC1urTvHavHx1G1W i+vn7SzONr1ht+jZsJXVYsb5fUwWtxtXsFkcftPOarFu5yR2B06PnbPusnv0bVnF6PF5k1wA cxSXTUpqTmZZapG+XQJXxqcHW5kL5htUdBxbw9jA2K/excjJISFgInF5zX92CFtM4sK99Wxd jFwcQgKLGCW+HTnACOF0MEnsaTwJVsUmYCjRe7SPEcQWEZCXeNJ7A6yDWeAJo8SfEweYQBLC Au4S/X/bwYpYBFQlXv58ygxi8wq4SfyceJ+li5EDaJ2CxJxJNiBhTqDy5TeOsIDYQkAlzxu2 sE1g5F3AyLCKUTS1ILmgOCk911CvODG3uDQvXS85P3cTIzionkntYFzZYHGIUYCDUYmHd0Nw QKAQa2JZcWXuIUYJDmYlEV7BjYGBQrwpiZVVqUX58UWlOanFhxilOViUxHkPtFoHCgmkJ5ak ZqemFqQWwWSZODilGhgXrzlo9CtA81zM9pIlW5nXCnROOSgT7HJr/p3OXr0CtmmVbpIhryom CL/VY9hm+uRJRIv/nPQ1Hzo4bK8d0j9Ru4BLdLfujv/fLgUz9Vqefbru6TZ/g1nzrl7Rnr15 RlJr9/atcwK3P1tfmbVNMsE8yG/PrO3FRSExq3OlZvVG6k3as5+5Y9F/JZbijERDLeai4kQA SFhkiCYCAAA= Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org This patch ads handling of clocks for the CAMBLK subsystem which is a glue logic for FIMC-IS or LCD controller and FIMC IP. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park --- Changes since v1: - Do not keep PXLASYNC clocks always enabled. Enable PXLASYNC0 clock only if video pipeline including FIMC-IS was opened. Enabling this clock only when it is actually used decreases power consumption a bit. --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 83 ++++++++++++++++++++---- drivers/media/platform/s5p-fimc/fimc-mdevice.h | 10 +++ 2 files changed, 82 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index abd3ad3..c5bc0d1 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -151,26 +151,48 @@ static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state) * __fimc_pipeline_open - update the pipeline information, enable power * of all pipeline subdevs and the sensor clock * @me: media entity to start graph walk with - * @prep: true to acquire sensor (and csis) subdevs + * @prepare: true to walk the current pipeline and acquire all subdevs * * Called with the graph mutex held. */ static int __fimc_pipeline_open(struct fimc_pipeline *p, - struct media_entity *me, bool prep) + struct media_entity *me, bool prepare) { + struct fimc_md *fmd = entity_to_fimc_mdev(me); + struct v4l2_subdev *sd; int ret; - if (prep) + if (WARN_ON(p == NULL || me == NULL)) + return -EINVAL; + + if (prepare) fimc_pipeline_prepare(p, me); - if (p->subdevs[IDX_SENSOR] == NULL) + sd = p->subdevs[IDX_SENSOR]; + if (sd == NULL) return -EINVAL; - ret = fimc_md_set_camclk(p->subdevs[IDX_SENSOR], true); - if (ret) - return ret; + /* Disable PXLASYNC clock if this pipeline includes FIMC-IS */ + if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) { + ret = clk_prepare_enable(fmd->wbclk[CLK_IDX_WB_B]); + if (ret < 0) + return ret; + } + ret = fimc_md_set_camclk(sd, true); + if (ret < 0) + goto err_wbclk; + + ret = fimc_pipeline_s_power(p, 1); + if (!ret) + return 0; + + fimc_md_set_camclk(sd, false); - return fimc_pipeline_s_power(p, 1); +err_wbclk: + if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) + clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); + + return ret; } /** @@ -181,15 +203,24 @@ static int __fimc_pipeline_open(struct fimc_pipeline *p, */ static int __fimc_pipeline_close(struct fimc_pipeline *p) { + struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL; + struct fimc_md *fmd; int ret = 0; - if (!p || !p->subdevs[IDX_SENSOR]) + if (WARN_ON(sd == NULL)) return -EINVAL; if (p->subdevs[IDX_SENSOR]) { ret = fimc_pipeline_s_power(p, 0); - fimc_md_set_camclk(p->subdevs[IDX_SENSOR], false); + fimc_md_set_camclk(sd, false); } + + fmd = entity_to_fimc_mdev(&sd->entity); + + /* Disable PXLASYNC clock if this pipeline includes FIMC-IS */ + if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) + clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); + return ret == -ENXIO ? 0 : ret; } @@ -957,7 +988,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) } /* - * The peripheral sensor clock management. + * The peripheral sensor and CAM_BLK (PIXELASYNCMx) clocks management. */ static void fimc_md_put_clocks(struct fimc_md *fmd) { @@ -970,6 +1001,14 @@ static void fimc_md_put_clocks(struct fimc_md *fmd) clk_put(fmd->camclk[i].clock); fmd->camclk[i].clock = ERR_PTR(-EINVAL); } + + /* Writeback (PIXELASYNCMx) clocks */ + for (i = 0; i < FIMC_MAX_WBCLKS; i++) { + if (IS_ERR(fmd->wbclk[i])) + continue; + clk_put(fmd->wbclk[i]); + fmd->wbclk[i] = ERR_PTR(-EINVAL); + } } static int fimc_md_get_clocks(struct fimc_md *fmd) @@ -1006,6 +1045,28 @@ static int fimc_md_get_clocks(struct fimc_md *fmd) if (ret) fimc_md_put_clocks(fmd); + if (!fmd->use_isp) + return 0; + /* + * For now get only PIXELASYNCM1 clock (Writeback B/ISP), + * leave PIXELASYNCM0 out for the LCD Writeback driver. + */ + fmd->wbclk[CLK_IDX_WB_A] = ERR_PTR(-EINVAL); + + for (i = CLK_IDX_WB_B; i < FIMC_MAX_WBCLKS; i++) { + snprintf(clk_name, sizeof(clk_name), "pxl_async%u", i); + clock = clk_get(dev, clk_name); + if (IS_ERR(clock)) { + v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s\n", + clk_name); + ret = PTR_ERR(clock); + break; + } + fmd->wbclk[i] = clock; + } + if (ret) + fimc_md_put_clocks(fmd); + return ret; } diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.h b/drivers/media/platform/s5p-fimc/fimc-mdevice.h index 5d6146e..46f3b82 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.h +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.h @@ -41,6 +41,13 @@ #define FIMC_MAX_SENSORS 8 #define FIMC_MAX_CAMCLKS 2 +/* LCD/ISP Writeback clocks (PIXELASYNCMx) */ +enum { + CLK_IDX_WB_A, + CLK_IDX_WB_B, + FIMC_MAX_WBCLKS +}; + struct fimc_csis_info { struct v4l2_subdev *sd; int id; @@ -73,6 +80,7 @@ struct fimc_sensor_info { * @num_sensors: actual number of registered sensors * @camclk: external sensor clock information * @fimc: array of registered fimc devices + * @use_isp: set to true when FIMC-IS subsystem is used * @media_dev: top level media device * @v4l2_dev: top level v4l2_device holding up the subdevs * @pdev: platform device this media device is hooked up into @@ -87,8 +95,10 @@ struct fimc_md { struct fimc_sensor_info sensor[FIMC_MAX_SENSORS]; int num_sensors; struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS]; + struct clk *wbclk[FIMC_MAX_WBCLKS]; struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS]; struct fimc_dev *fimc[FIMC_MAX_DEVS]; + bool use_isp; struct media_device media_dev; struct v4l2_device v4l2_dev; struct platform_device *pdev;