From patchwork Wed Dec 31 06:43:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alim Akhtar X-Patchwork-Id: 5554311 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 19B069F344 for ; Wed, 31 Dec 2014 06:52:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CC535201BC for ; Wed, 31 Dec 2014 06:52:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 92CC3201B4 for ; Wed, 31 Dec 2014 06:52:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751237AbaLaGwF (ORCPT ); Wed, 31 Dec 2014 01:52:05 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:56340 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751197AbaLaGwC (ORCPT ); Wed, 31 Dec 2014 01:52:02 -0500 Received: from epcpsbgr2.samsung.com (u142.gpu120.samsung.co.kr [203.254.230.142]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NHF006THPQONG00@mailout2.samsung.com>; Wed, 31 Dec 2014 15:52:01 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.134]) by epcpsbgr2.samsung.com (EPCPMTA) with SMTP id 85.BA.11124.01D93A45; Wed, 31 Dec 2014 15:52:00 +0900 (KST) X-AuditID: cbfee68e-f79b46d000002b74-7a-54a39d10e476 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id A8.22.09430.01D93A45; Wed, 31 Dec 2014 15:52:00 +0900 (KST) Received: from chromebld-server.sisodomain.com ([107.108.73.106]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NHF0009YPNPWLO0@mmp1.samsung.com>; Wed, 31 Dec 2014 15:52:00 +0900 (KST) From: Alim Akhtar To: linux-mmc@vger.kernel.org Cc: chris@printf.net, ulf.hansson@linaro.org, jh80.chung@samsung.com, tgih.jun@samsung.com, dianders@chromium.org, alim.akhtar@gmail.com, kgene@kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org, a.kesavan@samsung.com Subject: [PATCH v3 1/4] mmc: dw_mmc: exynos: incorporate ciu_div into timing property Date: Wed, 31 Dec 2014 12:13:02 +0530 Message-id: <1420008185-24758-2-git-send-email-alim.akhtar@samsung.com> X-Mailer: git-send-email 2.2.0 In-reply-to: <1420008185-24758-1-git-send-email-alim.akhtar@samsung.com> References: <1420008185-24758-1-git-send-email-alim.akhtar@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpkkeLIzCtJLcpLzFFi42JZI2LSpiswd3GIwY1GU4vHaxYzWSy9VW0x 4fJ2Rov5R86xWpxddpDN4savNlaL/sevmS02Pb7GanHkfz+jxYzz+5gsPty/yGxxfG24A4/H 7IaLLB47Z91l99i0qpPN4861PWwem5fUe9x4tZDJo2/LKkaPz5vkAjiiuGxSUnMyy1KL9O0S uDKmtK9jLrhsX3Hr2h+mBsa7xl2MnBwSAiYSHe/XMELYYhIX7q1n62Lk4hASWMoosWPLfDaY osev/zFDJBYxSvz4+5wVwpnAJHF41QpWkCo2AW2Ju9O3MIHYIgKyEj//XAAbxSwwj0ni9rQP zCAJYYFwiWN/l4CNZRFQldg5cTdQMwcHr4C7xMnrORDb5CS23HrEDmJzCnhI7G55CtYqBFSy /tVBdpCZEgKX2CUan39jhpgjIPFt8iEWkDkSQIs3HWCGmCMpcXDFDZYJjMILGBlWMYqmFiQX FCelFxnpFSfmFpfmpesl5+duYgTGzOl/z/p2MN48YH2IUYCDUYmH94bd4hAh1sSy4srcQ4ym QBsmMkuJJucDIzOvJN7Q2MzIwtTE1NjI3NJMSZw3QepnsJBAemJJanZqakFqUXxRaU5q8SFG Jg5OqQbGZVOCJvNdeSvdH7SEv1rWQb/hFNOz1cuCj8zffcIvY2q2UaXzvSuTDJy3TeYNPSYi snbVuT+TjucrmFnY1BXXBBhs2Mx5+q5xDc8sxdlvHxubLDlkl7qsPzxHXkX3yMlrizfZPpx0 YWtXgaiaUfeJkxpRq1e+X2pz8fL2vjMyU2+Lvzq86tQ/FiWW4oxEQy3mouJEAG3yq6+UAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrNIsWRmVeSWpSXmKPExsVy+t9jAV2BuYtDDF5O07N4vGYxk8XSW9UW Ey5vZ7SYf+Qcq8XZZQfZLG78amO16H/8mtli0+NrrBZH/vczWsw4v4/J4sP9i8wWx9eGO/B4 zG64yOKxc9Zddo9NqzrZPO5c28PmsXlJvceNVwuZPPq2rGL0+LxJLoAjqoHRJiM1MSW1SCE1 Lzk/JTMv3VbJOzjeOd7UzMBQ19DSwlxJIS8xN9VWycUnQNctMwfoWCWFssScUqBQQGJxsZK+ HaYJoSFuuhYwjRG6viFBcD1GBmggYR1jxpT2dcwFl+0rbl37w9TAeNe4i5GTQ0LAROLx63/M ELaYxIV769m6GLk4hAQWMUr8+PucFcKZwCRxeNUKVpAqNgFtibvTtzCB2CICshI//1wA62AW mMckcXvaB7BRwgLhEsf+LmEDsVkEVCV2TtwN1MzBwSvgLnHyeg7ENjmJLbcesYPYnAIeErtb noK1CgGVrH91kH0CI+8CRoZVjKKpBckFxUnpuUZ6xYm5xaV56XrJ+bmbGMER+Ux6B+OqBotD jAIcjEo8vDfsFocIsSaWFVfmHmKU4GBWEuG9rAkU4k1JrKxKLcqPLyrNSS0+xGgKdNREZinR 5HxgssgriTc0NjEzsjQyszAyMTdXEudVsm8LERJITyxJzU5NLUgtgulj4uCUamDMPsN5JrLL cNJ804/BHNfF/xVKPnypo53YcyfaZNOdvoo4+9bDL1mffZHoil+crlbrPjvx0LktbDLMJl/r fkXsUDvfeDB9dsVSkYeiWxfUHL70S+8YW2qkd1/2J2aBGev8D9ZGaz49abNz+5KM1G97XpfN VFH/LRwSfslgSfxTplVLI/cw9GYpsRRnJBpqMRcVJwIAOZF0e94CAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 From: Seungwon Jeon ciu_div may not be common value for all speed mode. So, it needs to be attached to CLKSEL timing. This also introduce a new compatibale 'dw-mshc-hs200-timing' for selecting hs200 timing value Signed-off-by: Seungwon Jeon Signed-off-by: Alim Akhtar --- .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 15 ++-- drivers/mmc/host/dw_mmc-exynos.c | 81 ++++++++++++++------ drivers/mmc/host/dw_mmc-exynos.h | 1 + 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt index ee4fc05..06455de 100644 --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt @@ -23,10 +23,6 @@ Required Properties: - "samsung,exynos7-dw-mshc-smu": for controllers with Samsung Exynos7 specific extensions having an SMU. -* samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface - unit (ciu) clock. This property is applicable only for Exynos5 SoC's and - ignored for Exynos4 SoC's. The valid range of divider value is 0 to 7. - * samsung,dw-mshc-sdr-timing: Specifies the value of CIU clock phase shift value in transmit mode and CIU clock phase shift value in receive mode for single data rate mode operation. Refer notes below for the order of the cells and the @@ -37,11 +33,16 @@ Required Properties: data rate mode operation. Refer notes below for the order of the cells and the valid values. +* samsung,dw-mshc-hs200-timing: Similar with dw-mshc-sdr-timing. + Notes for the sdr-timing and ddr-timing values: The order of the cells should be - First Cell: CIU clock phase shift value for tx mode. - Second Cell: CIU clock phase shift value for rx mode. + - Thrid Cell: Specifies the divider value for the card interface + unit (ciu) clock. This property is applicable only for Exynos5 SoC's and + ignored for Exynos4 SoC's. The valid range of divider value is 0 to 7. Valid values for SDR and DDR CIU clock timing for Exynos5250: - valid value for tx phase shift and rx phase shift is 0 to 7. @@ -79,8 +80,8 @@ Example: broken-cd; fifo-depth = <0x80>; card-detect-delay = <200>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <2 3>; - samsung,dw-mshc-ddr-timing = <1 2>; + samsung,dw-mshc-sdr-timing = <2 3 3>; + samsung,dw-mshc-ddr-timing = <1 2 3>; + samsung,dw-mshc-hs200-timing = <0 2 3>; bus-width = <8>; }; diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 12a5eaa..be6530e 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -40,6 +40,7 @@ struct dw_mci_exynos_priv_data { u8 ciu_div; u32 sdr_timing; u32 ddr_timing; + u32 hs200_timing; u32 cur_speed; }; @@ -71,6 +72,21 @@ static struct dw_mci_exynos_compatible { }, }; +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) + return EXYNOS4412_FIXED_CIU_CLK_DIV; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) + return EXYNOS4210_FIXED_CIU_CLK_DIV; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; + else + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1; +} + static int dw_mci_exynos_priv_init(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv = host->priv; @@ -85,6 +101,8 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT); } + priv->ciu_div = dw_mci_exynos_get_ciu_div(host); + return 0; } @@ -92,7 +110,7 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv = host->priv; - host->bus_hz /= (priv->ciu_div + 1); + host->bus_hz /= priv->ciu_div; return 0; } @@ -177,9 +195,14 @@ 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_MMC_DDR52) { + if (ios->timing == MMC_TIMING_MMC_HS200) { + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + mci_writel(host, CLKSEL64, priv->hs200_timing); + else + mci_writel(host, CLKSEL, priv->hs200_timing); + } else if (ios->timing == MMC_TIMING_MMC_DDR52) { if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) mci_writel(host, CLKSEL64, priv->ddr_timing); @@ -208,6 +231,7 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) wanted = EXYNOS_CCLKIN_MIN; if (wanted != priv->cur_speed) { + u8 div = dw_mci_exynos_get_ciu_div(host); int ret = clk_set_rate(host->ciu_clk, wanted * div); if (ret) dev_warn(host->dev, @@ -220,14 +244,34 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) } } +static int dw_mci_exynos_dt_populate_timing(struct dw_mci *host, + unsigned int ctrl_type, + const char *propname, + u32 *out_values) +{ + struct device_node *np = host->dev->of_node; + u32 timing[3]; + int ret; + + ret = of_property_read_u32_array(np, propname, timing, 3); + if (ret) + return ret; + + if (ctrl_type == DW_MCI_TYPE_EXYNOS4412 || + ctrl_type == DW_MCI_TYPE_EXYNOS4210) + timing[2] = 0; + + *out_values = SDMMC_CLKSEL_TIMING(timing[0], timing[1], timing[2]); + + return 0; +} + + static int dw_mci_exynos_parse_dt(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv; struct device_node *np = host->dev->of_node; - u32 timing[2]; - u32 div = 0; - int idx; - int ret; + int idx, ret; priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -238,29 +282,20 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) priv->ctrl_type = exynos_compat[idx].ctrl_type; } - 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); + ret = dw_mci_exynos_dt_populate_timing(host, priv->ctrl_type, + "samsung,dw-mshc-sdr-timing", &priv->sdr_timing); if (ret) return ret; - priv->sdr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); - - ret = of_property_read_u32_array(np, - "samsung,dw-mshc-ddr-timing", timing, 2); + ret = dw_mci_exynos_dt_populate_timing(host, priv->ctrl_type, + "samsung,dw-mshc-ddr-timing", &priv->ddr_timing); if (ret) return ret; - priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); + dw_mci_exynos_dt_populate_timing(host, priv->ctrl_type, + "samsung,dw-mshc-hs200-timing", &priv->hs200_timing); host->priv = priv; + return 0; } diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h index 7872ce5..c04ecef 100644 --- a/drivers/mmc/host/dw_mmc-exynos.h +++ b/drivers/mmc/host/dw_mmc-exynos.h @@ -21,6 +21,7 @@ #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) +#define SDMMC_CLKSEL_GET_DIV(x) (((x) >> 24) & 0x7) #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ SDMMC_CLKSEL_CCLK_DRIVE(y) | \ SDMMC_CLKSEL_CCLK_DIVIDER(z))