From patchwork Wed Jul 10 09:35:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 1130297 X-Patchwork-Delegate: van.freenix@gmail.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="Tw0xH4rl"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 45kDZ82xRXz9sN4 for ; Wed, 10 Jul 2019 19:35:26 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 811D5C21F21; Wed, 10 Jul 2019 09:35:23 +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=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 BBF5EC21DDC; Wed, 10 Jul 2019 09:35:19 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 92BA5C21DD7; Wed, 10 Jul 2019 09:35:17 +0000 (UTC) Received: from EUR03-DB5-obe.outbound.protection.outlook.com (mail-eopbgr40068.outbound.protection.outlook.com [40.107.4.68]) by lists.denx.de (Postfix) with ESMTPS id 1949BC21CB6 for ; Wed, 10 Jul 2019 09:35:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hOUUVJqJ8V7Cdx3wc5+dS2CFFl8azhVM8O84dUq2O4k=; b=Tw0xH4rlVJDK0yfacKs7eI9q0OpQCCDXwkCzmMijECw5KsX10TdsMALZuEhou7r3T4fE5tuNVdBJH3Imnl//BA07D0n1SaMMMjTutFIPznjm+oXu+hb4JXbM5k6gO8Pp5gwukevtbbHVvFvVNdX5wAsF/MzV9Q8Qqv97xUbqE0I= Received: from AM0PR04MB4481.eurprd04.prod.outlook.com (52.135.147.15) by AM0PR04MB6435.eurprd04.prod.outlook.com (20.179.255.94) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2052.19; Wed, 10 Jul 2019 09:35:15 +0000 Received: from AM0PR04MB4481.eurprd04.prod.outlook.com ([fe80::2023:c0e5:8a63:2e47]) by AM0PR04MB4481.eurprd04.prod.outlook.com ([fe80::2023:c0e5:8a63:2e47%5]) with mapi id 15.20.2052.020; Wed, 10 Jul 2019 09:35:15 +0000 From: Peng Fan To: Peng Fan Thread-Topic: [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode Thread-Index: AQHVNwLHZXCkjjRi2UqYV7mqSOYNFQ== Date: Wed, 10 Jul 2019 09:35:15 +0000 Message-ID: <20190710095006.15801-1-peng.fan@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: git-send-email 2.16.4 x-clientproxiedby: HK0PR01CA0028.apcprd01.prod.exchangelabs.com (2603:1096:203:3e::16) To AM0PR04MB4481.eurprd04.prod.outlook.com (2603:10a6:208:70::15) authentication-results: spf=none (sender IP is ) smtp.mailfrom=peng.fan@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [119.31.174.71] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 672e6ff3-fd04-4dfc-4c57-08d70519e9c1 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(5600148)(711020)(4605104)(1401327)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020); SRVR:AM0PR04MB6435; x-ms-traffictypediagnostic: AM0PR04MB6435: x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:7691; x-forefront-prvs: 0094E3478A x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(4636009)(39860400002)(396003)(346002)(366004)(376002)(136003)(199004)(189003)(81156014)(81166006)(6436002)(25786009)(14444005)(6486002)(44832011)(66556008)(2906002)(66946007)(102836004)(64756008)(66446008)(66476007)(26005)(8676002)(53936002)(476003)(2616005)(6512007)(36756003)(6506007)(386003)(486006)(7736002)(256004)(68736007)(6200100001)(305945005)(99286004)(7049001)(6116002)(186003)(3846002)(66066001)(1076003)(4326008)(54906003)(86362001)(478600001)(37006003)(71200400001)(5660300002)(8936002)(52116002)(316002)(71190400001)(14454004)(6862004)(50226002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR04MB6435; H:AM0PR04MB4481.eurprd04.prod.outlook.com; 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-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: 8U1+4O014Uruy4kUwtNiuLekqkq34gf4gd9gWWOiG4UGX+Z2A6ZN9qWnz/wgHaMNM+XVrdC3CNJvT40vLAFT84iE7vZXf6tfo0Ou9y3itSTGLeBVv5+nzwVU9fKC54mxSDkb6GTJ0TaFWRLzJENq+dyqdWdJdq9yRsTIJmnbOuPtCKk11vGnX8dFGCFA9F3BxflCBDbmE4YB7VqY5Y9c33sEGyCtd/JUFUvfm+M+Cb9ZMYyF8ImAmMXk5A7Tpwgt/sjDGPN9FUQuWK1m6cQUOM4XxyKfLuPfedbhmShhHl04Z+45iU6vDh4dFHg7Fuj0Hikf9YvibDro4pCXnmMrailN+RqTv9yV4ptUE1SJQcZ11iqFWFlDdDnYzl6IxroBn2YrVj3c9gKXEOwFRcY4QKN/bLM2EQ4/EbY7LUL/Gec= MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 672e6ff3-fd04-4dfc-4c57-08d70519e9c1 X-MS-Exchange-CrossTenant-originalarrivaltime: 10 Jul 2019 09:35:15.4012 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: peng.fan@nxp.com X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR04MB6435 Cc: Baruch Siach , Michal Simek , "u-boot@lists.denx.de" , dl-uboot-imx , T Karthik Reddy , Marek Vasut Subject: [U-Boot] [PATCH V2 1/7] mmc: support hs400 enhanced strobe mode 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" eMMC 5.1+ supports HS400 Enhances Strobe mode without the need for tuning procedure. The flow is as following: - set HS_TIMIMG (Highspeed) - Host change freq to <= 52Mhz - set the bus width to Enhanced strobe and DDR8Bit(CMD6), EXT_CSD[183] = 0x86 instead of 0x80 - set HS_TIMING to 0x3 (HS400) - Host change freq to <= 200Mhz - Host select HS400 enhanced strobe complete Signed-off-by: Peng Fan Cc: Jean-Jacques Hiblot Cc: Baruch Siach Cc: Michal Simek Cc: T Karthik Reddy Cc: Simon Glass Cc: Marek Vasut Cc: Jon Nettleton --- V2: Add return value for mmc strobe functions Use mmc_set_card_speed to replace mmc_switch drivers/mmc/Kconfig | 12 ++++++++ drivers/mmc/mmc-uclass.c | 17 ++++++++++++ drivers/mmc/mmc.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++- include/mmc.h | 15 ++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 93588725f2..f22c0a0589 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -117,6 +117,18 @@ 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_ES_SUPPORT + bool "enable HS400 Enhanced Strobe support" + help + The HS400 Enhanced Strobe mode is support by some eMMC. The bus + frequency is up to 200MHz. This mode does not tune the IO. + +config SPL_MMC_HS400_ES_SUPPORT + bool "enable HS400 Enhanced Strobe support in SPL" + help + The HS400 Enhanced Strobe mode is support by some eMMC. The bus + frequency is up to 200MHz. This mode does not tune the IO. + config MMC_HS400_SUPPORT bool "enable HS400 support" select MMC_HS200_SUPPORT diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index fa4d1af55d..890b380f1f 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -120,6 +120,23 @@ int mmc_execute_tuning(struct mmc *mmc, uint opcode) } #endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) +int dm_mmc_set_enhanced_strobe(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (ops->set_enhanced_strobe) + return ops->set_enhanced_strobe(dev); + + return -ENOTSUPP; +} + +int mmc_set_enhanced_strobe(struct mmc *mmc) +{ + return dm_mmc_set_enhanced_strobe(mmc->dev); +} +#endif + int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg) { int val; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 71b52c6cf2..c6b5488352 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -148,6 +148,7 @@ const char *mmc_mode_name(enum bus_mode mode) [MMC_DDR_52] = "MMC DDR52 (52MHz)", [MMC_HS_200] = "HS200 (200MHz)", [MMC_HS_400] = "HS400 (200MHz)", + [MMC_HS_400_ES] = "HS400ES (200MHz)", }; if (mode >= MMC_MODES_END) @@ -173,6 +174,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode) [UHS_SDR104] = 208000000, [MMC_HS_200] = 200000000, [MMC_HS_400] = 200000000, + [MMC_HS_400_ES] = 200000000, }; if (mode == MMC_LEGACY) @@ -788,6 +790,11 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode, case MMC_HS_400: speed_bits = EXT_CSD_TIMING_HS400; break; +#endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + case MMC_HS_400_ES: + speed_bits = EXT_CSD_TIMING_HS400; + break; #endif case MMC_LEGACY: speed_bits = EXT_CSD_TIMING_LEGACY; @@ -859,7 +866,8 @@ static int mmc_get_capabilities(struct mmc *mmc) mmc->card_caps |= MMC_MODE_HS200; } #endif -#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) || \ + CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V | EXT_CSD_CARD_TYPE_HS400_1_8V)) { mmc->card_caps |= MMC_MODE_HS400; @@ -873,6 +881,13 @@ static int mmc_get_capabilities(struct mmc *mmc) if (cardtype & EXT_CSD_CARD_TYPE_26) mmc->card_caps |= MMC_MODE_HS; +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + if (ext_csd[EXT_CSD_STROBE_SUPPORT] && + (mmc->card_caps & MMC_MODE_HS400)) { + mmc->card_caps |= MMC_MODE_HS400_ES; + } +#endif + return 0; } #endif @@ -1778,6 +1793,7 @@ static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode, u32 card_mask = 0; switch (mode) { + case MMC_HS_400_ES: case MMC_HS_400: case MMC_HS_200: if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V | @@ -1820,6 +1836,12 @@ 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_ES_SUPPORT) + { + .mode = MMC_HS_400_ES, + .widths = MMC_MODE_8BIT, + }, +#endif #if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) { .mode = MMC_HS_400, @@ -1917,6 +1939,47 @@ static int mmc_select_hs400(struct mmc *mmc) } #endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) +#if !CONFIG_IS_ENABLED(DM_MMC) +static int mmc_set_enhanced_strobe(struct mmc *mmc) +{ + return -ENOTSUPP; +} +#endif +static int mmc_select_hs400es(struct mmc *mmc) +{ + int err; + + err = mmc_set_card_speed(mmc, MMC_HS, true); + if (err) + return err; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, + EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG | + EXT_CSD_BUS_WIDTH_STROBE); + if (err) { + printf("switch to bus width for hs400 failed\n"); + return err; + } + /* TODO: driver strength */ + err = mmc_set_card_speed(mmc, MMC_HS_400_ES, false); + if (err) + return err; + + mmc_select_mode(mmc, MMC_HS_400_ES); + err = mmc_set_clock(mmc, mmc->tran_speed, false); + if (err) + return err; + + return mmc_set_enhanced_strobe(mmc); +} +#else +static int mmc_select_hs400es(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);\ @@ -1988,6 +2051,13 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps) printf("Select HS400 failed %d\n", err); goto error; } + } else if (mwt->mode == MMC_HS_400_ES) { + err = mmc_select_hs400es(mmc); + if (err) { + printf("Select HS400ES failed %d\n", + err); + goto error; + } } else { /* configure the bus speed (card) */ err = mmc_set_card_speed(mmc, mwt->mode, false); diff --git a/include/mmc.h b/include/mmc.h index 2be3e91fcb..b42687395c 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -65,6 +65,7 @@ #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_HS400_ES MMC_CAP(MMC_HS_400_ES) #define MMC_CAP_NONREMOVABLE BIT(14) #define MMC_CAP_NEEDS_POLL BIT(15) @@ -223,6 +224,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) #define EXT_CSD_BOOT_BUS_WIDTH 177 #define EXT_CSD_PART_CONF 179 /* R/W */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ +#define EXT_CSD_STROBE_SUPPORT 184 /* R/W */ #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_CARD_TYPE 196 /* RO */ @@ -264,11 +266,13 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) #define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ #define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ #define EXT_CSD_DDR_FLAG BIT(2) /* Flag for DDR mode */ +#define EXT_CSD_BUS_WIDTH_STROBE BIT(7) /* Enhanced strobe mode */ #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_DRV_STR_SHIFT 4 /* Driver Strength shift */ #define EXT_CSD_BOOT_ACK_ENABLE (1 << 6) #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3) @@ -465,6 +469,11 @@ struct dm_mmc_ops { */ int (*wait_dat0)(struct udevice *dev, int state, int timeout); #endif + +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + /* set_enhanced_strobe() - set HS400 enhanced strobe */ + int (*set_enhanced_strobe)(struct udevice *dev); +#endif }; #define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops) @@ -485,6 +494,7 @@ int mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); int mmc_execute_tuning(struct mmc *mmc, uint opcode); int mmc_wait_dat0(struct mmc *mmc, int state, int timeout); +int mmc_set_enhanced_strobe(struct mmc *mmc); #else struct mmc_ops { @@ -530,6 +540,7 @@ enum bus_mode { UHS_SDR104, MMC_HS_200, MMC_HS_400, + MMC_HS_400_ES, MMC_MODES_END }; @@ -547,6 +558,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode) #if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) else if (mode == MMC_HS_400) return true; +#endif +#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) + else if (mode == MMC_HS_400_ES) + return true; #endif else return false;