From patchwork Wed Aug 21 13:49:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seungwon Jeon X-Patchwork-Id: 2847745 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 7C307BF546 for ; Wed, 21 Aug 2013 13:49:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CDE8E20514 for ; Wed, 21 Aug 2013 13:49:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DCDD920512 for ; Wed, 21 Aug 2013 13:49:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751960Ab3HUNt0 (ORCPT ); Wed, 21 Aug 2013 09:49:26 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:44066 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751921Ab3HUNtZ (ORCPT ); Wed, 21 Aug 2013 09:49:25 -0400 Received: from epcpsbgr5.samsung.com (u145.gpu120.samsung.co.kr [203.254.230.145]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MRV00APTVQ7BOD0@mailout3.samsung.com> for linux-mmc@vger.kernel.org; Wed, 21 Aug 2013 22:49:24 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [203.254.230.50]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id BA.EA.11618.465C4125; Wed, 21 Aug 2013 22:49:24 +0900 (KST) X-AuditID: cbfee691-b7fef6d000002d62-dc-5214c5645634 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 3C.91.31505.465C4125; Wed, 21 Aug 2013 22:49:24 +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 <0MRV00E0XVQCLL80@mmp1.samsung.com>; Wed, 21 Aug 2013 22:49:24 +0900 (KST) From: Seungwon Jeon To: linux-mmc@vger.kernel.org Cc: 'Chris Ball' , 'Jaehoon Chung' , 'Alim Akhtar' References: In-reply-to: Subject: [PATCH 02/14] mmc: dw_mmc: exynos: add variable delay tuning sequence Date: Wed, 21 Aug 2013 22:49:24 +0900 Message-id: <002701ce9e75$3eca9870$bc5fc950$%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: Ac03z3aCvVFr8FaITt2vKVQKst76fw3OcIrwS9fJ1BA= Content-language: ko X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrCIsWRmVeSWpSXmKPExsVy+t8zI92UoyJBBp1vxSwezNvGZrH99UY2 ixu/2lgtjvzvZ3Rg8Th0ZS2jR9+WVYwenzfJBTBHcdmkpOZklqUW6dslcGU8fnCLveCpQsXN nkaWBsa5Ul2MnBwSAiYSW7dPY4GwxSQu3FvP1sXIxSEksIxR4lXzVlaYon3NX6ESixgl+p5u Y4Vw/jBKHNr5gB2kik1AS+LvmzfMILaIgKzEzz8X2EBsZoEyibd37gPFOYAauCVWNweBhDkF eCTW/ekEKxcW8JO4sOo9E0gJi4CqxJ8lcSBhXgFbibun97FA2IISPybfYwEpYRZQl5gyJRdi uLzE5jVvwYZLAIUf/dWF2G8lcXj5EVaIEhGJfS/eMUJ8coxd4shGsIksAgIS3yYfYoFolZXY dIAZokRS4uCKGywTGCVmIdk7C2HvLCR7ZyFZsICRZRWjaGpBckFxUnqRqV5xYm5xaV66XnJ+ 7iZGSAxO3MF4/4D1IcZkoO0TmaVEk/OBMZxXEm9obGZkYWpiamxkbmlGmrCSOK96i3WgkEB6 YklqdmpqQWpRfFFpTmrxIUYmDk6pBkbLQjPm2huK34snfM/z38ebz+Rdxrr+pNdLNvZ5jK5v FSPTXmWu/xhu7xbXeyRb9K5+JsM+devLqZ2f87e0LjOtXNeYLntuepLd2ol6ZyY21wTvnP/o 3MJ/PQor6h/P7P91SubH669bt2++8m+/hef0jb8Me24b3BO4sujvEtGcjtWO+23zdysrsRRn JBpqMRcVJwIAUwlm/tcCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrEKsWRmVeSWpSXmKPExsVy+t9jAd2UoyJBBgd3C1k8mLeNzWL7641s Fjd+tbFaHPnfz+jA4nHoylpGj74tqxg9Pm+SC2COamC0yUhNTEktUkjNS85PycxLt1XyDo53 jjc1MzDUNbS0MFdSyEvMTbVVcvEJ0HXLzAFap6RQlphTChQKSCwuVtK3wzQhNMRN1wKmMULX NyQIrsfIAA0krGPMePzgFnvBU4WKmz2NLA2Mc6W6GDk5JARMJPY1f2WDsMUkLtxbD2RzcQgJ LGKU6Hu6jRXC+cMocWjnA3aQKjYBLYm/b94wg9giArISP/9cAOtmFiiTeHvnPlCcA6iBW2J1 cxBImFOAR2Ldn06wcmEBP4kLq94zgZSwCKhK/FkSBxLmFbCVuHt6HwuELSjxY/I9FpASZgF1 iSlTciGGy0tsXvMWbLgEUPjRX12I/VYSh5cfYYUoEZHY9+Id4wRGoVlIBs1CGDQLyaBZSDoW MLKsYhRNLUguKE5KzzXSK07MLS7NS9dLzs/dxAiO8WfSOxhXNVgcYhTgYFTi4b2wUyRIiDWx rLgy9xCjBAezkgjv5/1AId6UxMqq1KL8+KLSnNTiQ4zJQF9OZJYSTc4Hpp+8knhDYxMzI0sj MwsjE3Nz0oSVxHkPtloHCgmkJ5akZqemFqQWwWxh4uCUamCcwpv7f+mK+5vOLnjUE3Jr06qH B8z2aoi/e1q3aIpX2k4uXz6TaV/Of/85eVnnotVTGWU9u6u3BN/rV7/9+ekMtttXP4Xo+Us4 fZM/MT3Y9sGSFW/m/C6JZdhdu2Vz1VTrXGbRBStfzzrxlWtfCcPB7/YrcsLub7tx546yO/fZ vzdE5l9lX11wXV6JpTgj0VCLuag4EQDrdBcNNQMAAA== 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.7 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 Implements variable delay tuning. In this change, exynos host can determine the correct sampling point for the HS200 and SDR104 speed mode. Signed-off-by: Seungwon Jeon --- drivers/mmc/host/dw_mmc-exynos.c | 124 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 124 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 866edef..90f9335 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -14,8 +14,10 @@ #include #include #include +#include #include #include +#include #include "dw_mmc.h" #include "dw_mmc-pltfm.h" @@ -150,6 +152,127 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) return 0; } +static inline u8 dw_mci_exynos_get_clksmpl(struct dw_mci *host) +{ + return SDMMC_CLKSEL_CCLK_SAMPLE(mci_readl(host, CLKSEL)); +} + +static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) +{ + u32 clksel; + clksel = mci_readl(host, CLKSEL); + clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); + mci_writel(host, CLKSEL, clksel); +} + +static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) +{ + u32 clksel; + u8 sample; + + clksel = mci_readl(host, CLKSEL); + sample = (clksel + 1) & 0x7; + clksel = (clksel & ~0x7) | sample; + mci_writel(host, CLKSEL, clksel); + return sample; +} + +static s8 dw_mci_exynos_get_best_clksmpl(u8 candiates) +{ + const u8 iter = 8; + u8 __c; + s8 i, loc = -1; + + for (i = 0; i < iter; i++) { + __c = ror8(candiates, i); + if ((__c & 0xc7) == 0xc7) { + loc = i; + goto out; + } + } + + for (i = 0; i < iter; i++) { + __c = ror8(candiates, i); + if ((__c & 0x83) == 0x83) { + loc = i; + goto out; + } + } + +out: + return loc; +} + +static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode, + struct dw_mci_tuning_data *tuning_data) +{ + struct dw_mci *host = slot->host; + struct mmc_host *mmc = slot->mmc; + const u8 *blk_pattern = tuning_data->blk_pattern; + u8 *blk_test; + unsigned int blksz = tuning_data->blksz; + u8 start_smpl, smpl, candiates = 0; + s8 found = -1; + int ret = 0; + + blk_test = kmalloc(blksz, GFP_KERNEL); + if (!blk_test) + return -ENOMEM; + + start_smpl = dw_mci_exynos_get_clksmpl(host); + + do { + struct mmc_request mrq = {NULL}; + struct mmc_command cmd = {0}; + struct mmc_command stop = {0}; + struct mmc_data data = {0}; + struct scatterlist sg; + + cmd.opcode = opcode; + cmd.arg = 0; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + stop.opcode = MMC_STOP_TRANSMISSION; + stop.arg = 0; + stop.flags = MMC_RSP_R1B | MMC_CMD_AC; + + data.blksz = blksz; + data.blocks = 1; + data.flags = MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; + + sg_init_one(&sg, blk_test, blksz); + mrq.cmd = &cmd; + mrq.stop = &stop; + mrq.data = &data; + host->mrq = &mrq; + + mci_writel(host, TMOUT, ~0); + smpl = dw_mci_exynos_move_next_clksmpl(host); + + mmc_wait_for_req(mmc, &mrq); + + if (!cmd.error && !data.error) { + if (!memcmp(blk_pattern, blk_test, blksz)) + candiates |= (1 << smpl); + } else { + dev_dbg(host->dev, + "Tuning error: cmd.error:%d, data.error:%d\n", + cmd.error, data.error); + } + } while (start_smpl != smpl); + + found = dw_mci_exynos_get_best_clksmpl(candiates); + if (found >= 0) + dw_mci_exynos_set_clksmpl(host, found); + else + ret = -EIO; + + kfree(blk_test); + return ret; +} + /* Common capabilities of Exynos4/Exynos5 SoC */ static unsigned long exynos_dwmmc_caps[4] = { MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR | @@ -166,6 +289,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { .prepare_command = dw_mci_exynos_prepare_command, .set_ios = dw_mci_exynos_set_ios, .parse_dt = dw_mci_exynos_parse_dt, + .execute_tuning = dw_mci_exynos_execute_tuning, }; static const struct of_device_id dw_mci_exynos_match[] = {