From patchwork Fri Aug 10 06:07:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 955938 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=nxp.com header.i=@nxp.com header.b="io897G8H"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41mvfF3DDfz9s9l for ; Fri, 10 Aug 2018 16:02:13 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 19267C21C8B; Fri, 10 Aug 2018 06:02:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=BAD_ENC_HEADER, SPF_HELO_PASS, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 45B93C21C4A; Fri, 10 Aug 2018 06:02:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 91CF8C21C4A; Fri, 10 Aug 2018 06:02:04 +0000 (UTC) Received: from EUR02-HE1-obe.outbound.protection.outlook.com (mail-eopbgr10084.outbound.protection.outlook.com [40.107.1.84]) by lists.denx.de (Postfix) with ESMTPS id 81C13C21C27 for ; Fri, 10 Aug 2018 06:02:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ckqrOZsmroEcnkv7DZr+TZ5Jwl30M/RKbpPNtagIr3Y=; b=io897G8HXGwjMe6nv5UGZ82CPiPNo5BXL4vbi3A8bOYysNTP6CfQfk4s4hk2b4QXOadArvh9bwlICXRq60JpQ+1OK92J7p5yVPY2dRSt0l50B+86VCPcPp0Sgv5An/x2LuMYrUh9fIB9W2g1OQZdsoUjV1QaBi31+EPyNwQPnxU= Received: from linux-u7w5.ap.freescale.net.net (92.121.68.129) by AM6PR04MB4487.eurprd04.prod.outlook.com (2603:10a6:20b:23::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1017.18; Fri, 10 Aug 2018 06:01:57 +0000 From: Peng Fan To: jh80.chung@samsung.com, sbabic@denx.de Date: Fri, 10 Aug 2018 14:07:54 +0800 Message-Id: <20180810060755.25287-1-peng.fan@nxp.com> X-Mailer: git-send-email 2.14.1 MIME-Version: 1.0 X-Originating-IP: [92.121.68.129] X-ClientProxiedBy: HK0P153CA0012.APCP153.PROD.OUTLOOK.COM (2603:1096:203:18::24) To AM6PR04MB4487.eurprd04.prod.outlook.com (2603:10a6:20b:23::23) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1e13e0a6-c301-4861-29d4-08d5fe86ca6f X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989117)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:AM6PR04MB4487; X-Microsoft-Exchange-Diagnostics: 1; AM6PR04MB4487; 3:bqRqqvvW6pPznwNtYuNBy7RmS3Hg5NwOvNm/hHglBHJwQXmfnwqLPAuv30bLQHQFRsQu0SB4uNlBWbFg9WoHAvrXBoVUlI/ViKDqtxHDGlCPw3POpyGobRMGA3AaLziFD2qMBnoGlAuJT7QBJysxahsGiF2WaShn8P5Lw7INjg2u4c9TIUyCNjzH829lZIBMSAAfcO6dtitaNObN+UuM466xuln0Ybm5hGZbcqxLE4jSsL8LPfgK4o3L2sk3OKia; 25:uSS4RY3uz+O7ub4ec4E5gEnbCInbdF6ZvjmI2amOLfVg2oNel+et7lSJ6L2IzRMeoCKQoQSnGRN0AdQGbMQWKrGRw7NYe/reqLjataQwbKjg5Zz22WKlS2849xGpF9mynAzVNPZ+wOoDcwTmNt7y9+qRbmjYQCgTcZS8M+lKFIQUqrdsP7Co/2vvy3SYVO1Ag8547EBhzV4/prAYj1Bibzow5kDqUMxPLj4EI/xf5MJWiDCAmCvtHaBN2lywYqvj7rU8Z/4t3O7tLivRXq7lYb1p+hropKM5lTzqoBi28cuv1MP54r8hqaxDrxHD85Wf2Y2j/AYpvFnR2NV+gnj4CQ==; 31:IqTf1mBaRad3XDbkEdWxrDJwMg4JDUJs+eL4N0EUSsGtEKPuogxxnySU3JEKd56sLx36+16U6rqwlaa0iKrhYps9FQe6izbWsbw4AD5Sm9FNN8SuGpAgcCwGStwWfPhokAXF/Tit/PnOuqQN2GCuUwMkYfREE88cXDcAxfKYMnb4oMvhroWvrFTityA9EV+ITjjkTcknaqVZ7n1wyf+MJ77nzyZQw2nJTrFhsh6QYD0= X-MS-TrafficTypeDiagnostic: AM6PR04MB4487: Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=peng.fan@nxp.com; X-Microsoft-Exchange-Diagnostics: 1; AM6PR04MB4487; 20:3EO97yR0UygU2eZhwAX2V3keBXDIeadJby7woAlhXGIHK9kMC0KybP18ZXDlk8Xq4ABnar8SbbWBW4tKMGoEF12nhF7D93AP03pI01KPDBUeJPbDFJka1xg9wdf35CRXOQKO0s8MkxGY2B/RCarVKzw9IyDtgYVY27vn2KeDXYbqGmNItwpFyRn31n6rllrRGLAThEs4uu9U/gMASdUIeSKFe61MLLphrGcHVqdRzPNvq1oesnsY3kVaRaY18n6wiGEQPQByFLV8TwLTk0fnQOBZJANS1An8lUi3Fw5puwXvDn3wMzPfOLZqx14VN2HCpW/l1elKLA8aS55kGe4+LyytJ1H1I0K7oT6q0nq+kDnlLhjsnIkoHIxWM5fB8WogsTIcvp8nsLvg61lHm9oVKvJiu1PcS5VsdJESPpYgEBv4pa2eRjtgM0LDjcsycnkTo3C574Al9QX/IgX3Zsdax0+UV0nSp2tXTXR5jY+maS9a+s3eNlz5+BpdVWA4ca4w; 4:hYuvF415RTamev1H45bS0oGUoBRG8YyF5TLA4jxRjQ76G4EMjJ9jyZbI845iOvWPke2q1kXeNGYQ0OwSK+VDNPpNnQpZdEz+QcJA0Q6mnrqmx4m2+1d8lsNY2npz34+VE2u7iijI4I3H5fBC18MFoLr60WEAoAswdwCr9xMyrIrsd2xyVdo+YpgZ6qtP4z9qWktGp3dWAZPa/cZmUgwBLXkL3ZbYEWtPhWG/TXc70K2OAwzkTuhakDddyCNkmyZ6/PVyoKQcr0NaBtK5cgI0uawZmydf0ntBf3T5vL6TH0Xqz5972G359w9uksHLPGGR59JtYVz1raxdcasKneQUgZlPRz1P0xwPGVJlTsSxqA8PNFz9PJmahHhWtDOcJne4 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(31051911155226)(185117386973197)(7411616537696); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(823301030)(3002001)(10201501046)(3231311)(944501410)(52105095)(93006095)(93001095)(6055026)(149027)(150027)(6041310)(20161123564045)(20161123560045)(20161123562045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011)(7699016); SRVR:AM6PR04MB4487; BCL:0; PCL:0; RULEID:; SRVR:AM6PR04MB4487; X-Forefront-PRVS: 07607ED19A X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(136003)(396003)(346002)(39860400002)(376002)(366004)(199004)(189003)(68736007)(25786009)(3846002)(1076002)(81166006)(86362001)(6116002)(97736004)(106356001)(8676002)(8936002)(478600001)(81156014)(44832011)(53936002)(486006)(4326008)(956004)(476003)(50226002)(2906002)(2616005)(66066001)(316002)(6512007)(26005)(51416003)(386003)(6506007)(16586007)(16526019)(6666003)(52116002)(5660300001)(105586002)(36756003)(7736002)(50466002)(48376002)(6486002)(186003)(305945005)(47776003)(54906003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM6PR04MB4487; H:linux-u7w5.ap.freescale.net.net; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM6PR04MB4487; 23:/QGpyunSj0KLeKiqOh5IYZ2ZUKNQiQfuX1JwdGNJp?= lFuH7S9hvR42xfWvoJi3yksYOci0Ue3koUx2EaN6luTW2QalChTfLOh6qX/vAiqElssBBCHHeAD388YniWDyrqNETYvim76lW8CNqIEHp2lunw8JQloLTnIyehBsm7D3jX1c6SKp+fd6lNUjH8MnH3/uiSbnM6StTq3L6B+nh6ZFjoebsL5z49M7MaiEUBugKqylLeXl0hHrqGGdDEVrdneQaknJJuPVJy6aTAf/1h3tZB2bl+gutl04gpNusHJ0EJR3x52FaapempOfbZtz6WeGOE8pJJee46iYFN+Xkbjd2PxSmeM/SSvoGptGTj7+u1PcW94PKd2QeIoynCQ7rihzQV9c0PW9ladpgginqtcH1ErjTwc7DvBvME8r83Cn2Rn2rbvkYTbdpNmfSW90n6O+Z+wqUvo/KojaBk+cyb+EdfN3QEUPZ+iSzi4rqoMghIiat7qufBPElhoOfUH02KKBBeX0lfRJyFXmxgQ3fel6t07PkjEzdf8U8dy93PDQzsafPQ8G7KDP+IG8Ae26bNuMOHuQiqvCKzucx2m6O6bi7WMUuBX73Sd2+tbbd9loxxwW2gFF/H+d/Gajs6GT4kOvvPsskI+6CC4xw4GvyHVeQHTtVPoT9g2WwrwMubgLS4+MeOt175J+uedyOYYK3LyQkmUB0oUyR6PaFTeCkhy8iPu12YDEJuFheuQtDOV2jMMLpTJb4AIiHuJKvVo+Xef1kefq7W0p411XrZztfePeXiLGkiuQvER7/uCG9ELe8YeIoPzCXbhWllH1BBqK8BI+qi1YGloNyasXSA7ppMjcpyunA8ylBEfkEq/v6+zpXYnwiaWrp93v75bTc3QxaqLn7Y3XMU5OasaZ8trULNDIv35f+gJiDHThvaIwdbghEzFR+8MSn5hvhfAftthC47ZnQbpU00nL+LKVDgL72WLaaieG7Cr6vQcEYli1xIMifS3rmZCWdGO9qqXgqIvimW8QuTI+w1VSBLs+ynLmWUOWVbvJ3cGngSffJAV1aEjGHa36RiWLzJ/r6K/xu2q0KMGHZ77mwqelXc9U6t3mBNdjqAs1C7wT68TTKcumxhdYjV+I71vE69ebcsDurwTHddZQ1GNtuySKqlxcP/cHpmOYg== X-Microsoft-Antispam-Message-Info: D0dLFqh4kd3ZCmY0fOwD10ybnFM9U3n9RpdEVIM+oV++D4Se+WPsK/3aNmzELXzp9zfLprJ1o0NgyGN9840H6ZWI8BvBLvgwGpHtN5yt0veZ2Uf8Fum97UDFHnYKXiqi2dBPjBqET+BZ9jMlFp/+ZMIZteEhFP/gxOixqPfV1v/jziBnsmS1tWHjvSQtMLGFSg05e0tSBHGysohcqdoaY9+G04Bmpj3RF2oDmkExgqUGYRpNqh42I30ipbw7taLvUNpIKPNgrCM7fFEz6cu8+Zot9fu0GT5Rfg5xs3izP8/AiMDjgKxA3Khj2kJ7UH5dOJKWXZsBh2CL1ijuZiBmIoZthDcoQp5kQnoLGNS/2PE= X-Microsoft-Exchange-Diagnostics: 1; AM6PR04MB4487; 6:zAXLqmQ6rVVGm5mYxagHaZXoXaPBpmZaoD9jXdOSnquPmBPp8AiDZq7tL0nbDBH9mIq8sNBNtXpQPMHEaIZR6DkyxiYxUjOcnZJc/8CXF5/dTSy8pwXUqWJW7EdAWEl0srR4jfr3dfsD4H0MTr7WAWgm4Lhg5ZdVYjgi/lhptKwLC86CtIJviL3dHTZHL20uWXSfEtzygns8D0hAk9INO83ddICMbOiea75H4EO+/tBTB8JgE6zYijMj2F5SU8onwaZ0dNSeCQbk91mfHgjgzNnX0rd08Gk9ddqNU2cuJG5WgQxRnaikVWcvj6vjsvZx2ts6Nq8CxUwL10d97tWsq/epvMI/1n3NuyyDBYuKnIkecduhj2J7S2D3jplYr+C94Q5UuZbM+3V0M0WOvfP++dZYtkZmFFBZ8yh95D75gmQLoldNUrWzRU85kqyFK1PKDi70muxO7qC5n8ZFe7ApQg==; 5:41uY4XC5KwLfjmFQcvRgwEfaKr9Y/AHiJpyNI2Rf8UoHQaJAwLXF0H/0IAC5rTIQBtbK1XvXGMWEsKOy0ThZ/zTJgz7x8LRM1xjxf7WtP9zsp2Rs47JO/T65xLokyc7RmC2eIyFoCBASDlCYrgfEhgO1MK7Ht/zWvs65pQfoOBQ=; 7:2qbNkPY7YnSSifJJcBLSJ2SekuyIyGfZOWkBBjoCx+lz1pW3BBCmdryYi3WcdKHh+IruDMcg5e/dA+wR5CfeZJGuscLZ9YLDnqgtLjOgiG83PrjrHCAdRfqRUwx5Q4jYqoYvLrSp4nu1ag6YiP91ivhiWkT5vfW0iCM6xnv7EMYGn8CG3E22PbgY9LywPHrm/GVbBS69KhqD8fCa6LnZtQz9fZJ5iAJkcoX+MgL6kFyotreYGVeJFSA+G98t8xit SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Aug 2018 06:01:57.8149 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 1e13e0a6-c301-4861-29d4-08d5fe86ca6f X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR04MB4487 Cc: Marek Vasut , Kishon Vijay Abraham I , u-boot@lists.denx.de, linux-imx@nxp.com Subject: [U-Boot] [PATCH V4 1/2] mmc: add HS400 support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add HS400 support. Selecting HS400 needs first select HS200 according to spec, so use a dedicated function for HS400. Add HS400 related macros. Remove the restriction of only using the low 6 bits of EXT_CSD_CARD_TYPE, using all the 8 bits. Signed-off-by: Peng Fan Cc: Jaehoon Chung Cc: Jean-Jacques Hiblot Cc: Stefano Babic Cc: Kishon Vijay Abraham I Cc: Faiz Abbas Cc: Marek Vasut Signed-off-by: Peng Fan --- V4: Add SPL_MMC_HS400_SUPPORT Kconfig entry typo fix, HS199->HS200 in commit log. V3: Simplify code add error msg V2: remove 4bits support from HS400, as HS400 does not support 4bits per spec. drivers/mmc/Kconfig | 13 +++++ drivers/mmc/mmc.c | 137 +++++++++++++++++++++++++++++++++++++++++----------- include/mmc.h | 11 +++++ 3 files changed, 134 insertions(+), 27 deletions(-) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 377b1c4b3b..1616022b91 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -111,6 +111,19 @@ config SPL_MMC_UHS_SUPPORT cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus frequency can go up to 208MHz (SDR104) +config MMC_HS400_SUPPORT + bool "enable HS400 support" + select MMC_HS200_SUPPORT + help + The HS400 mode is support by some eMMC. The bus frequency is up to + 200MHz. This mode requires tuning the IO. + +config SPL_MMC_HS400_SUPPORT + bool "enable HS400 support in SPL" + help + The HS400 mode is support by some eMMC. The bus frequency is up to + 200MHz. This mode requires tuning the IO. + config MMC_HS200_SUPPORT bool "enable HS200 support" help diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ad429f49c9..585951cd78 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -147,6 +147,7 @@ const char *mmc_mode_name(enum bus_mode mode) [MMC_HS_52] = "MMC High Speed (52MHz)", [MMC_DDR_52] = "MMC DDR52 (52MHz)", [MMC_HS_200] = "HS200 (200MHz)", + [MMC_HS_400] = "HS400 (200MHz)", }; if (mode >= MMC_MODES_END) @@ -171,6 +172,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode) [UHS_DDR50] = 50000000, [UHS_SDR104] = 208000000, [MMC_HS_200] = 200000000, + [MMC_HS_400] = 200000000, }; if (mode == MMC_LEGACY) @@ -769,6 +771,11 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode) case MMC_HS_200: speed_bits = EXT_CSD_TIMING_HS200; break; +#endif +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) + case MMC_HS_400: + speed_bits = EXT_CSD_TIMING_HS400; + break; #endif case MMC_LEGACY: speed_bits = EXT_CSD_TIMING_LEGACY; @@ -816,7 +823,7 @@ static int mmc_get_capabilities(struct mmc *mmc) mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT; - cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f; + cardtype = ext_csd[EXT_CSD_CARD_TYPE]; mmc->cardtype = cardtype; #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) @@ -824,6 +831,12 @@ static int mmc_get_capabilities(struct mmc *mmc) EXT_CSD_CARD_TYPE_HS200_1_8V)) { mmc->card_caps |= MMC_MODE_HS200; } +#endif +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) + if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V | + EXT_CSD_CARD_TYPE_HS400_1_8V)) { + mmc->card_caps |= MMC_MODE_HS400; + } #endif if (cardtype & EXT_CSD_CARD_TYPE_52) { if (cardtype & EXT_CSD_CARD_TYPE_DDR_52) @@ -1734,10 +1747,13 @@ static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode, u32 card_mask = 0; switch (mode) { + case MMC_HS_400: case MMC_HS_200: - if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_8V) + if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V | + EXT_CSD_CARD_TYPE_HS400_1_8V)) card_mask |= MMC_SIGNAL_VOLTAGE_180; - if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_2V) + if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V | + EXT_CSD_CARD_TYPE_HS400_1_2V)) card_mask |= MMC_SIGNAL_VOLTAGE_120; break; case MMC_DDR_52: @@ -1773,6 +1789,13 @@ static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode, #endif static const struct mode_width_tuning mmc_modes_by_pref[] = { +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) + { + .mode = MMC_HS_400, + .widths = MMC_MODE_8BIT, + .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200 + }, +#endif #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) { .mode = MMC_HS_200, @@ -1816,6 +1839,54 @@ static const struct ext_csd_bus_width { {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1}, }; +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) +static int mmc_select_hs400(struct mmc *mmc) +{ + int err; + + /* Set timing to HS200 for tuning */ + err = mmc_set_card_speed(mmc, MMC_HS_200); + if (err) + return err; + + /* configure the bus mode (host) */ + mmc_select_mode(mmc, MMC_HS_200); + mmc_set_clock(mmc, mmc->tran_speed, false); + + /* execute tuning if needed */ + err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200); + if (err) { + debug("tuning failed\n"); + return err; + } + + /* Set back to HS */ + mmc_set_card_speed(mmc, MMC_HS); + mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false); + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, + EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG); + if (err) + return err; + + err = mmc_set_card_speed(mmc, MMC_HS_400); + if (err) + return err; + + mmc_select_mode(mmc, MMC_HS_400); + err = mmc_set_clock(mmc, mmc->tran_speed, false); + if (err) + return err; + + return 0; +} +#else +static int mmc_select_hs400(struct mmc *mmc) +{ + return -ENOTSUPP; +} +#endif + #define for_each_supported_width(caps, ddr, ecbv) \ for (ecbv = ext_csd_bus_width;\ ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\ @@ -1869,37 +1940,49 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps) goto error; mmc_set_bus_width(mmc, bus_width(ecbw->cap)); - /* configure the bus speed (card) */ - err = mmc_set_card_speed(mmc, mwt->mode); - if (err) - goto error; - - /* - * configure the bus width AND the ddr mode (card) - * The host side will be taken care of in the next step - */ - if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) { - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, - ecbw->ext_csd_bits); + if (mwt->mode == MMC_HS_400) { + err = mmc_select_hs400(mmc); + if (err) { + printf("Select HS400 failed %d\n", err); + goto error; + } + } else { + /* configure the bus speed (card) */ + err = mmc_set_card_speed(mmc, mwt->mode); if (err) goto error; - } - /* configure the bus mode (host) */ - mmc_select_mode(mmc, mwt->mode); - mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE); + /* + * configure the bus width AND the ddr mode + * (card). The host side will be taken care + * of in the next step + */ + if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) { + err = mmc_switch(mmc, + EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BUS_WIDTH, + ecbw->ext_csd_bits); + if (err) + goto error; + } + + /* configure the bus mode (host) */ + mmc_select_mode(mmc, mwt->mode); + mmc_set_clock(mmc, mmc->tran_speed, + MMC_CLK_ENABLE); #ifdef MMC_SUPPORTS_TUNING - /* execute tuning if needed */ - if (mwt->tuning) { - err = mmc_execute_tuning(mmc, mwt->tuning); - if (err) { - pr_debug("tuning failed\n"); - goto error; + /* execute tuning if needed */ + if (mwt->tuning) { + err = mmc_execute_tuning(mmc, + mwt->tuning); + if (err) { + pr_debug("tuning failed\n"); + goto error; + } } - } #endif + } /* do a transfer to check the configuration */ err = mmc_read_and_compare_ext_csd(mmc); diff --git a/include/mmc.h b/include/mmc.h index df4255b828..9b9cbedadc 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -64,6 +64,7 @@ #define MMC_MODE_HS_52MHz MMC_CAP(MMC_HS_52) #define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52) #define MMC_MODE_HS200 MMC_CAP(MMC_HS_200) +#define MMC_MODE_HS400 MMC_CAP(MMC_HS_400) #define MMC_MODE_8BIT BIT(30) #define MMC_MODE_4BIT BIT(29) @@ -248,6 +249,10 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) /* 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_CARD_TYPE_HS400_1_8V BIT(6) +#define EXT_CSD_CARD_TYPE_HS400_1_2V BIT(7) +#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \ + EXT_CSD_CARD_TYPE_HS400_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 */ @@ -259,6 +264,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) #define EXT_CSD_TIMING_LEGACY 0 /* no high speed */ #define EXT_CSD_TIMING_HS 1 /* HS */ #define EXT_CSD_TIMING_HS200 2 /* HS200 */ +#define EXT_CSD_TIMING_HS400 3 /* HS400 */ #define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) @@ -519,6 +525,7 @@ enum bus_mode { UHS_DDR50, UHS_SDR104, MMC_HS_200, + MMC_HS_400, MMC_MODES_END }; @@ -532,6 +539,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode) #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) else if (mode == UHS_DDR50) return true; +#endif +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) + else if (mode == MMC_HS_400) + return true; #endif else return false;