From patchwork Sat Apr 26 20:38:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhilash Kesavan X-Patchwork-Id: 4069641 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 603869F1F4 for ; Sat, 26 Apr 2014 20:42:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 84C322022A for ; Sat, 26 Apr 2014 20:42:49 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B18EC20254 for ; Sat, 26 Apr 2014 20:42:44 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1We9O9-0002xW-1Z; Sat, 26 Apr 2014 20:39:57 +0000 Received: from mail-pa0-x230.google.com ([2607:f8b0:400e:c03::230]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1We9Nu-0002rF-Ba for linux-arm-kernel@lists.infradead.org; Sat, 26 Apr 2014 20:39:43 +0000 Received: by mail-pa0-f48.google.com with SMTP id hz1so4352011pad.7 for ; Sat, 26 Apr 2014 13:39:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=bvxY4s7NHzrWKZpQV5+4msAfzn2a1KqYGHHXQWXjM48=; b=tYm8DZh+sHwlj85T1CPhRD5LHuQd8cLGJ+MuxB2DE11xmHuwlF4Pe2Lelj6NVqetFh 14vanQW6mgZDnvNaLurMsUn6RINXLp6UAOs/zSf3WH2DDkVgW27MsHVmoc+E6vc7jErc FyINe2yZPuWnmc9UuOBtNVmOdfjodfo1qtAg20ayzZ34p/VknBBGbD6havUuLZAq5Q/B 3DxfsyRn1xPCxdij9tFTK5c5bYHROb4eKMWlrkqh/zx/HojMR0gpyRXcBTDHWAP07zKb APqHASTxbSzOH5p112A0ySRTUwTZC29e6RrL/TftRJ4unmVbF1Nf6J/Sz/bC5WvCH2mx 872Q== X-Received: by 10.66.166.47 with SMTP id zd15mr15931415pab.0.1398544760812; Sat, 26 Apr 2014 13:39:20 -0700 (PDT) Received: from localhost.localdomain ([122.171.91.187]) by mx.google.com with ESMTPSA id ff4sm61718492pad.24.2014.04.26.13.39.16 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 26 Apr 2014 13:39:20 -0700 (PDT) From: Abhilash Kesavan To: linux-arm-kernel@lists.infradead.org, kgene.kim@samsung.com, t.figa@samsung.com, myungjoo.ham@samsung.com, rafael.j.wysocki@intel.com, linux-pm@vger.kernel.or, devicetree@vger.kernel.org Subject: [PATCH RFC 5/8] PM / devfreq: exynos5250: migrate to common-clock Date: Sun, 27 Apr 2014 02:08:45 +0530 Message-Id: <1398544728-2075-6-git-send-email-a.kesavan@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1398544728-2075-1-git-send-email-a.kesavan@samsung.com> References: <1398544728-2075-1-git-send-email-a.kesavan@samsung.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140426_133942_446580_E779C41D X-CRM114-Status: GOOD ( 17.82 ) X-Spam-Score: 0.0 (/) Cc: cw00.choi@samsung.com, kesavan.abhilash@gmail.com, b.zolnierkie@samsung.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Andrew Bresticker Use the common-clock framework to scale frequencies for the various peripheral clocks on the Exynos5250. Signed-off-by: Andrew Bresticker Signed-off-by: Abhilash Kesavan --- drivers/devfreq/exynos/exynos5_bus.c | 131 +++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 12 deletions(-) diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c index ab54a69..d4b8a68 100644 --- a/drivers/devfreq/exynos/exynos5_bus.c +++ b/drivers/devfreq/exynos/exynos5_bus.c @@ -57,7 +57,6 @@ struct busfreq_data_int { struct notifier_block pm_notifier; struct mutex lock; struct pm_qos_request int_req; - struct clk *int_clk; }; struct int_bus_opp_table { @@ -66,6 +65,17 @@ struct int_bus_opp_table { unsigned long volt; }; +struct int_clk_table { + unsigned int idx; + unsigned long freq; +}; + +struct int_clk { + const char *clk_name; + struct clk *clk; + struct int_clk_table *freq_table; +}; + static struct int_bus_opp_table exynos5_int_opp_table[] = { {LV_0, 266000, 1025000}, {LV_1, 200000, 1025000}, @@ -75,6 +85,98 @@ static struct int_bus_opp_table exynos5_int_opp_table[] = { {0, 0, 0}, }; +static struct int_clk_table aclk_166[] = { + {LV_0, 167000}, + {LV_1, 111000}, + {LV_2, 84000}, + {LV_3, 84000}, + {LV_4, 42000}, +}; + +static struct int_clk_table aclk_200[] = { + {LV_0, 200000}, + {LV_1, 160000}, + {LV_2, 160000}, + {LV_3, 134000}, + {LV_4, 100000}, +}; + +static struct int_clk_table aclk_266[] = { + {LV_0, 267000}, + {LV_1, 200000}, + {LV_2, 160000}, + {LV_3, 134000}, + {LV_4, 100000}, +}; + +static struct int_clk_table aclk_333[] = { + {LV_0, 333000}, + {LV_1, 167000}, + {LV_2, 111000}, + {LV_3, 111000}, + {LV_4, 42000}, +}; + +static struct int_clk_table aclk_300_disp1[] = { + {LV_0, 267000}, + {LV_1, 267000}, + {LV_2, 267000}, + {LV_3, 267000}, + {LV_4, 200000}, +}; + +static struct int_clk_table aclk_300_gscl[] = { + {LV_0, 267000}, + {LV_1, 267000}, + {LV_2, 267000}, + {LV_3, 200000}, + {LV_4, 100000}, +}; + +#define EXYNOS5_INT_CLK(name, tbl) { \ + .clk_name = name, \ + .freq_table = tbl, \ +} + +static struct int_clk exynos5_int_clks[] = { + EXYNOS5_INT_CLK("aclk166_d", aclk_166), + EXYNOS5_INT_CLK("aclk200_d", aclk_200), + EXYNOS5_INT_CLK("aclk266_d", aclk_266), + EXYNOS5_INT_CLK("aclk333_d", aclk_333), + EXYNOS5_INT_CLK("aclk300_disp1_d", aclk_300_disp1), + EXYNOS5_INT_CLK("aclk300_gscl_d", aclk_300_gscl), +}; + +static int exynos5_int_set_rate(struct busfreq_data_int *data, + unsigned long rate) +{ + int index, i; + + for (index = 0; index < ARRAY_SIZE(exynos5_int_opp_table); index++) { + if (exynos5_int_opp_table[index].clk == rate) + break; + } + + if (index >= _LV_END) + return -EINVAL; + + /* Change the system clock divider values */ + for (i = 0; i < ARRAY_SIZE(exynos5_int_clks); i++) { + struct int_clk *clk_info = &exynos5_int_clks[i]; + int ret; + + ret = clk_set_rate(clk_info->clk, + clk_info->freq_table[index].freq * 1000); + if (ret) { + dev_err(data->dev, "Failed to set %s rate: %d\n", + clk_info->clk_name, ret); + return ret; + } + } + + return 0; +} + static int exynos5_int_setvolt(struct busfreq_data_int *data, unsigned long volt) { @@ -126,7 +228,7 @@ static int exynos5_busfreq_int_target(struct device *dev, unsigned long *_freq, if (err) goto out; - err = clk_set_rate(data->int_clk, freq * 1000); + err = exynos5_int_set_rate(data, freq); if (err) goto out; @@ -229,7 +331,7 @@ static int exynos5_busfreq_int_pm_notifier_event(struct notifier_block *this, if (err) goto unlock; - err = clk_set_rate(data->int_clk, freq * 1000); + err = exynos5_int_set_rate(data, freq); if (err) goto unlock; @@ -309,10 +411,15 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev) return PTR_ERR(data->vdd_int); } - data->int_clk = devm_clk_get(dev, "int_clk"); - if (IS_ERR(data->int_clk)) { - dev_err(dev, "Cannot get clock \"int_clk\"\n"); - return PTR_ERR(data->int_clk); + for (i = 0; i < ARRAY_SIZE(exynos5_int_clks); i++) { + struct int_clk *clk_info = &exynos5_int_clks[i]; + + clk_info->clk = devm_clk_get(dev, clk_info->clk_name); + if (IS_ERR(clk_info->clk)) { + dev_err(dev, "Failed to get clock %s\n", + clk_info->clk_name); + return PTR_ERR(clk_info->clk); + } } rcu_read_lock(); @@ -329,16 +436,16 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev) rcu_read_unlock(); data->curr_freq = initial_freq; - err = clk_set_rate(data->int_clk, initial_freq * 1000); + err = exynos5_int_setvolt(data, initial_volt); + if (err) + return err; + + err = exynos5_int_set_rate(data, initial_freq); if (err) { dev_err(dev, "Failed to set initial frequency\n"); return err; } - err = exynos5_int_setvolt(data, initial_volt); - if (err) - return err; - platform_set_drvdata(pdev, data); busfreq_mon_reset(ppmu_data);