From patchwork Fri Mar 7 14:36:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seungwon Jeon X-Patchwork-Id: 3791901 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 A35429F369 for ; Fri, 7 Mar 2014 14:36:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 91FCC201F4 for ; Fri, 7 Mar 2014 14:36:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5E409201EF for ; Fri, 7 Mar 2014 14:36:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752716AbaCGOgX (ORCPT ); Fri, 7 Mar 2014 09:36:23 -0500 Received: from mailout4.samsung.com ([203.254.224.34]:30058 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752671AbaCGOgW (ORCPT ); Fri, 7 Mar 2014 09:36:22 -0500 Received: from epcpsbgr2.samsung.com (u142.gpu120.samsung.co.kr [203.254.230.142]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N2200DVRLWLN720@mailout4.samsung.com> for linux-mmc@vger.kernel.org; Fri, 07 Mar 2014 23:36:21 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [203.254.230.48]) by epcpsbgr2.samsung.com (EPCPMTA) with SMTP id 78.A8.09028.569D9135; Fri, 07 Mar 2014 23:36:21 +0900 (KST) X-AuditID: cbfee68e-b7f566d000002344-a3-5319d965098c Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id E0.84.28157.469D9135; Fri, 07 Mar 2014 23:36:21 +0900 (KST) Received: from DOTGIHJUN01 ([12.36.185.168]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N2200CZXLWK6N00@mmp2.samsung.com>; Fri, 07 Mar 2014 23:36:20 +0900 (KST) From: Seungwon Jeon To: linux-mmc@vger.kernel.org Cc: 'Chris Ball' , 'Ulf Hansson' , 'Jaehoon Chung' , 'Jackey Shen' , 'Alim Akhtar' References: <1383653403-10049-1-git-send-email-ulf.hansson@linaro.org> <006901cf2a58$d844f440$88cedcc0$%jun@samsung.com> In-reply-to: <006901cf2a58$d844f440$88cedcc0$%jun@samsung.com> Subject: [PATCH v2 2/5] mmc: identify available device type to select Date: Fri, 07 Mar 2014 23:36:20 +0900 Message-id: <003c01cf3a12$9b58e3b0$d20aab10$%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: Ac7aH/uUm1J6MxFOSyaXb4Fx/nx/rAABnFmgDfJZ22AGGhe9UAPt7YIg Content-language: ko X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrFIsWRmVeSWpSXmKPExsVy+t8zA93Um5LBBnsus1s8mLeNzWLC5e2M FhPuTWS1uPGrjdXiyP9+Rovja8Md2DxaL/1l87hzbQ+bx41XC5k8+rasYvT4vEkugDWKyyYl NSezLLVI3y6BK+PckfeMBfvdKi69XMfUwPjcoouRk0NCwERi3eNpTBC2mMSFe+vZuhi5OIQE ljFK9Nw6yw5TdGf2dFYQW0hgOqPEzwPVEEV/GCWuHd/DApJgE9CS+PvmDTOILSIgK/HzzwWw ScwCx4GKthxggeiukni44AeYzSlgJ3Hy/TkwW1jAVaLtxF42EJtFQFViffMusDivgK3ElFvf GSFsQYkfk+8BxTmAhqpLTJmSCxJmFpCX2LzmLTNIWAIo/OivLsQJbhK7LqxkgigRkdj34h0j yDkSAo/YJd5um8cCsUpA4tvkQywQvbISmw4wQ/wrKXFwxQ2WCYwSs5AsnoWweBaSxbOQbFjA yLKKUTS1ILmgOCm9yEivODG3uDQvXS85P3cTIyRe+3Yw3jxgfYgxGWj7RGYp0eR8YLznlcQb GpsZWZiamBobmVuakSasJM676GFSkJBAemJJanZqakFqUXxRaU5q8SFGJg5OqQbGIOmFfFnV uppLpk57eUZGP6L+xXzpVxIeXQUbzxzPKk1/sdjbdu7StUcyUszr95dq5ecsZXh4YZp86F/p 7zW1/7SF7nAs/i9fduKlmL3QfCY3yfUX929I/z7Hq0F5BnNEoB2/qJvJtpac0hdnfmrLWe73 PrlA3ihhEkf3DOHjh6UvdqosvpqkxFKckWioxVxUnAgAAeRO2+0CAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrOKsWRmVeSWpSXmKPExsVy+t9jQd3Um5LBBh3nmCwezNvGZjHh8nZG iwn3JrJa3PjVxmpx5H8/o8XxteEObB6tl/6yedy5tofN48arhUwefVtWMXp83iQXwBrVwGiT kZqYklqkkJqXnJ+SmZduq+QdHO8cb2pmYKhraGlhrqSQl5ibaqvk4hOg65aZA3SBkkJZYk4p UCggsbhYSd8O04TQEDddC5jGCF3fkCC4HiMDNJCwjjHj3JH3jAX73SouvVzH1MD43KKLkZND QsBE4s7s6awQtpjEhXvr2UBsIYHpjBI/D1R3MXIB2X8YJa4d38MCkmAT0JL4++YNM4gtIiAr 8fPPBTaQImaB40BFWw6wQHRXSTxc8APM5hSwkzj5/hyYLSzgKtF2Yi/YBhYBVYn1zbvA4rwC thJTbn1nhLAFJX5MvgcU5wAaqi4xZUouSJhZQF5i85q3zCBhCaDwo7+6ECe4Sey6sJIJokRE Yt+Ld4wTGIVmIRk0C2HQLCSDZiHpWMDIsopRNLUguaA4KT3XSK84Mbe4NC9dLzk/dxMjOBk8 k97BuKrB4hCjAAejEg9vxyKJYCHWxLLiytxDjBIczEoivDyrJYOFeFMSK6tSi/Lji0pzUosP MSYDvTmRWUo0OR+YqPJK4g2NTcyMLI3MLIxMzM1JE1YS5z3Yah0oJJCeWJKanZpakFoEs4WJ g1OqgXEpT+g/1w1Lc2QYxD5pyTBsU7hxZ9319QoHgjJt9zxJ6MoPu1QZ3H/T4I/DrOtxRcqO y5gWHm3/tfCr/jFOsYLAOOkNb+Ns+J5sMN2w9Gjn8aOHoqL0K/Y+nD99oyS/v4nqsrm/JvxV aAhTC419dkJ+g9i5ymWOQib8mf5yG6oOTjgYe91H7Z4SS3FGoqEWc1FxIgAqqOUYSgMAAA== 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=-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 Device types which are supported by both host and device can be identified when EXT_CSD is read. There is no need to check host's capability anymore. Signed-off-by: Seungwon Jeon --- Changes in v2: Just rebased with latest one. drivers/mmc/core/mmc.c | 77 ++++++++++++++++++++++++++------------------- include/linux/mmc/card.h | 6 ++- include/linux/mmc/host.h | 6 --- include/linux/mmc/mmc.h | 12 +++++-- 4 files changed, 56 insertions(+), 45 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index db9655f..0abece0 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -243,28 +243,46 @@ static void mmc_select_card_type(struct mmc_card *card) u8 card_type = card->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_MASK; u32 caps = host->caps, caps2 = host->caps2; unsigned int hs_max_dtr = 0; + unsigned int avail_type = 0; - if (card_type & EXT_CSD_CARD_TYPE_26) + if (caps & MMC_CAP_MMC_HIGHSPEED && + card_type & EXT_CSD_CARD_TYPE_HS_26) { hs_max_dtr = MMC_HIGH_26_MAX_DTR; + avail_type |= EXT_CSD_CARD_TYPE_HS_26; + } if (caps & MMC_CAP_MMC_HIGHSPEED && - card_type & EXT_CSD_CARD_TYPE_52) + card_type & EXT_CSD_CARD_TYPE_HS_52) { hs_max_dtr = MMC_HIGH_52_MAX_DTR; + avail_type |= EXT_CSD_CARD_TYPE_HS_52; + } - if ((caps & MMC_CAP_1_8V_DDR && - card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) || - (caps & MMC_CAP_1_2V_DDR && - card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)) + if (caps & MMC_CAP_1_8V_DDR && + card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) { hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; + avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V; + } - if ((caps2 & MMC_CAP2_HS200_1_8V_SDR && - card_type & EXT_CSD_CARD_TYPE_SDR_1_8V) || - (caps2 & MMC_CAP2_HS200_1_2V_SDR && - card_type & EXT_CSD_CARD_TYPE_SDR_1_2V)) + if (caps & MMC_CAP_1_2V_DDR && + card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) { + hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; + avail_type |= EXT_CSD_CARD_TYPE_DDR_1_2V; + } + + if (caps2 & MMC_CAP2_HS200_1_8V_SDR && + card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) { hs_max_dtr = MMC_HS200_MAX_DTR; + avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V; + } + + if (caps2 & MMC_CAP2_HS200_1_2V_SDR && + card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) { + hs_max_dtr = MMC_HS200_MAX_DTR; + avail_type |= EXT_CSD_CARD_TYPE_HS200_1_2V; + } card->ext_csd.hs_max_dtr = hs_max_dtr; - card->ext_csd.card_type = card_type; + card->mmc_avail_type = avail_type; } /* @@ -708,6 +726,11 @@ static struct device_type mmc_type = { .groups = mmc_attr_groups, }; +static inline unsigned int mmc_snoop_ddr(struct mmc_card *card) +{ + return card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_52; +} + /* * Select the PowerClass for the current bus width * If power class is defined for 4/8 bit bus in the @@ -808,12 +831,10 @@ static int mmc_select_hs200(struct mmc_card *card) host = card->host; - if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V && - host->caps2 & MMC_CAP2_HS200_1_2V_SDR) + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); - if (err && card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_8V && - host->caps2 & MMC_CAP2_HS200_1_8V_SDR) + if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); /* If fails try again during next card power cycle */ @@ -1072,10 +1093,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, */ if (card->ext_csd.hs_max_dtr != 0) { err = 0; - if (card->ext_csd.hs_max_dtr > 52000000 && - host->caps2 & MMC_CAP2_HS200) + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) err = mmc_select_hs200(card); - else if (host->caps & MMC_CAP_MMC_HIGHSPEED) + else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1, card->ext_csd.generic_cmd6_time, @@ -1089,13 +1109,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, mmc_hostname(card->host)); err = 0; } else { - if (card->ext_csd.hs_max_dtr > 52000000 && - host->caps2 & MMC_CAP2_HS200) { + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) mmc_set_timing(card->host, MMC_TIMING_MMC_HS200); - } else { + else mmc_set_timing(card->host, MMC_TIMING_MMC_HS); - } } } @@ -1118,14 +1136,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, /* * Indicate DDR mode (if supported). */ - if (mmc_card_hs(card)) { - if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) - && (host->caps & MMC_CAP_1_8V_DDR)) - ddr = MMC_1_8V_DDR_MODE; - else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) - && (host->caps & MMC_CAP_1_2V_DDR)) - ddr = MMC_1_2V_DDR_MODE; - } + if (mmc_card_hs(card)) + ddr = mmc_snoop_ddr(card); /* * Indicate HS200 SDR mode (if supported). @@ -1145,8 +1157,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * 3. set the clock to > 52Mhz <=200MHz and * 4. execute tuning for HS200 */ - if ((host->caps2 & MMC_CAP2_HS200) && - card->host->ops->execute_tuning) { + if (card->host->ops->execute_tuning) { mmc_host_clk_hold(card->host); err = card->host->ops->execute_tuning(card->host, MMC_SEND_TUNING_BLOCK_HS200); @@ -1255,7 +1266,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * * WARNING: eMMC rules are NOT the same as SD DDR */ - if (ddr == MMC_1_2V_DDR_MODE) { + if (ddr & EXT_CSD_CARD_TYPE_DDR_1_2V) { err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); if (err) diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 5473133..c232b10 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -68,7 +68,6 @@ struct mmc_ext_csd { #define MMC_HIGH_DDR_MAX_DTR 52000000 #define MMC_HS200_MAX_DTR 200000000 unsigned int sectors; - unsigned int card_type; unsigned int hc_erase_size; /* In sectors */ unsigned int hc_erase_timeout; /* In milliseconds */ unsigned int sec_trim_mult; /* Secure trim multiplier */ @@ -297,7 +296,10 @@ struct mmc_card { const char **info; /* info strings */ struct sdio_func_tuple *tuples; /* unknown common tuples */ - unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */ + union { + unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */ + unsigned int mmc_avail_type; /* supported device type by both host and card */ + }; struct dentry *debugfs_root; struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 2f263ae..1ee3c10 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -62,12 +62,6 @@ struct mmc_ios { #define MMC_TIMING_MMC_DDR52 8 #define MMC_TIMING_MMC_HS200 9 -#define MMC_SDR_MODE 0 -#define MMC_1_2V_DDR_MODE 1 -#define MMC_1_8V_DDR_MODE 2 -#define MMC_1_2V_SDR_MODE 3 -#define MMC_1_8V_SDR_MODE 4 - unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ #define MMC_SIGNAL_VOLTAGE_330 0 diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 50bcde3..f734c0c 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -354,18 +354,22 @@ struct _mmc_csd { #define EXT_CSD_CMD_SET_SECURE (1<<1) #define EXT_CSD_CMD_SET_CPSECURE (1<<2) -#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ -#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ #define EXT_CSD_CARD_TYPE_MASK 0x3F /* Mask out reserved bits */ +#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */ +#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */ +#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \ + EXT_CSD_CARD_TYPE_HS_52) #define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */ /* DDR mode @1.8V or 3V I/O */ #define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */ /* DDR mode @1.2V I/O */ #define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \ | EXT_CSD_CARD_TYPE_DDR_1_2V) -#define EXT_CSD_CARD_TYPE_SDR_1_8V (1<<4) /* Card can run at 200MHz */ -#define EXT_CSD_CARD_TYPE_SDR_1_2V (1<<5) /* Card can run at 200MHz */ +#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */ +#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */ /* SDR mode @1.2V I/O */ +#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \ + EXT_CSD_CARD_TYPE_HS200_1_2V) #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */