From patchwork Fri Aug 30 15:13:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seungwon Jeon X-Patchwork-Id: 2852117 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 63641C0AB5 for ; Fri, 30 Aug 2013 15:13:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 03F262018D for ; Fri, 30 Aug 2013 15:13:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 213B920182 for ; Fri, 30 Aug 2013 15:13:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756548Ab3H3PNF (ORCPT ); Fri, 30 Aug 2013 11:13:05 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:46280 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756321Ab3H3PNE (ORCPT ); Fri, 30 Aug 2013 11:13:04 -0400 Received: from epcpsbgr3.samsung.com (u143.gpu120.samsung.co.kr [203.254.230.143]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MSC0023TNLRN5N0@mailout3.samsung.com> for linux-mmc@vger.kernel.org; Sat, 31 Aug 2013 00:13:03 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [203.254.230.47]) by epcpsbgr3.samsung.com (EPCPMTA) with SMTP id A3.07.22755.F76B0225; Sat, 31 Aug 2013 00:13:03 +0900 (KST) X-AuditID: cbfee68f-b7f656d0000058e3-60-5220b67fa153 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 11.EB.05832.F76B0225; Sat, 31 Aug 2013 00:13:03 +0900 (KST) Received: from DOTGIHJUN01 ([12.23.118.161]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MSC0011ZNLRYA10@mmp1.samsung.com>; Sat, 31 Aug 2013 00:13:03 +0900 (KST) From: Seungwon Jeon To: linux-mmc@vger.kernel.org Cc: 'Chris Ball' , 'Jaehoon Chung' References: In-reply-to: Subject: [PATCH 11/22] mmc: dw_mmc: exynos: adjust the clock rate with speed mode Date: Sat, 31 Aug 2013 00:13:03 +0900 Message-id: <000e01cea593$6c05ad50$441107f0$%jun@samsung.com> MIME-version: 1.0 Content-type: text/plain; charset=utf-8 Content-transfer-encoding: 7bit X-Mailer: Microsoft Office Outlook 12.0 Thread-index: Ac03z3aCvVFr8FaITt2vKVQKst76fw3OcIrwS9fJ1BAByUIdcA== Content-language: ko X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrPIsWRmVeSWpSXmKPExsVy+t8zfd36bQpBBo3HJC22v97IZnHjVxur xZH//YwOzB6Hrqxl9OjbsorR4/MmuQDmKC6blNSczLLUIn27BK6MR9s/shSck6t49/4xewNj v2QXIweHhICJxJupQCYnkCkmceHeerYuRi4OIYFljBKbvhxmh0iYSJz5MYkRIrGIUeLo4d9M EM4fRonJj38wglSxCWhJ/H3zhhnEFhGQlfj55wIbiM0s4C3xav4aRpBtQgLcEqubg0DCnAI8 Euv+dIKVCwsES3Qu3s0CUsIioCrxejUTSJhXwFZi7ea7zBC2oMSPyffASpgF1CWmTMmFGC4v sXnNW2aIV9QlHv3VhdjvJHG26SAjRImIxL4X78CulxDYxS4x/XID2HgWAQGJb5MPsUD0ykps OsAM8a2kxMEVN1gmMErMQrJ4FsLiWUgWz0KyYQEjyypG0dSC5ILipPQiY73ixNzi0rx0veT8 3E2MkMjr38F494D1IcZkoO0TmaVEk/OBkZtXEm9obGZkYWpiamxkbmlGmrCSOK9ai3WgkEB6 YklqdmpqQWpRfFFpTmrxIUYmDk6pBsY9p7/cWrVW8lhwJmf5bc9NjS77dkp1Xpq7p/qhS0xS tOPidcZTutvuXs/eJpJ5XbB+nVbTq66yZVxbk7d+e+wmq29asWD7k7sd3vFq1q8WsDu84b2X Ut7Czirg1Vko/Os4D8/Hsg2Mq12eddhe/uye5x3s3tP+dLGg+tb/fc94jfeHJzOfa1NiKc5I NNRiLipOBAAwjEXJ0gIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprLKsWRmVeSWpSXmKPExsVy+t9jAd36bQpBBtcOilpsf72RzeLGrzZW iyP/+xkdmD0OXVnL6NG3ZRWjx+dNcgHMUQ2MNhmpiSmpRQqpecn5KZl56bZK3sHxzvGmZgaG uoaWFuZKCnmJuam2Si4+AbpumTlAm5QUyhJzSoFCAYnFxUr6dpgmhIa46VrANEbo+oYEwfUY GaCBhHWMGY+2f2QpOCdX8e79Y/YGxn7JLkZODgkBE4kzPyYxQthiEhfurWfrYuTiEBJYxChx 9PBvJgjnD6PE5Mc/wKrYBLQk/r55wwxiiwjISvz8c4ENxGYW8JZ4NX8NUA0HUAO3xOrmIJAw pwCPxLo/nWDlwgLBEp2Ld7OAlLAIqEq8Xs0EEuYVsJVYu/kuM4QtKPFj8j2wEmYBdYkpU3Ih hstLbF7zlhkkLAEUfvRXF2K/k8TZpoOMECUiEvtevGOcwCg0C8mgWQiDZiEZNAtJxwJGllWM oqkFyQXFSem5RnrFibnFpXnpesn5uZsYwZH9THoH46oGi0OMAhyMSjy8O5crBAmxJpYVV+Ye YpTgYFYS4f24GCjEm5JYWZValB9fVJqTWnyIMRnoy4nMUqLJ+cCkk1cSb2hsYmZkaWRmYWRi bk6asJI478FW60AhgfTEktTs1NSC1CKYLUwcnFINjBH9cjZ6nf4bUsTyMrr9ft8Rerr35Xxz v4J0hg1T321V+77xycnEguvVJcf3mV34HnuY18G/VSuLSaF4zdojlZeMTjH8eqlx7vjMLf3h OXmMOwwyOHoTHk3P5ExkEWd+IOX/+Nas770n6qSklt2QtzyubCP0c2PTHP8II/Neo/7L6XZ9 b8RKlViKMxINtZiLihMBF5dTcjADAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 Exynos's host has divider logic before 'cclk_in' to controller core. It means that actual clock rate of ciu clock comes from this divider value. So, source clock should be adjusted along with 'ciu_div' which indicates the host's divider ratio. Setting clock rate basically fits the required speed. Specially, 'cclk_in' should have double rate of target speed in case of DDR 8-bit mode. Signed-off-by: Seungwon Jeon Tested-by: Alim Akhtar --- drivers/mmc/host/dw_mmc-exynos.c | 55 +++++++++++++++++++++++++++++--------- 1 files changed, 42 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index b86f518..d42e664 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -56,6 +56,8 @@ #define DWMCI_MPSCTRL_ENCRYPTION BIT(1) #define DWMCI_MPSCTRL_VALID BIT(0) +#define EXYNOS_CCLKIN_MIN 50000000 /* unit: HZ */ + /* Variations in Exynos specific dw-mshc controller */ enum dw_mci_exynos_type { DW_MCI_TYPE_EXYNOS4210, @@ -71,6 +73,7 @@ struct dw_mci_exynos_priv_data { u8 ciu_div; u32 sdr_timing; u32 ddr_timing; + u32 cur_speed; }; static struct dw_mci_exynos_compatible { @@ -114,16 +117,9 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) static int dw_mci_exynos_setup_clock(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv = host->priv; + unsigned long rate = clk_get_rate(host->ciu_clk); - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250 || - priv->ctrl_type == DW_MCI_TYPE_EXYNOS5420 || - priv->ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU) - host->bus_hz /= (priv->ciu_div + 1); - else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) - host->bus_hz /= EXYNOS4412_FIXED_CIU_CLK_DIV; - else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) - host->bus_hz /= EXYNOS4210_FIXED_CIU_CLK_DIV; - + host->bus_hz = rate / (priv->ciu_div + 1); return 0; } @@ -187,11 +183,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) { struct dw_mci_exynos_priv_data *priv = host->priv; + unsigned int wanted = ios->clock; + unsigned long actual; + u8 div = priv->ciu_div + 1; - if (ios->timing == MMC_TIMING_UHS_DDR50) + if (ios->timing == MMC_TIMING_UHS_DDR50) { mci_writel(host, CLKSEL, priv->ddr_timing); - else + /* Should be double rate for DDR mode */ + if (ios->bus_width == MMC_BUS_WIDTH_8) + wanted <<= 1; + } else { mci_writel(host, CLKSEL, priv->sdr_timing); + } + + /* Don't care if wanted clock is zero */ + if (!wanted) + return; + + /* Guaranteed minimum frequency for cclkin */ + if (wanted < EXYNOS_CCLKIN_MIN) + wanted = EXYNOS_CCLKIN_MIN; + + if (wanted != priv->cur_speed) { + int ret = clk_set_rate(host->ciu_clk, wanted * div); + if (ret) + dev_warn(host->dev, + "failed to set clk-rate %u error: %d\n", + wanted * div, ret); + actual = clk_get_rate(host->ciu_clk); + host->bus_hz = actual / div; + priv->cur_speed = wanted; + host->current_speed = 0; + } } static int dw_mci_exynos_parse_dt(struct dw_mci *host) @@ -214,8 +237,14 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) priv->ctrl_type = exynos_compat[idx].ctrl_type; } - of_property_read_u32(np, "samsung,dw-mshc-ciu-div", &div); - priv->ciu_div = div; + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) + priv->ciu_div = EXYNOS4412_FIXED_CIU_CLK_DIV - 1; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) + priv->ciu_div = EXYNOS4210_FIXED_CIU_CLK_DIV - 1; + else { + of_property_read_u32(np, "samsung,dw-mshc-ciu-div", &div); + priv->ciu_div = div; + } ret = of_property_read_u32_array(np, "samsung,dw-mshc-sdr-timing", timing, 2);