From patchwork Thu Sep 21 14:29:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Jacques Hiblot X-Patchwork-Id: 816894 X-Patchwork-Delegate: jh80.chung@samsung.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; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="NfusvhWd"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xyfDm4bMBz9s7h for ; Fri, 22 Sep 2017 00:31:20 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 3F0FAC21F29; Thu, 21 Sep 2017 14:30:51 +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=RCVD_IN_DNSWL_NONE, 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 34DD4C21F14; Thu, 21 Sep 2017 14:30:31 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B6FABC21F29; Thu, 21 Sep 2017 14:30:29 +0000 (UTC) Received: from lelnx194.ext.ti.com (lelnx194.ext.ti.com [198.47.27.80]) by lists.denx.de (Postfix) with ESMTPS id 0B88DC21E0A for ; Thu, 21 Sep 2017 14:30:27 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelnx194.ext.ti.com (8.15.1/8.15.1) with ESMTP id v8LEUNF0002807; Thu, 21 Sep 2017 09:30:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ti.com; s=ti-com-17Q1; t=1506004223; bh=I73dajOX/VllT74loarTpXKPaN7wtBJ+IYCp8zKhGBM=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=NfusvhWdHkql3+Gc8l6X4zPKzVs4YiLaaNahRR4bSHjBZ7ixJmAOObpiHosKm4Yaj nnoN8LvAtnSBLmuq2Q/sESewD7xM+ohaLMDKYABfW43dtZ5jbdN4LU3k2HCjf67YMD +SIBYaNGWxA/uhl8r3sweNZOg7hQ0NqlUVdM1OHY= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id v8LEUNJx028111; Thu, 21 Sep 2017 09:30:23 -0500 Received: from DFLE104.ent.ti.com (10.64.6.25) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.845.34; Thu, 21 Sep 2017 09:30:23 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.845.34 via Frontend Transport; Thu, 21 Sep 2017 09:30:23 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id v8LEUMgt011134; Thu, 21 Sep 2017 09:30:22 -0500 From: Jean-Jacques Hiblot To: , , , Date: Thu, 21 Sep 2017 16:29:49 +0200 Message-ID: <1506004213-22620-3-git-send-email-jjhiblot@ti.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506004213-22620-1-git-send-email-jjhiblot@ti.com> References: <1506004213-22620-1-git-send-email-jjhiblot@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 02/26] mmc: split mmc_startup() 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" No functionnal change here. The function is really big and can be split. The part related to bus configuration are put in 2 separate functions: one for MMC and one for SD. Signed-off-by: Jean-Jacques Hiblot Reviewed-by: Simon Glass --- drivers/mmc/mmc.c | 274 +++++++++++++++++++++++++++++------------------------- 1 file changed, 148 insertions(+), 126 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 11285be..1946875 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1103,6 +1103,152 @@ static void mmc_set_bus_width(struct mmc *mmc, uint width) mmc_set_ios(mmc); } +static int sd_select_bus_freq_width(struct mmc *mmc) +{ + int err; + struct mmc_cmd cmd; + + err = sd_change_freq(mmc); + if (err) + return err; + + /* Restrict card's capabilities by what the host can do */ + mmc->card_caps &= mmc->cfg->host_caps; + + if (mmc->card_caps & MMC_MODE_4BIT) { + cmd.cmdidx = MMC_CMD_APP_CMD; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = mmc->rca << 16; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; + cmd.resp_type = MMC_RSP_R1; + cmd.cmdarg = 2; + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + mmc_set_bus_width(mmc, 4); + } + + err = sd_read_ssr(mmc); + if (err) + return err; + + if (mmc->card_caps & MMC_MODE_HS) + mmc->tran_speed = 50000000; + else + mmc->tran_speed = 25000000; + + return 0; +} + +static int mmc_select_bus_freq_width(struct mmc *mmc, const u8 *ext_csd) +{ + ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN); + /* An array of possible bus widths in order of preference */ + static const unsigned int ext_csd_bits[] = { + EXT_CSD_DDR_BUS_WIDTH_8, + EXT_CSD_DDR_BUS_WIDTH_4, + EXT_CSD_BUS_WIDTH_8, + EXT_CSD_BUS_WIDTH_4, + EXT_CSD_BUS_WIDTH_1, + }; + /* An array to map CSD bus widths to host cap bits */ + static const unsigned int ext_to_hostcaps[] = { + [EXT_CSD_DDR_BUS_WIDTH_4] = + MMC_MODE_DDR_52MHz | MMC_MODE_4BIT, + [EXT_CSD_DDR_BUS_WIDTH_8] = + MMC_MODE_DDR_52MHz | MMC_MODE_8BIT, + [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT, + [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT, + }; + /* An array to map chosen bus width to an integer */ + static const unsigned int widths[] = { + 8, 4, 8, 4, 1, + }; + int err; + int idx; + + err = mmc_change_freq(mmc); + if (err) + return err; + + /* Restrict card's capabilities by what the host can do */ + mmc->card_caps &= mmc->cfg->host_caps; + + /* Only version 4 of MMC supports wider bus widths */ + if (mmc->version < MMC_VERSION_4) + return 0; + + for (idx = 0; idx < ARRAY_SIZE(ext_csd_bits); idx++) { + unsigned int extw = ext_csd_bits[idx]; + unsigned int caps = ext_to_hostcaps[extw]; + /* + * If the bus width is still not changed, + * don't try to set the default again. + * Otherwise, recover from switch attempts + * by switching to 1-bit bus width. + */ + if (extw == EXT_CSD_BUS_WIDTH_1 && + mmc->bus_width == 1) { + err = 0; + break; + } + + /* + * Check to make sure the card and controller support + * these capabilities + */ + if ((mmc->card_caps & caps) != caps) + continue; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BUS_WIDTH, extw); + + if (err) + continue; + + mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0; + mmc_set_bus_width(mmc, widths[idx]); + + err = mmc_send_ext_csd(mmc, test_csd); + + if (err) + continue; + + /* Only compare read only fields */ + if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] + == test_csd[EXT_CSD_PARTITIONING_SUPPORT] && + ext_csd[EXT_CSD_HC_WP_GRP_SIZE] + == test_csd[EXT_CSD_HC_WP_GRP_SIZE] && + ext_csd[EXT_CSD_REV] + == test_csd[EXT_CSD_REV] && + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] + == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] && + memcmp(&ext_csd[EXT_CSD_SEC_CNT], + &test_csd[EXT_CSD_SEC_CNT], 4) == 0) + break; + + err = -EBADMSG; + } + + if (err) + return err; + + if (mmc->card_caps & MMC_MODE_HS) { + if (mmc->card_caps & MMC_MODE_HS_52MHz) + mmc->tran_speed = 52000000; + else + mmc->tran_speed = 26000000; + } + + return err; +} + static int mmc_startup(struct mmc *mmc) { int err, i; @@ -1110,7 +1256,6 @@ static int mmc_startup(struct mmc *mmc) u64 cmult, csize, capacity; struct mmc_cmd cmd; ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); - ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN); bool has_parts = false; bool part_completed; struct blk_desc *bdesc; @@ -1415,136 +1560,13 @@ static int mmc_startup(struct mmc *mmc) return err; if (IS_SD(mmc)) - err = sd_change_freq(mmc); + err = sd_select_bus_freq_width(mmc); else - err = mmc_change_freq(mmc); + err = mmc_select_bus_freq_width(mmc, ext_csd); if (err) return err; - /* Restrict card's capabilities by what the host can do */ - mmc->card_caps &= mmc->cfg->host_caps; - - if (IS_SD(mmc)) { - if (mmc->card_caps & MMC_MODE_4BIT) { - cmd.cmdidx = MMC_CMD_APP_CMD; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = mmc->rca << 16; - - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - - cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = 2; - err = mmc_send_cmd(mmc, &cmd, NULL); - if (err) - return err; - - mmc_set_bus_width(mmc, 4); - } - - err = sd_read_ssr(mmc); - if (err) - return err; - - if (mmc->card_caps & MMC_MODE_HS) - mmc->tran_speed = 50000000; - else - mmc->tran_speed = 25000000; - } else if (mmc->version >= MMC_VERSION_4) { - /* Only version 4 of MMC supports wider bus widths */ - int idx; - - /* An array of possible bus widths in order of preference */ - static unsigned ext_csd_bits[] = { - EXT_CSD_DDR_BUS_WIDTH_8, - EXT_CSD_DDR_BUS_WIDTH_4, - EXT_CSD_BUS_WIDTH_8, - EXT_CSD_BUS_WIDTH_4, - EXT_CSD_BUS_WIDTH_1, - }; - - /* An array to map CSD bus widths to host cap bits */ - static unsigned ext_to_hostcaps[] = { - [EXT_CSD_DDR_BUS_WIDTH_4] = - MMC_MODE_DDR_52MHz | MMC_MODE_4BIT, - [EXT_CSD_DDR_BUS_WIDTH_8] = - MMC_MODE_DDR_52MHz | MMC_MODE_8BIT, - [EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT, - [EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT, - }; - - /* An array to map chosen bus width to an integer */ - static unsigned widths[] = { - 8, 4, 8, 4, 1, - }; - - for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) { - unsigned int extw = ext_csd_bits[idx]; - unsigned int caps = ext_to_hostcaps[extw]; - - /* - * If the bus width is still not changed, - * don't try to set the default again. - * Otherwise, recover from switch attempts - * by switching to 1-bit bus width. - */ - if (extw == EXT_CSD_BUS_WIDTH_1 && - mmc->bus_width == 1) { - err = 0; - break; - } - - /* - * Check to make sure the card and controller support - * these capabilities - */ - if ((mmc->card_caps & caps) != caps) - continue; - - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, extw); - - if (err) - continue; - - mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0; - mmc_set_bus_width(mmc, widths[idx]); - - err = mmc_send_ext_csd(mmc, test_csd); - - if (err) - continue; - - /* Only compare read only fields */ - if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] - == test_csd[EXT_CSD_PARTITIONING_SUPPORT] && - ext_csd[EXT_CSD_HC_WP_GRP_SIZE] - == test_csd[EXT_CSD_HC_WP_GRP_SIZE] && - ext_csd[EXT_CSD_REV] - == test_csd[EXT_CSD_REV] && - ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] - == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] && - memcmp(&ext_csd[EXT_CSD_SEC_CNT], - &test_csd[EXT_CSD_SEC_CNT], 4) == 0) - break; - else - err = -EBADMSG; - } - - if (err) - return err; - - if (mmc->card_caps & MMC_MODE_HS) { - if (mmc->card_caps & MMC_MODE_HS_52MHz) - mmc->tran_speed = 52000000; - else - mmc->tran_speed = 26000000; - } - } - mmc_set_clock(mmc, mmc->tran_speed); /* Fix the block length for DDR mode */