From patchwork Mon Jun 27 13:22:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ritesh Harjani X-Patchwork-Id: 9200567 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8A22C607D3 for ; Mon, 27 Jun 2016 13:23:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C21528564 for ; Mon, 27 Jun 2016 13:23:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6E81428596; Mon, 27 Jun 2016 13:23:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F04F928564 for ; Mon, 27 Jun 2016 13:23:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751827AbcF0NXj (ORCPT ); Mon, 27 Jun 2016 09:23:39 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:56247 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751745AbcF0NXi (ORCPT ); Mon, 27 Jun 2016 09:23:38 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id AD3FB613AE; Mon, 27 Jun 2016 13:23:37 +0000 (UTC) Received: from rharjani-linux.qualcomm.com (unknown [202.46.23.54]) (using TLSv1.1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: riteshh@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 7F42961376; Mon, 27 Jun 2016 13:23:31 +0000 (UTC) From: Ritesh Harjani To: ulf.hansson@linaro.org, linux-mmc@vger.kernel.org Cc: linux-arm-msm@vger.kernel.org, adrian.hunter@intel.com, alex.lemberg@sandisk.com, mateusz.nowak@intel.com, Yuliy.Izrailov@sandisk.com, jh80.chung@samsung.com, dongas86@gmail.com, asutoshd@codeaurora.org, zhangfei.gao@gmail.com, sthumma@codeaurora.org, kdorfman@codeaurora.org, david.griego@linaro.org, stummala@codeaurora.org, venkatg@codeaurora.org, shawn.lin@rock-chips.com, Subhash Jadavani , Ritesh Harjani Subject: [PATCH RFCv2 03/10] mmc: core: Add command queue initialzation support Date: Mon, 27 Jun 2016 18:52:30 +0530 Message-Id: <1467033757-32498-4-git-send-email-riteshh@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1467033757-32498-1-git-send-email-riteshh@codeaurora.org> References: <1467033757-32498-1-git-send-email-riteshh@codeaurora.org> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Asutosh Das Command Queueing (CQ) feature is introduced to eMMC standard in revision 5.1. CQ includes new commands for issuing tasks to the device, for ordering the execution of previously issued tasks and for additional task management functions. This patch adds initialization and enabling of command queue in the card and controller. If the card and the controller support CQ, then it is enabled. Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani [riteshh@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Ritesh Harjani --- drivers/mmc/core/mmc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/card.h | 6 ++++++ include/linux/mmc/host.h | 6 ++++++ include/linux/mmc/mmc.h | 1 + 4 files changed, 63 insertions(+) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 77734c8..e0432b0 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1371,6 +1371,43 @@ static int mmc_hs200_tuning(struct mmc_card *card) return mmc_execute_tuning(card); } +static int mmc_select_cmdq(struct mmc_card *card) +{ + struct mmc_host *host = card->host; + int ret = 0; + + if (!host->cmdq_ops) { + pr_err("%s: host controller doesn't support CMDQ\n", + mmc_hostname(host)); + return 0; + } + + ret = mmc_set_blocklen(card, MMC_CARD_CMDQ_BLK_SIZE); + if (ret) + goto out; + + ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_CMDQ, 1, + card->ext_csd.generic_cmd6_time); + if (ret) + goto out; + + mmc_card_set_cmdq(card); + ret = host->cmdq_ops->enable(card->host); + if (ret) { + pr_err("%s: failed (%d) enabling CMDQ on host\n", + mmc_hostname(host), ret); + mmc_card_clr_cmdq(card); + ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_CMDQ, 0, + card->ext_csd.generic_cmd6_time); + if (ret) + goto out; + } + + pr_debug("%s: CMDQ enabled on card\n", mmc_hostname(host)); +out: + return ret; +} + /* * Handle the detection and initialisation of a card. * @@ -1399,6 +1436,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * respond. * mmc_go_idle is needed for eMMC that are asleep */ +reinit: mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ @@ -1677,6 +1715,18 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, if (!oldcard) host->card = card; + if (card->ext_csd.cmdq_support && (card->host->caps2 & + MMC_CAP2_CMD_QUEUE)) { + err = mmc_select_cmdq(card); + if (err) { + pr_err("%s: selecting CMDQ mode: failed: %d\n", + mmc_hostname(card->host), err); + card->ext_csd.cmdq_support = 0; + oldcard = card; + goto reinit; + } + } + return 0; free_card: diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index f74db84..85a0d8d 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -14,6 +14,8 @@ #include #include +#define MMC_CARD_CMDQ_BLK_SIZE 512 + struct mmc_cid { unsigned int manfid; char prod_name[8]; @@ -265,6 +267,7 @@ struct mmc_card { #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ #define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ +#define MMC_STATE_CMDQ (1<<12) /* card is in cmd queue mode */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -433,6 +436,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) +#define mmc_card_cmdq(c) ((c)->state & MMC_STATE_CMDQ) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) @@ -443,6 +447,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) +#define mmc_card_set_cmdq(c) ((c)->state |= MMC_STATE_CMDQ) +#define mmc_card_clr_cmdq(c) ((c)->state &= ~MMC_STATE_CMDQ) /* * Quirk add/remove for MMC products. diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 3842208..3c4a569 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -79,6 +79,11 @@ struct mmc_ios { #define MMC_SET_DRIVER_TYPE_D 3 }; +struct mmc_cmdq_host_ops { + int (*enable)(struct mmc_host *host); + void (*disable)(struct mmc_host *host, bool soft); +}; + struct mmc_host_ops { /* * It is optional for the host to implement pre_req and post_req in @@ -230,6 +235,7 @@ struct mmc_host { struct device class_dev; int index; const struct mmc_host_ops *ops; + const struct mmc_cmdq_host_ops *cmdq_ops; struct mmc_pwrseq *pwrseq; unsigned int f_min; unsigned int f_max; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 694c189..55913d9 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -272,6 +272,7 @@ struct _mmc_csd { * EXT_CSD fields */ +#define EXT_CSD_CMDQ 15 /* R/W */ #define EXT_CSD_FLUSH_CACHE 32 /* W */ #define EXT_CSD_CACHE_CTRL 33 /* R/W */ #define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */