From patchwork Wed Nov 16 09:04:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 82461 Delivered-To: patch@linaro.org Received: by 10.182.1.168 with SMTP id 8csp56669obn; Wed, 16 Nov 2016 01:06:02 -0800 (PST) X-Received: by 10.99.235.10 with SMTP id t10mr6012594pgh.95.1479287162853; Wed, 16 Nov 2016 01:06:02 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l65si30929499pge.112.2016.11.16.01.06.02; Wed, 16 Nov 2016 01:06:02 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-media-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-media-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964818AbcKPJF6 (ORCPT + 4 others); Wed, 16 Nov 2016 04:05:58 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:57066 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934094AbcKPJFj (ORCPT ); Wed, 16 Nov 2016 04:05:39 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OGQ00DM5990ZH80@mailout1.w1.samsung.com>; Wed, 16 Nov 2016 09:05:24 +0000 (GMT) Received: from eusmges3.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20161116090523eucas1p28d92d69b6587954e629de00b405feb2e~He80ijKJR0300603006eucas1p2A; Wed, 16 Nov 2016 09:05:23 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3.samsung.com (EUCPMTA) with SMTP id 74.60.11330.3512C285; Wed, 16 Nov 2016 09:05:23 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20161116090522eucas1p2110bfe357718cfb5aebd750201a1b22e~He8zrFR_C0300603006eucas1p2-; Wed, 16 Nov 2016 09:05:22 +0000 (GMT) X-AuditID: cbfec7f2-f79556d000002c42-29-582c21534084 Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 82.58.10494.7312C285; Wed, 16 Nov 2016 09:04:55 +0000 (GMT) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OGQ00GDL98JU960@eusync2.samsung.com>; Wed, 16 Nov 2016 09:05:22 +0000 (GMT) From: Marek Szyprowski To: linux-media@vger.kernel.org, linux-samsung-soc@vger.kernel.org Cc: Marek Szyprowski , Sylwester Nawrocki , Krzysztof Kozlowski , Seung-Woo Kim , Bartlomiej Zolnierkiewicz , Javier Martinez Canillas , Andrzej Hajda , Inki Dae Subject: [PATCH 8/9] s5p-mfc: Rework clock handling Date: Wed, 16 Nov 2016 10:04:57 +0100 Message-id: <1479287098-30493-9-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1479287098-30493-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrMIsWRmVeSWpSXmKPExsWy7djPc7rBijoRBjOPiljcWneO1WLjjPWs FpPuT2CxePN2DZPF+fMb2C16NmxltZhxfh+Txdojd9ktDr9pB3Inv2Rz4PLYtKqTzWNL/112 j74tqxg9Pm+SC2CJ4rJJSc3JLEst0rdL4Mr4sWw7S0GnecXxc62MDYz/dboYOTkkBEwkfh6e xgxhi0lcuLeerYuRi0NIYCmjxNLVh5khnM+MEqfb5gA5HGAdh7qtIeLLGCXOdzxngXAamCSm P5vHDjKKTcBQouttFxuILSLgJLFw1l92kCJmgSdMEt8a+sD2CQsYS5xqOANmswioSky5fJQJ xOYV8JBYuqSdCeImOYmTxyazgticAp4ST2a+AtsmIdDMLnH9fzvUSbISmw5A/eAiMeHibihb WOLV8S3sELaMxOXJ3SwQdj+jRFOrNoQ9g1Hi3FteCNta4vDxi2C7mAX4JCZtmw41nleio00I osRD4s+E46wQtqPE46N97BDPz2GUaNj3jHECo8wCRoZVjCKppcW56anFxnrFibnFpXnpesn5 uZsYgVF9+t/xTzsYv56wOsQowMGoxMO7QF07Qog1say4MvcQowQHs5II73VBnQgh3pTEyqrU ovz4otKc1OJDjNIcLErivHsWXAkXEkhPLEnNTk0tSC2CyTJxcEo1MJquuZCtc2j99MADr5If B+xIe7ba7vrTk7WaJ9P0J73X+60hPZ/thYjfl1XrVWWUnnxfka0TO/PmZw6m3emb17/U73dd bBG/duqnzjfhj8X1LzxVdOLqmB50JTXiztyImldx+0UiD4R93Gzs+6rXJ3F3WdgP2wdMbZzS txYlbRN9EmOVy+Dm8F6JpTgj0VCLuag4EQApgOq05gIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrILMWRmVeSWpSXmKPExsVy+t/xK7rmijoRBu++mVrcWneO1WLjjPWs FpPuT2CxePN2DZPF+fMb2C16NmxltZhxfh+Txdojd9ktDr9pB3Inv2Rz4PLYtKqTzWNL/112 j74tqxg9Pm+SC2CJcrPJSE1MSS1SSM1Lzk/JzEu3VQoNcdO1UFLIS8xNtVWK0PUNCVJSKEvM KQXyjAzQgINzgHuwkr5dglvGj2XbWQo6zSuOn2tlbGD8r9PFyMEhIWAicajbuouRE8gUk7hw bz1bFyMXh5DAEkaJd3sXsIIkhASamCRmz60AsdkEDCW63naxgdgiAk4SC2f9ZQdpYBZ4wiRx 5t1+JpCEsICxxKmGM8wgNouAqsSUy0fB4rwCHhJLl7QzQWyTkzh5bDLYAk4BT4knM1+xgBwk BFSz/KjpBEbeBYwMqxhFUkuLc9Nzi430ihNzi0vz0vWS83M3MQKDe9uxn1t2MHa9Cz7EKMDB qMTDu0BdO0KINbGsuDL3EKMEB7OSCO91QZ0IId6UxMqq1KL8+KLSnNTiQ4ymQDdNZJYSTc4H Rl5eSbyhiaG5paGRsYWFuZGRkjjv1A9XwoUE0hNLUrNTUwtSi2D6mDg4pRoYHYKY2M/Ynt3O 3O6iYFDcf139voSvdZLCc8a71tKFZvplPAXpHvorA+dHbDT/f6pqM/dHu+UPD4nknxe4EZem mVDAl8915UeMiVvFytNNmrtlq76+O+w4IXJ/0dq1ptZaj931tZKTeCT8zFRK1eNuS05bMPne oRCBdS+cfu85wqXNfCT4loASS3FGoqEWc1FxIgCtL18vhAIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20161116090522eucas1p2110bfe357718cfb5aebd750201a1b22e X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?TWFyZWsgU3p5cHJvd3NraRtTUlBPTC1LZXJuZWwgKFRQKRs=?= =?UTF-8?B?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?TWFyZWsgU3p5cHJvd3NraRtTUlBPTC1LZXJuZWwgKFRQKRtT?= =?UTF-8?B?YW1zdW5nIEVsZWN0cm9uaWNzG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20161116090522eucas1p2110bfe357718cfb5aebd750201a1b22e X-RootMTR: 20161116090522eucas1p2110bfe357718cfb5aebd750201a1b22e References: <1479287098-30493-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org This patch changes the code for handling clocks. Now clocks are defined per each device variant, what is a preparation for adding support for Exynos 5433 MFC V8, which has more clocks than all previous versions. Also use devm_clk_get() to simplify cleanup path. Signed-off-by: Marek Szyprowski --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 8 ++ drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 9 ++- drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 98 ++++++++++--------------- 3 files changed, 56 insertions(+), 59 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 72af819a4f47..fa674e8e09a8 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1433,6 +1433,8 @@ static int s5p_mfc_resume(struct device *dev) .buf_size = &buf_size_v5, .buf_align = &mfc_buf_align_v5, .fw_name[0] = "s5p-mfc.fw", + .clk_names = {"mfc", "sclk_mfc"}, + .num_clocks = 2, .use_clock_gating = true, }; @@ -1466,6 +1468,8 @@ static int s5p_mfc_resume(struct device *dev) * for init buffer command */ .fw_name[1] = "s5p-mfc-v6-v2.fw", + .clk_names = {"mfc"}, + .num_clocks = 1, }; static struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = { @@ -1493,6 +1497,8 @@ static int s5p_mfc_resume(struct device *dev) .buf_size = &buf_size_v7, .buf_align = &mfc_buf_align_v7, .fw_name[0] = "s5p-mfc-v7.fw", + .clk_names = {"mfc", "sclk_mfc"}, + .num_clocks = 2, }; static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = { @@ -1520,6 +1526,8 @@ static int s5p_mfc_resume(struct device *dev) .buf_size = &buf_size_v8, .buf_align = &mfc_buf_align_v8, .fw_name[0] = "s5p-mfc-v8.fw", + .clk_names = {"mfc"}, + .num_clocks = 1, }; static const struct of_device_id exynos_mfc_match[] = { diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 58b15c212dd2..ab23236aa942 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -104,6 +104,8 @@ static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b) #define S5P_MFC_R2H_CMD_ENC_BUFFER_FUL_RET 16 #define S5P_MFC_R2H_CMD_ERR_RET 32 +#define MFC_MAX_CLOCKS 4 + #define mfc_read(dev, offset) readl(dev->regs_base + (offset)) #define mfc_write(dev, data, offset) writel((data), dev->regs_base + \ (offset)) @@ -197,9 +199,12 @@ struct s5p_mfc_buf { * struct s5p_mfc_pm - power management data structure */ struct s5p_mfc_pm { - struct clk *clock; struct clk *clock_gate; + const char **clk_names; + struct clk *clocks[MFC_MAX_CLOCKS]; + int num_clocks; bool use_clock_gating; + struct device *device; }; @@ -235,6 +240,8 @@ struct s5p_mfc_variant { struct s5p_mfc_buf_size *buf_size; struct s5p_mfc_buf_align *buf_align; char *fw_name[MFC_FW_MAX_VERSIONS]; + const char *clk_names[MFC_MAX_CLOCKS]; + int num_clocks; bool use_clock_gating; }; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index 796dac85746a..eb85cedc5ef3 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -18,56 +18,42 @@ #include "s5p_mfc_debug.h" #include "s5p_mfc_pm.h" -#define MFC_GATE_CLK_NAME "mfc" -#define MFC_SCLK_NAME "sclk_mfc" - static struct s5p_mfc_pm *pm; static struct s5p_mfc_dev *p_dev; static atomic_t clk_ref; int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) { - int ret = 0; + int i; pm = &dev->pm; p_dev = dev; - pm->use_clock_gating = dev->variant->use_clock_gating; - pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME); - if (IS_ERR(pm->clock_gate)) { - mfc_err("Failed to get clock-gating control\n"); - ret = PTR_ERR(pm->clock_gate); - goto err_g_ip_clk; - } - if (dev->variant->version != MFC_VERSION_V6) { - pm->clock = clk_get(&dev->plat_dev->dev, MFC_SCLK_NAME); - if (IS_ERR(pm->clock)) { - mfc_info("Failed to get MFC special clock control\n"); - pm->clock = NULL; + pm->num_clocks = dev->variant->num_clocks; + pm->clk_names = dev->variant->clk_names; + pm->device = &dev->plat_dev->dev; + pm->clock_gate = NULL; + + /* clock control */ + for (i = 0; i < pm->num_clocks; i++) { + pm->clocks[i] = devm_clk_get(pm->device, pm->clk_names[i]); + if (IS_ERR(pm->clocks[i])) { + mfc_err("Failed to get clock: %s\n", + pm->clk_names[i]); + return PTR_ERR(pm->clocks[i]); } } - pm->device = &dev->plat_dev->dev; + if (dev->variant->use_clock_gating) + pm->clock_gate = pm->clocks[0]; + pm_runtime_enable(pm->device); atomic_set(&clk_ref, 0); - return 0; - - clk_put(pm->clock_gate); - pm->clock_gate = NULL; -err_g_ip_clk: - return ret; } void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) { - if (dev->variant->version != MFC_VERSION_V6 && - pm->clock) { - clk_put(pm->clock); - pm->clock = NULL; - } - clk_put(pm->clock_gate); - pm->clock_gate = NULL; pm_runtime_disable(pm->device); } @@ -76,8 +62,6 @@ int s5p_mfc_clock_on(void) atomic_inc(&clk_ref); mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); - if (!pm->use_clock_gating) - return 0; return clk_enable(pm->clock_gate); } @@ -86,50 +70,48 @@ void s5p_mfc_clock_off(void) atomic_dec(&clk_ref); mfc_debug(3, "- %d\n", atomic_read(&clk_ref)); - if (!pm->use_clock_gating) - return; clk_disable(pm->clock_gate); } int s5p_mfc_power_on(void) { - int ret; + int i, ret = 0; ret = pm_runtime_get_sync(pm->device); - if (ret) + if (ret < 0) return ret; - ret = clk_prepare_enable(pm->clock_gate); - if (ret) - goto err_pm; - - if (pm->clock) { - ret = clk_prepare_enable(pm->clock); - if (ret) - goto err_gate; + /* clock control */ + for (i = 0; i < pm->num_clocks; i++) { + ret = clk_prepare_enable(pm->clocks[i]); + if (ret < 0) { + mfc_err("clock prepare failed for clock: %s\n", + pm->clk_names[i]); + i++; + goto err; + } } - if (pm->use_clock_gating) - clk_disable(pm->clock_gate); - return 0; + /* prepare for software clock gating */ + clk_disable(pm->clock_gate); -err_gate: - clk_disable_unprepare(pm->clock_gate); -err_pm: - pm_runtime_put_sync(pm->device); + return 0; +err: + while (--i > 0) + clk_disable_unprepare(pm->clocks[i]); + pm_runtime_put(pm->device); return ret; - } int s5p_mfc_power_off(void) { - if (pm->clock) - clk_disable_unprepare(pm->clock); + int i; + + /* finish software clock gating */ + clk_enable(pm->clock_gate); - if (pm->use_clock_gating) - clk_unprepare(pm->clock_gate); - else - clk_disable_unprepare(pm->clock_gate); + for (i = 0; i < pm->num_clocks; i++) + clk_disable_unprepare(pm->clocks[i]); return pm_runtime_put_sync(pm->device); }