From patchwork Wed Aug 21 13:49:10 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seungwon Jeon X-Patchwork-Id: 2847744 Return-Path: X-Original-To: patchwork-linux-mmc@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 B3FAF9F271 for ; Wed, 21 Aug 2013 13:49:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D4DD420512 for ; Wed, 21 Aug 2013 13:49:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8D38020516 for ; Wed, 21 Aug 2013 13:49:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751955Ab3HUNtO (ORCPT ); Wed, 21 Aug 2013 09:49:14 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:44045 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751921Ab3HUNtN (ORCPT ); Wed, 21 Aug 2013 09:49:13 -0400 Received: from epcpsbgr2.samsung.com (u142.gpu120.samsung.co.kr [203.254.230.142]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MRV00APOVPZBOD0@mailout3.samsung.com> for linux-mmc@vger.kernel.org; Wed, 21 Aug 2013 22:49:11 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [203.254.230.50]) by epcpsbgr2.samsung.com (EPCPMTA) with SMTP id 88.81.08825.755C4125; Wed, 21 Aug 2013 22:49:11 +0900 (KST) X-AuditID: cbfee68e-b7f276d000002279-95-5214c5579d53 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 59.91.31505.755C4125; Wed, 21 Aug 2013 22:49:11 +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 <0MRV00GDWVPYKI30@mmp1.samsung.com>; Wed, 21 Aug 2013 22:49:11 +0900 (KST) From: Seungwon Jeon To: linux-mmc@vger.kernel.org Cc: 'Chris Ball' , 'Jaehoon Chung' , 'Alim Akhtar' References: In-reply-to: Subject: [PATCH 01/14] mmc: dw_mmc: add support tuning scheme Date: Wed, 21 Aug 2013 22:49:10 +0900 Message-id: <002601ce9e75$36fa0400$a4ee0c00$%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+t8zI93woyJBBoe/CVg8mLeNzWL7641s Fjd+tbFaHPnfz+jA4nHoylpGj74tqxg9Pm+SC2CO4rJJSc3JLEst0rdL4MqYv/40e8EGs4o1 M2axNDBO1+li5OCQEDCRaP0a28XICWSKSVy4t56ti5GLQ0hgGaPE/sWTWSASJhI3d95hgkgs YpR4t+M4C4TzB6hq0kewKjYBLYm/b94wg9giArISP/9cYAOxmQXKJN7euc8Msk1IgFtidXMQ SJhTgEdi3Z9OsHJhAVuJw+8WgNksAqoSf7u7WEFsXqB4+4zXzBC2oMSPyfdYQMYwC6hLTJmS CzFdXmLzmrfMEL+oSzz6qwtxgJXE4eVHWCFKRCT2vXjHCPHKIXaJN9c1ITYJSHybfIgFolVW YtMBZogSSYmDK26wTGCUmIVk7yyEvbOQ7J2FZMECRpZVjKKpBckFxUnpRUZ6xYm5xaV56XrJ +bmbGCEx2LeD8eYB60OMyUDbJzJLiSbnA2M4ryTe0NjMyMLUxNTYyNzSjDRhJXFetRbrQCGB 9MSS1OzU1ILUovii0pzU4kOMTBycUg2MWmeC+Fg1xHhy/JbtW3g/Rd6cIeFV07Tc//ELlJ7v bxB+Efy/9f7iGovQN182am0oL7wikbiwafK0p2bdNsfYmacK7ctN0/5SfkjGyvrsxnbNig/e Bxu/7v5kueJIkknqfSN+BbuJAblxC/8kfVZ+U377qovehsONGbrrexY8j1MwmyVuP3uVEktx RqKhFnNRcSIAjTUamNcCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrMKsWRmVeSWpSXmKPExsVy+t9jAd3woyJBBp1beCwezNvGZrH99UY2 ixu/2lgtjvzvZ3Rg8Th0ZS2jR9+WVYwenzfJBTBHNTDaZKQmpqQWKaTmJeenZOal2yp5B8c7 x5uaGRjqGlpamCsp5CXmptoqufgE6Lpl5gCtU1IoS8wpBQoFJBYXK+nbYZoQGuKmawHTGKHr GxIE12NkgAYS1jFmzF9/mr1gg1nFmhmzWBoYp+t0MXJySAiYSNzceYcJwhaTuHBvPVsXIxeH kMAiRol3O46zQDh/GCX2T/rIAlLFJqAl8ffNG2YQW0RAVuLnnwtsIDazQJnE2zv3geIcQA3c Equbg0DCnAI8Euv+dIKVCwvYShx+twDMZhFQlfjb3cUKYvMCxdtnvGaGsAUlfky+xwIyhllA XWLKlFyI6fISm9e8BZsuARR+9FcX4gAricPLj7BClIhI7HvxjnECo9AsJINmIQyahWTQLCQd CxhZVjGKphYkFxQnpeca6RUn5haX5qXrJefnbmIER/kz6R2MqxosDjEKcDAq8fBe2CkSJMSa WFZcmXuIUYKDWUmE9/N+oBBvSmJlVWpRfnxRaU5q8SHGZKA3JzJLiSbnAxNQXkm8obGJmZGl kZmFkYm5OWnCSuK8B1utA4UE0hNLUrNTUwtSi2C2MHFwSjUwTgnZ7MPiy/DvZ9b3rc5bu5yO Zv/4Ir2ANci81f7Djr5tdpeMRPxYpiX3ME97OfGu4bzjro+maIS/3iJTGuFdLfzpa5XRD5+n n/4J2AVfduB8dvpy4BbWB6uOCH05JH03PDuI3celfLZB3c6UAoZvFbvO/H5tN0VabObCmRJS ys08L+acTpvzW4mlOCPRUIu5qDgRAJzVVWU2AwAA 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 For the speed modes HS200 and SDR104, tuning is needed to determine the correct sampling point. Actual tuning procedure is provided by specific host controller driver. This patch defines the tuning command and tuning data. Additionally, 'struct dw_mci_slot' is moved to header file to consider the extensive usages in driver. Signed-off-by: Seungwon Jeon --- drivers/mmc/host/dw_mmc.c | 93 +++++++++++++++++++++++++++++---------------- drivers/mmc/host/dw_mmc.h | 43 +++++++++++++++++++++ 2 files changed, 103 insertions(+), 33 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index ee5f167..5d1123f 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -76,40 +76,34 @@ struct idmac_desc { }; #endif /* CONFIG_MMC_DW_IDMAC */ -/** - * struct dw_mci_slot - MMC slot state - * @mmc: The mmc_host representing this slot. - * @host: The MMC controller this slot is using. - * @quirks: Slot-level quirks (DW_MCI_SLOT_QUIRK_XXX) - * @wp_gpio: If gpio_is_valid() we'll use this to read write protect. - * @ctype: Card type for this slot. - * @mrq: mmc_request currently being processed or waiting to be - * processed, or NULL when the slot is idle. - * @queue_node: List node for placing this node in the @queue list of - * &struct dw_mci. - * @clock: Clock rate configured by set_ios(). Protected by host->lock. - * @flags: Random state bits associated with the slot. - * @id: Number of this slot. - * @last_detect_state: Most recently observed card detect state. - */ -struct dw_mci_slot { - struct mmc_host *mmc; - struct dw_mci *host; - - int quirks; - int wp_gpio; - - u32 ctype; - - struct mmc_request *mrq; - struct list_head queue_node; +static const u8 tuning_blk_pattern_4bit[] = { + 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, + 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, + 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, + 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, + 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, + 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, + 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, + 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, +}; - unsigned int clock; - unsigned long flags; -#define DW_MMC_CARD_PRESENT 0 -#define DW_MMC_CARD_NEED_INIT 1 - int id; - int last_detect_state; +static const u8 tuning_blk_pattern_8bit[] = { + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, + 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, + 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, + 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, + 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, + 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, + 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, + 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, + 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, + 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, + 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, + 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, + 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, }; #if defined(CONFIG_DEBUG_FS) @@ -939,6 +933,38 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) } } +static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) +{ + struct dw_mci_slot *slot = mmc_priv(mmc); + struct dw_mci *host = slot->host; + const struct dw_mci_drv_data *drv_data = host->drv_data; + struct dw_mci_tuning_data tuning_data; + int err = -ENOSYS; + + if (opcode == MMC_SEND_TUNING_BLOCK_HS200) { + if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) { + tuning_data.blk_pattern = tuning_blk_pattern_8bit; + tuning_data.blksz = sizeof(tuning_blk_pattern_8bit); + } else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) { + tuning_data.blk_pattern = tuning_blk_pattern_4bit; + tuning_data.blksz = sizeof(tuning_blk_pattern_4bit); + } else { + return -EINVAL; + } + } else if (opcode == MMC_SEND_TUNING_BLOCK) { + tuning_data.blk_pattern = tuning_blk_pattern_4bit; + tuning_data.blksz = sizeof(tuning_blk_pattern_4bit); + } else { + dev_err(host->dev, + "Undefined command(%d) for tuning\n", opcode); + return -EINVAL; + } + + if (drv_data && drv_data->execute_tuning) + err = drv_data->execute_tuning(slot, opcode, &tuning_data); + return err; +} + static const struct mmc_host_ops dw_mci_ops = { .request = dw_mci_request, .pre_req = dw_mci_pre_req, @@ -947,6 +973,7 @@ static const struct mmc_host_ops dw_mci_ops = { .get_ro = dw_mci_get_ro, .get_cd = dw_mci_get_cd, .enable_sdio_irq = dw_mci_enable_sdio_irq, + .execute_tuning = dw_mci_execute_tuning, }; static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 81b2994..661c6f9 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -184,6 +184,47 @@ extern int dw_mci_resume(struct dw_mci *host); #endif /** + * struct dw_mci_slot - MMC slot state + * @mmc: The mmc_host representing this slot. + * @host: The MMC controller this slot is using. + * @quirks: Slot-level quirks (DW_MCI_SLOT_QUIRK_XXX) + * @wp_gpio: If gpio_is_valid() we'll use this to read write protect. + * @ctype: Card type for this slot. + * @mrq: mmc_request currently being processed or waiting to be + * processed, or NULL when the slot is idle. + * @queue_node: List node for placing this node in the @queue list of + * &struct dw_mci. + * @clock: Clock rate configured by set_ios(). Protected by host->lock. + * @flags: Random state bits associated with the slot. + * @id: Number of this slot. + * @last_detect_state: Most recently observed card detect state. + */ +struct dw_mci_slot { + struct mmc_host *mmc; + struct dw_mci *host; + + int quirks; + int wp_gpio; + + u32 ctype; + + struct mmc_request *mrq; + struct list_head queue_node; + + unsigned int clock; + unsigned long flags; +#define DW_MMC_CARD_PRESENT 0 +#define DW_MMC_CARD_NEED_INIT 1 + int id; + int last_detect_state; +}; + +struct dw_mci_tuning_data { + const u8 *blk_pattern; + unsigned int blksz; +}; + +/** * dw_mci driver data - dw-mshc implementation specific driver data. * @caps: mmc subsystem specified capabilities of the controller(s). * @init: early implementation specific initialization. @@ -203,5 +244,7 @@ struct dw_mci_drv_data { void (*prepare_command)(struct dw_mci *host, u32 *cmdr); void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); int (*parse_dt)(struct dw_mci *host); + int (*execute_tuning)(struct dw_mci_slot *slot, u32 opcode, + struct dw_mci_tuning_data *tuning_data); }; #endif /* _DW_MMC_H_ */