Message ID | 20230915094351.11120-11-victorshihgli@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp1027164vqi; Fri, 15 Sep 2023 06:04:14 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE0FMrpUI3qRva5i4en77G2vSR2nTYEpyWNBRPgqQ2qkqxZrpLfnUSLqLWqpZoNL1aC2j8B X-Received: by 2002:a05:6a00:2283:b0:68e:2d2d:56c1 with SMTP id f3-20020a056a00228300b0068e2d2d56c1mr1717158pfe.9.1694783054643; Fri, 15 Sep 2023 06:04:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694783054; cv=none; d=google.com; s=arc-20160816; b=LwWrkQiRr10nTkbyrATor+T/xeZqAMsfRTyRRdb0m0+Uykl6sqxfx+onkIIG5OC6YB jC7OPFWVHH7frsQTVyXraiJ+ZFfq4xSCgrTAJZAxl0ZfT5AJDlSxK+F7KqGTJzL6IsXO MR5OyXbThG5kqQ60W4X2zh02F3HJR2FxOgauGeWy3JF+6J6K8N4rmFPxDgxFOr5bbLjo YoY4BmsikYDDWOqJ/r1disF5xzQe9upFBUAvGPXpdkCXX8svbFZaWLgUiHPypuddHadC xS4aTWxc4hSTtnZ++j0OmKjE8bJy8EHS+PM7dJMC0xN9KIb6fEsoOmsxHRC71PuUUvdT pgQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gT4GYvp7XZLzsi+yWOCwdJmnYZ/3FfZ/O3XhWmznl5k=; fh=y5fk6vguAkbcel7KoRWpitGO8B8BpGYTQpzSdaI/dY4=; b=AdyZd8SUogy08agE3Zis7e9qa+RlGW5CXsfceHY3cflj6VQ0/wVZIVZ9y4JdsvjoXz 6oXP1bZNzrAo9Y8fpFy1ImoPH6OXhbFmTx1AugBEQpzw4KF8YYo77yw36i7flajGXMHh bXqq0keDvfCco9Iu92728f+cVAfBbV0oXdKCPt+9xEOqn/4AKRL3Ek8lKXv5puiUWqeI gJVSjl55G3Qswy4JUKG9uoLrtbPUNjm4gN9g5/fPBTHJtKqxWCkEbxC0idelQ+xZajvZ nTxTsSiOeKdvrcKXSpxfyNVyPdW+nbBkXJ/4/RNCkm/933nypQMgzWH9aHWF4qv2P2Rg R2tg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b="McJTJW/D"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from pete.vger.email (pete.vger.email. [2620:137:e000::3:6]) by mx.google.com with ESMTPS id f20-20020a631014000000b005638183ab90si3143677pgl.611.2023.09.15.06.04.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 06:04:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) client-ip=2620:137:e000::3:6; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b="McJTJW/D"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 4802281A8AAE; Fri, 15 Sep 2023 02:45:52 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233671AbjIOJpH (ORCPT <rfc822;ruipengqi7@gmail.com> + 32 others); Fri, 15 Sep 2023 05:45:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233915AbjIOJo5 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 15 Sep 2023 05:44:57 -0400 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78E812D47; Fri, 15 Sep 2023 02:44:26 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1c09673b006so15393185ad.1; Fri, 15 Sep 2023 02:44:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1694771066; x=1695375866; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gT4GYvp7XZLzsi+yWOCwdJmnYZ/3FfZ/O3XhWmznl5k=; b=McJTJW/DgZqiauDdbigcinWre/ZxzJLeQXfnysdTODs20OGva3XbBMk1IR8XujRw67 WfQ9KKYLPKB7p0i+xG6jaZDddD6xznbAyA63D+t2xlPkglM6FiH4ZsfEtdQU8dLtUbjh LcolAGAka76OOZMEnd/26Ik3boEKwKo5jXAC0f32lCvGW97d332yYMhXjrJhIwUGGVn0 Mb/Z2a1lT/sgjqTsQU/o73MqWnLkdIqWPcsJLhf+rC38V62M8Tt0hp+/h2CUrkdgzMWZ eRx9yVamcqlqnRlBOuHT+NXyJqAE3J+7udYSqonvcP0wCfZ/hlN9xFW+P1kOnljEcxSM KgKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694771066; x=1695375866; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gT4GYvp7XZLzsi+yWOCwdJmnYZ/3FfZ/O3XhWmznl5k=; b=WkiKFC7jMWHZdllbS6IVPGAXmwdbFwqTBDmfl09T17jrMwV5qhxzkHlCu4AYRJRTEq K8dPuUDLCVDB9pttmo+vWoyl3H4NVBuXKnsWKxQI6wWwxsRsZmZsbFZXwKy4LTt9W5BZ 3VadwSETJVH9+g84xam5c8u47+Gn3OIyljWSgFgQZ11AI5tNHlAQwGIMtpkcFbbzp5GW laVMpjjgkw0YeUb/OEkUqIsnjCs0sViQSqTv3+gAfIzrfuIY7X3Cb+Q1LvreTVVk8lbB Kud6eqfFrOuKH2eNH11qQaARI3K0j/u4+mVlUAPPRQSTFnC8vdLEihUrqfUPmg/oVMlT U9hg== X-Gm-Message-State: AOJu0YxoIZU6OTupYsetRzZ98l12klXKXKT9ryvu1qmFRlgZGbpS9GZM bped3EfSV7d31k+uCoAy9OQ= X-Received: by 2002:a17:90a:7483:b0:273:f584:40ca with SMTP id p3-20020a17090a748300b00273f58440camr865489pjk.16.1694771065891; Fri, 15 Sep 2023 02:44:25 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e2a6-6d77-d32f-f490-6688-3d32.emome-ip6.hinet.net. [2001:b400:e2a6:6d77:d32f:f490:6688:3d32]) by smtp.gmail.com with ESMTPSA id x4-20020a17090a530400b0025023726fc4sm4432794pjh.26.2023.09.15.02.44.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 02:44:25 -0700 (PDT) From: Victor Shih <victorshihgli@gmail.com> To: ulf.hansson@linaro.org, adrian.hunter@intel.com Cc: linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, benchuanggli@gmail.com, HL.Liu@genesyslogic.com.tw, Greg.tu@genesyslogic.com.tw, takahiro.akashi@linaro.org, dlunev@chromium.org, Victor Shih <victorshihgli@gmail.com>, Ben Chuang <ben.chuang@genesyslogic.com.tw>, Victor Shih <victor.shih@genesyslogic.com.tw> Subject: [PATCH V12 10/23] mmc: sdhci-uhs2: add reset function and uhs2_mode function Date: Fri, 15 Sep 2023 17:43:38 +0800 Message-Id: <20230915094351.11120-11-victorshihgli@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230915094351.11120-1-victorshihgli@gmail.com> References: <20230915094351.11120-1-victorshihgli@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Fri, 15 Sep 2023 02:45:52 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777108836062669322 X-GMAIL-MSGID: 1777108836062669322 |
Series |
Add support UHS-II for GL9755
|
|
Commit Message
Victor Shih
Sept. 15, 2023, 9:43 a.m. UTC
From: Victor Shih <victor.shih@genesyslogic.com.tw> Sdhci_uhs2_reset() does a UHS-II specific reset operation. Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> Acked-by: Adrian Hunter <adrian.hunter@intel.com> --- Updates in V8: - Adjust the position of matching brackets. Updates in V6: - Remove unnecessary functions and simplify code. --- drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 2 ++ 2 files changed, 47 insertions(+)
Comments
On Fri, 15 Sept 2023 at 11:44, Victor Shih <victorshihgli@gmail.com> wrote: > > From: Victor Shih <victor.shih@genesyslogic.com.tw> > > Sdhci_uhs2_reset() does a UHS-II specific reset operation. > > Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> > Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> > Acked-by: Adrian Hunter <adrian.hunter@intel.com> > --- > > Updates in V8: > - Adjust the position of matching brackets. > > Updates in V6: > - Remove unnecessary functions and simplify code. > > --- > > drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ > drivers/mmc/host/sdhci-uhs2.h | 2 ++ > 2 files changed, 47 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > index e339821d3504..dfc80a7f1bad 100644 > --- a/drivers/mmc/host/sdhci-uhs2.c > +++ b/drivers/mmc/host/sdhci-uhs2.c > @@ -10,7 +10,9 @@ > * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> > */ > > +#include <linux/delay.h> > #include <linux/module.h> > +#include <linux/iopoll.h> > > #include "sdhci.h" > #include "sdhci-uhs2.h" > @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) > } > EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); > > +/*****************************************************************************\ > + * * > + * Low level functions * > + * * > +\*****************************************************************************/ > + > +bool sdhci_uhs2_mode(struct sdhci_host *host) > +{ > + return host->mmc->flags & MMC_UHS2_SUPPORT; The MMC_UHS2_SUPPORT bit looks redundant to me. Instead, I think we should be using mmc->ios.timings, which already indicates whether we are using UHS2 (MMC_TIMING_UHS2_SPEED_*). See patch2 where we added this. That said, I think we should drop the sdhci_uhs2_mode() function altogether and instead use mmc_card_uhs2(), which means we should move it to include/linux/mmc/host.h, so it becomes available for host drivers. > +} > + > +/** > + * sdhci_uhs2_reset - invoke SW reset > + * @host: SDHCI host > + * @mask: Control mask > + * > + * Invoke SW reset, depending on a bit in @mask and wait for completion. > + */ > +void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask) > +{ > + unsigned long timeout; > + u32 val; > + > + sdhci_writew(host, mask, SDHCI_UHS2_SW_RESET); > + > + if (mask & SDHCI_UHS2_SW_RESET_FULL) > + host->clock = 0; > + > + /* Wait max 100 ms */ > + timeout = 100000; Please convert into using a define and use that directly, below instead. > + > + /* hw clears the bit when it's done */ > + if (read_poll_timeout_atomic(sdhci_readw, val, !(val & mask), 10, > + timeout, true, host, SDHCI_UHS2_SW_RESET)) { > + pr_err("%s: %s: Reset 0x%x never completed.\n", __func__, > + mmc_hostname(host->mmc), (int)mask); > + pr_err("%s: clean reset bit\n", mmc_hostname(host->mmc)); It looks silly to do two pr_err immediately after each other, please combine them into one. Moreover, I think we should probably convert into using a pr_warn() instead. > + sdhci_writeb(host, 0, SDHCI_UHS2_SW_RESET); > + return; > + } > +} > +EXPORT_SYMBOL_GPL(sdhci_uhs2_reset); > + > /*****************************************************************************\ > * * > * Driver init/exit * > diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h > index 2bfe18d29bca..8253d50f7852 100644 > --- a/drivers/mmc/host/sdhci-uhs2.h > +++ b/drivers/mmc/host/sdhci-uhs2.h > @@ -177,5 +177,7 @@ > struct sdhci_host; > > void sdhci_uhs2_dump_regs(struct sdhci_host *host); > +bool sdhci_uhs2_mode(struct sdhci_host *host); > +void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask); > > #endif /* __SDHCI_UHS2_H */ > -- > 2.25.1 > Kind regards Uffe
On 3/10/23 13:30, Ulf Hansson wrote: > On Fri, 15 Sept 2023 at 11:44, Victor Shih <victorshihgli@gmail.com> wrote: >> >> From: Victor Shih <victor.shih@genesyslogic.com.tw> >> >> Sdhci_uhs2_reset() does a UHS-II specific reset operation. >> >> Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> >> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> >> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> >> Acked-by: Adrian Hunter <adrian.hunter@intel.com> >> --- >> >> Updates in V8: >> - Adjust the position of matching brackets. >> >> Updates in V6: >> - Remove unnecessary functions and simplify code. >> >> --- >> >> drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ >> drivers/mmc/host/sdhci-uhs2.h | 2 ++ >> 2 files changed, 47 insertions(+) >> >> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c >> index e339821d3504..dfc80a7f1bad 100644 >> --- a/drivers/mmc/host/sdhci-uhs2.c >> +++ b/drivers/mmc/host/sdhci-uhs2.c >> @@ -10,7 +10,9 @@ >> * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> >> */ >> >> +#include <linux/delay.h> >> #include <linux/module.h> >> +#include <linux/iopoll.h> >> >> #include "sdhci.h" >> #include "sdhci-uhs2.h" >> @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) >> } >> EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); >> >> +/*****************************************************************************\ >> + * * >> + * Low level functions * >> + * * >> +\*****************************************************************************/ >> + >> +bool sdhci_uhs2_mode(struct sdhci_host *host) >> +{ >> + return host->mmc->flags & MMC_UHS2_SUPPORT; > > The MMC_UHS2_SUPPORT bit looks redundant to me. Instead, I think we > should be using mmc->ios.timings, which already indicates whether we > are using UHS2 (MMC_TIMING_UHS2_SPEED_*). See patch2 where we added > this. > > That said, I think we should drop the sdhci_uhs2_mode() function > altogether and instead use mmc_card_uhs2(), which means we should move > it to include/linux/mmc/host.h, so it becomes available for host > drivers. > UHS2 mode starts at UHS2 initialization and ends either when UHS2 initialization fails, or the card is removed. So it includes re-initialization and reset when the transfer mode currently transitions through MMC_TIMING_LEGACY. So mmc_card_uhs2() won't work correctly for the host callbacks unless something is done about that.
On Tue, 3 Oct 2023 at 13:37, Adrian Hunter <adrian.hunter@intel.com> wrote: > > On 3/10/23 13:30, Ulf Hansson wrote: > > On Fri, 15 Sept 2023 at 11:44, Victor Shih <victorshihgli@gmail.com> wrote: > >> > >> From: Victor Shih <victor.shih@genesyslogic.com.tw> > >> > >> Sdhci_uhs2_reset() does a UHS-II specific reset operation. > >> > >> Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> > >> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> > >> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> > >> Acked-by: Adrian Hunter <adrian.hunter@intel.com> > >> --- > >> > >> Updates in V8: > >> - Adjust the position of matching brackets. > >> > >> Updates in V6: > >> - Remove unnecessary functions and simplify code. > >> > >> --- > >> > >> drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ > >> drivers/mmc/host/sdhci-uhs2.h | 2 ++ > >> 2 files changed, 47 insertions(+) > >> > >> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > >> index e339821d3504..dfc80a7f1bad 100644 > >> --- a/drivers/mmc/host/sdhci-uhs2.c > >> +++ b/drivers/mmc/host/sdhci-uhs2.c > >> @@ -10,7 +10,9 @@ > >> * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> > >> */ > >> > >> +#include <linux/delay.h> > >> #include <linux/module.h> > >> +#include <linux/iopoll.h> > >> > >> #include "sdhci.h" > >> #include "sdhci-uhs2.h" > >> @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) > >> } > >> EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); > >> > >> +/*****************************************************************************\ > >> + * * > >> + * Low level functions * > >> + * * > >> +\*****************************************************************************/ > >> + > >> +bool sdhci_uhs2_mode(struct sdhci_host *host) > >> +{ > >> + return host->mmc->flags & MMC_UHS2_SUPPORT; > > > > The MMC_UHS2_SUPPORT bit looks redundant to me. Instead, I think we > > should be using mmc->ios.timings, which already indicates whether we > > are using UHS2 (MMC_TIMING_UHS2_SPEED_*). See patch2 where we added > > this. > > > > That said, I think we should drop the sdhci_uhs2_mode() function > > altogether and instead use mmc_card_uhs2(), which means we should move > > it to include/linux/mmc/host.h, so it becomes available for host > > drivers. > > > > UHS2 mode starts at UHS2 initialization and ends either when UHS2 > initialization fails, or the card is removed. > > So it includes re-initialization and reset when the transfer mode > currently transitions through MMC_TIMING_LEGACY. > > So mmc_card_uhs2() won't work correctly for the host callbacks > unless something is done about that. Right, thanks for clarifying! In that case I wonder if we couldn't change the way we update the ->ios.timing for UHS2. It seems silly to have two (similar) ways to indicate that we have moved to UHS2. Kind regards Uffe
On 3/10/23 15:22, Ulf Hansson wrote: > On Tue, 3 Oct 2023 at 13:37, Adrian Hunter <adrian.hunter@intel.com> wrote: >> >> On 3/10/23 13:30, Ulf Hansson wrote: >>> On Fri, 15 Sept 2023 at 11:44, Victor Shih <victorshihgli@gmail.com> wrote: >>>> >>>> From: Victor Shih <victor.shih@genesyslogic.com.tw> >>>> >>>> Sdhci_uhs2_reset() does a UHS-II specific reset operation. >>>> >>>> Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> >>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> >>>> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> >>>> Acked-by: Adrian Hunter <adrian.hunter@intel.com> >>>> --- >>>> >>>> Updates in V8: >>>> - Adjust the position of matching brackets. >>>> >>>> Updates in V6: >>>> - Remove unnecessary functions and simplify code. >>>> >>>> --- >>>> >>>> drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ >>>> drivers/mmc/host/sdhci-uhs2.h | 2 ++ >>>> 2 files changed, 47 insertions(+) >>>> >>>> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c >>>> index e339821d3504..dfc80a7f1bad 100644 >>>> --- a/drivers/mmc/host/sdhci-uhs2.c >>>> +++ b/drivers/mmc/host/sdhci-uhs2.c >>>> @@ -10,7 +10,9 @@ >>>> * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> >>>> */ >>>> >>>> +#include <linux/delay.h> >>>> #include <linux/module.h> >>>> +#include <linux/iopoll.h> >>>> >>>> #include "sdhci.h" >>>> #include "sdhci-uhs2.h" >>>> @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) >>>> } >>>> EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); >>>> >>>> +/*****************************************************************************\ >>>> + * * >>>> + * Low level functions * >>>> + * * >>>> +\*****************************************************************************/ >>>> + >>>> +bool sdhci_uhs2_mode(struct sdhci_host *host) >>>> +{ >>>> + return host->mmc->flags & MMC_UHS2_SUPPORT; >>> >>> The MMC_UHS2_SUPPORT bit looks redundant to me. Instead, I think we >>> should be using mmc->ios.timings, which already indicates whether we >>> are using UHS2 (MMC_TIMING_UHS2_SPEED_*). See patch2 where we added >>> this. >>> >>> That said, I think we should drop the sdhci_uhs2_mode() function >>> altogether and instead use mmc_card_uhs2(), which means we should move >>> it to include/linux/mmc/host.h, so it becomes available for host >>> drivers. >>> >> >> UHS2 mode starts at UHS2 initialization and ends either when UHS2 >> initialization fails, or the card is removed. >> >> So it includes re-initialization and reset when the transfer mode >> currently transitions through MMC_TIMING_LEGACY. >> >> So mmc_card_uhs2() won't work correctly for the host callbacks >> unless something is done about that. > > Right, thanks for clarifying! > > In that case I wonder if we couldn't change the way we update the > ->ios.timing for UHS2. It seems silly to have two (similar) ways to > indicate that we have moved to UHS2. Perhaps something like below: diff --git a/drivers/mmc/core/sd_uhs2.c b/drivers/mmc/core/sd_uhs2.c index aacefdd6bc9e..e39d63d46041 100644 --- a/drivers/mmc/core/sd_uhs2.c +++ b/drivers/mmc/core/sd_uhs2.c @@ -70,7 +70,8 @@ static int sd_uhs2_power_off(struct mmc_host *host) host->ios.vdd = 0; host->ios.clock = 0; - host->ios.timing = MMC_TIMING_LEGACY; + /* Must set UHS2 timing to identify UHS2 mode */ + host->ios.timing = MMC_TIMING_UHS2_SPEED_A; host->ios.power_mode = MMC_POWER_OFF; if (host->flags & MMC_UHS2_SD_TRAN) host->flags &= ~MMC_UHS2_SD_TRAN; @@ -1095,7 +1096,8 @@ static void sd_uhs2_detect(struct mmc_host *host) mmc_claim_host(host); mmc_detach_bus(host); sd_uhs2_power_off(host); - host->flags &= ~MMC_UHS2_SUPPORT; + /* Remove UHS2 timing to indicate the end of UHS2 mode */ + host->ios.timing = MMC_TIMING_LEGACY; mmc_release_host(host); } } @@ -1338,7 +1340,8 @@ static int sd_uhs2_attach(struct mmc_host *host) err: mmc_detach_bus(host); sd_uhs2_power_off(host); - host->flags &= ~MMC_UHS2_SUPPORT; + /* Remove UHS2 timing to indicate the end of UHS2 mode */ + host->ios.timing = MMC_TIMING_LEGACY; return err; } diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 517c497112f4..d1f3318b7d3a 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -267,10 +267,11 @@ static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* UHS2 timing. Note, UHS2 timing is disabled when powering off */ ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); - if (ios->timing == MMC_TIMING_UHS2_SPEED_A || - ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || - ios->timing == MMC_TIMING_UHS2_SPEED_B || - ios->timing == MMC_TIMING_UHS2_SPEED_B_HD) + if (ios->power_mode != MMC_POWER_OFF && + (ios->timing == MMC_TIMING_UHS2_SPEED_A || + ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || + ios->timing == MMC_TIMING_UHS2_SPEED_B || + ios->timing == MMC_TIMING_UHS2_SPEED_B_HD)) ctrl_2 |= SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE; else ctrl_2 &= ~(SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE);
On Tue, 3 Oct 2023 at 17:03, Adrian Hunter <adrian.hunter@intel.com> wrote: > > On 3/10/23 15:22, Ulf Hansson wrote: > > On Tue, 3 Oct 2023 at 13:37, Adrian Hunter <adrian.hunter@intel.com> wrote: > >> > >> On 3/10/23 13:30, Ulf Hansson wrote: > >>> On Fri, 15 Sept 2023 at 11:44, Victor Shih <victorshihgli@gmail.com> wrote: > >>>> > >>>> From: Victor Shih <victor.shih@genesyslogic.com.tw> > >>>> > >>>> Sdhci_uhs2_reset() does a UHS-II specific reset operation. > >>>> > >>>> Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> > >>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> > >>>> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> > >>>> Acked-by: Adrian Hunter <adrian.hunter@intel.com> > >>>> --- > >>>> > >>>> Updates in V8: > >>>> - Adjust the position of matching brackets. > >>>> > >>>> Updates in V6: > >>>> - Remove unnecessary functions and simplify code. > >>>> > >>>> --- > >>>> > >>>> drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ > >>>> drivers/mmc/host/sdhci-uhs2.h | 2 ++ > >>>> 2 files changed, 47 insertions(+) > >>>> > >>>> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > >>>> index e339821d3504..dfc80a7f1bad 100644 > >>>> --- a/drivers/mmc/host/sdhci-uhs2.c > >>>> +++ b/drivers/mmc/host/sdhci-uhs2.c > >>>> @@ -10,7 +10,9 @@ > >>>> * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> > >>>> */ > >>>> > >>>> +#include <linux/delay.h> > >>>> #include <linux/module.h> > >>>> +#include <linux/iopoll.h> > >>>> > >>>> #include "sdhci.h" > >>>> #include "sdhci-uhs2.h" > >>>> @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) > >>>> } > >>>> EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); > >>>> > >>>> +/*****************************************************************************\ > >>>> + * * > >>>> + * Low level functions * > >>>> + * * > >>>> +\*****************************************************************************/ > >>>> + > >>>> +bool sdhci_uhs2_mode(struct sdhci_host *host) > >>>> +{ > >>>> + return host->mmc->flags & MMC_UHS2_SUPPORT; > >>> > >>> The MMC_UHS2_SUPPORT bit looks redundant to me. Instead, I think we > >>> should be using mmc->ios.timings, which already indicates whether we > >>> are using UHS2 (MMC_TIMING_UHS2_SPEED_*). See patch2 where we added > >>> this. > >>> > >>> That said, I think we should drop the sdhci_uhs2_mode() function > >>> altogether and instead use mmc_card_uhs2(), which means we should move > >>> it to include/linux/mmc/host.h, so it becomes available for host > >>> drivers. > >>> > >> > >> UHS2 mode starts at UHS2 initialization and ends either when UHS2 > >> initialization fails, or the card is removed. > >> > >> So it includes re-initialization and reset when the transfer mode > >> currently transitions through MMC_TIMING_LEGACY. > >> > >> So mmc_card_uhs2() won't work correctly for the host callbacks > >> unless something is done about that. > > > > Right, thanks for clarifying! > > > > In that case I wonder if we couldn't change the way we update the > > ->ios.timing for UHS2. It seems silly to have two (similar) ways to > > indicate that we have moved to UHS2. > > Perhaps something like below: > > diff --git a/drivers/mmc/core/sd_uhs2.c b/drivers/mmc/core/sd_uhs2.c > index aacefdd6bc9e..e39d63d46041 100644 > --- a/drivers/mmc/core/sd_uhs2.c > +++ b/drivers/mmc/core/sd_uhs2.c > @@ -70,7 +70,8 @@ static int sd_uhs2_power_off(struct mmc_host *host) > > host->ios.vdd = 0; > host->ios.clock = 0; > - host->ios.timing = MMC_TIMING_LEGACY; > + /* Must set UHS2 timing to identify UHS2 mode */ > + host->ios.timing = MMC_TIMING_UHS2_SPEED_A; > host->ios.power_mode = MMC_POWER_OFF; > if (host->flags & MMC_UHS2_SD_TRAN) > host->flags &= ~MMC_UHS2_SD_TRAN; > @@ -1095,7 +1096,8 @@ static void sd_uhs2_detect(struct mmc_host *host) > mmc_claim_host(host); > mmc_detach_bus(host); > sd_uhs2_power_off(host); > - host->flags &= ~MMC_UHS2_SUPPORT; > + /* Remove UHS2 timing to indicate the end of UHS2 mode */ > + host->ios.timing = MMC_TIMING_LEGACY; > mmc_release_host(host); > } > } > @@ -1338,7 +1340,8 @@ static int sd_uhs2_attach(struct mmc_host *host) > err: > mmc_detach_bus(host); > sd_uhs2_power_off(host); > - host->flags &= ~MMC_UHS2_SUPPORT; > + /* Remove UHS2 timing to indicate the end of UHS2 mode */ > + host->ios.timing = MMC_TIMING_LEGACY; > return err; > } I wouldn't mind changing to the above. But, maybe an even better option is to use the ->timing variable in the struct sdhci_host, as it's there already to keep track of the current/previous timing state. Would that work too? > > diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > index 517c497112f4..d1f3318b7d3a 100644 > --- a/drivers/mmc/host/sdhci-uhs2.c > +++ b/drivers/mmc/host/sdhci-uhs2.c > @@ -267,10 +267,11 @@ static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > > /* UHS2 timing. Note, UHS2 timing is disabled when powering off */ > ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); > - if (ios->timing == MMC_TIMING_UHS2_SPEED_A || > - ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || > - ios->timing == MMC_TIMING_UHS2_SPEED_B || > - ios->timing == MMC_TIMING_UHS2_SPEED_B_HD) > + if (ios->power_mode != MMC_POWER_OFF && > + (ios->timing == MMC_TIMING_UHS2_SPEED_A || > + ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || > + ios->timing == MMC_TIMING_UHS2_SPEED_B || > + ios->timing == MMC_TIMING_UHS2_SPEED_B_HD)) > ctrl_2 |= SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE; > else > ctrl_2 &= ~(SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE); > > Kind regards Uffe
On 4/10/23 11:35, Ulf Hansson wrote: > On Tue, 3 Oct 2023 at 17:03, Adrian Hunter <adrian.hunter@intel.com> wrote: >> >> On 3/10/23 15:22, Ulf Hansson wrote: >>> On Tue, 3 Oct 2023 at 13:37, Adrian Hunter <adrian.hunter@intel.com> wrote: >>>> >>>> On 3/10/23 13:30, Ulf Hansson wrote: >>>>> On Fri, 15 Sept 2023 at 11:44, Victor Shih <victorshihgli@gmail.com> wrote: >>>>>> >>>>>> From: Victor Shih <victor.shih@genesyslogic.com.tw> >>>>>> >>>>>> Sdhci_uhs2_reset() does a UHS-II specific reset operation. >>>>>> >>>>>> Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> >>>>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> >>>>>> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> >>>>>> Acked-by: Adrian Hunter <adrian.hunter@intel.com> >>>>>> --- >>>>>> >>>>>> Updates in V8: >>>>>> - Adjust the position of matching brackets. >>>>>> >>>>>> Updates in V6: >>>>>> - Remove unnecessary functions and simplify code. >>>>>> >>>>>> --- >>>>>> >>>>>> drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ >>>>>> drivers/mmc/host/sdhci-uhs2.h | 2 ++ >>>>>> 2 files changed, 47 insertions(+) >>>>>> >>>>>> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c >>>>>> index e339821d3504..dfc80a7f1bad 100644 >>>>>> --- a/drivers/mmc/host/sdhci-uhs2.c >>>>>> +++ b/drivers/mmc/host/sdhci-uhs2.c >>>>>> @@ -10,7 +10,9 @@ >>>>>> * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> >>>>>> */ >>>>>> >>>>>> +#include <linux/delay.h> >>>>>> #include <linux/module.h> >>>>>> +#include <linux/iopoll.h> >>>>>> >>>>>> #include "sdhci.h" >>>>>> #include "sdhci-uhs2.h" >>>>>> @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) >>>>>> } >>>>>> EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); >>>>>> >>>>>> +/*****************************************************************************\ >>>>>> + * * >>>>>> + * Low level functions * >>>>>> + * * >>>>>> +\*****************************************************************************/ >>>>>> + >>>>>> +bool sdhci_uhs2_mode(struct sdhci_host *host) >>>>>> +{ >>>>>> + return host->mmc->flags & MMC_UHS2_SUPPORT; >>>>> >>>>> The MMC_UHS2_SUPPORT bit looks redundant to me. Instead, I think we >>>>> should be using mmc->ios.timings, which already indicates whether we >>>>> are using UHS2 (MMC_TIMING_UHS2_SPEED_*). See patch2 where we added >>>>> this. >>>>> >>>>> That said, I think we should drop the sdhci_uhs2_mode() function >>>>> altogether and instead use mmc_card_uhs2(), which means we should move >>>>> it to include/linux/mmc/host.h, so it becomes available for host >>>>> drivers. >>>>> >>>> >>>> UHS2 mode starts at UHS2 initialization and ends either when UHS2 >>>> initialization fails, or the card is removed. >>>> >>>> So it includes re-initialization and reset when the transfer mode >>>> currently transitions through MMC_TIMING_LEGACY. >>>> >>>> So mmc_card_uhs2() won't work correctly for the host callbacks >>>> unless something is done about that. >>> >>> Right, thanks for clarifying! >>> >>> In that case I wonder if we couldn't change the way we update the >>> ->ios.timing for UHS2. It seems silly to have two (similar) ways to >>> indicate that we have moved to UHS2. >> >> Perhaps something like below: >> >> diff --git a/drivers/mmc/core/sd_uhs2.c b/drivers/mmc/core/sd_uhs2.c >> index aacefdd6bc9e..e39d63d46041 100644 >> --- a/drivers/mmc/core/sd_uhs2.c >> +++ b/drivers/mmc/core/sd_uhs2.c >> @@ -70,7 +70,8 @@ static int sd_uhs2_power_off(struct mmc_host *host) >> >> host->ios.vdd = 0; >> host->ios.clock = 0; >> - host->ios.timing = MMC_TIMING_LEGACY; >> + /* Must set UHS2 timing to identify UHS2 mode */ >> + host->ios.timing = MMC_TIMING_UHS2_SPEED_A; >> host->ios.power_mode = MMC_POWER_OFF; >> if (host->flags & MMC_UHS2_SD_TRAN) >> host->flags &= ~MMC_UHS2_SD_TRAN; >> @@ -1095,7 +1096,8 @@ static void sd_uhs2_detect(struct mmc_host *host) >> mmc_claim_host(host); >> mmc_detach_bus(host); >> sd_uhs2_power_off(host); >> - host->flags &= ~MMC_UHS2_SUPPORT; >> + /* Remove UHS2 timing to indicate the end of UHS2 mode */ >> + host->ios.timing = MMC_TIMING_LEGACY; >> mmc_release_host(host); >> } >> } >> @@ -1338,7 +1340,8 @@ static int sd_uhs2_attach(struct mmc_host *host) >> err: >> mmc_detach_bus(host); >> sd_uhs2_power_off(host); >> - host->flags &= ~MMC_UHS2_SUPPORT; >> + /* Remove UHS2 timing to indicate the end of UHS2 mode */ >> + host->ios.timing = MMC_TIMING_LEGACY; >> return err; >> } > > I wouldn't mind changing to the above. But, maybe an even better > option is to use the ->timing variable in the struct sdhci_host, as > it's there already to keep track of the current/previous timing state. > Would that work too? The host does not really have enough information. > >> >> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c >> index 517c497112f4..d1f3318b7d3a 100644 >> --- a/drivers/mmc/host/sdhci-uhs2.c >> +++ b/drivers/mmc/host/sdhci-uhs2.c >> @@ -267,10 +267,11 @@ static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) >> >> /* UHS2 timing. Note, UHS2 timing is disabled when powering off */ >> ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); >> - if (ios->timing == MMC_TIMING_UHS2_SPEED_A || >> - ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || >> - ios->timing == MMC_TIMING_UHS2_SPEED_B || >> - ios->timing == MMC_TIMING_UHS2_SPEED_B_HD) >> + if (ios->power_mode != MMC_POWER_OFF && >> + (ios->timing == MMC_TIMING_UHS2_SPEED_A || >> + ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || >> + ios->timing == MMC_TIMING_UHS2_SPEED_B || >> + ios->timing == MMC_TIMING_UHS2_SPEED_B_HD)) >> ctrl_2 |= SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE; >> else >> ctrl_2 &= ~(SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE); >> >> > > Kind regards > Uffe
On Tue, 10 Oct 2023 at 12:29, Adrian Hunter <adrian.hunter@intel.com> wrote: > > On 4/10/23 11:35, Ulf Hansson wrote: > > On Tue, 3 Oct 2023 at 17:03, Adrian Hunter <adrian.hunter@intel.com> wrote: > >> > >> On 3/10/23 15:22, Ulf Hansson wrote: > >>> On Tue, 3 Oct 2023 at 13:37, Adrian Hunter <adrian.hunter@intel.com> wrote: > >>>> > >>>> On 3/10/23 13:30, Ulf Hansson wrote: > >>>>> On Fri, 15 Sept 2023 at 11:44, Victor Shih <victorshihgli@gmail.com> wrote: > >>>>>> > >>>>>> From: Victor Shih <victor.shih@genesyslogic.com.tw> > >>>>>> > >>>>>> Sdhci_uhs2_reset() does a UHS-II specific reset operation. > >>>>>> > >>>>>> Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> > >>>>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> > >>>>>> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> > >>>>>> Acked-by: Adrian Hunter <adrian.hunter@intel.com> > >>>>>> --- > >>>>>> > >>>>>> Updates in V8: > >>>>>> - Adjust the position of matching brackets. > >>>>>> > >>>>>> Updates in V6: > >>>>>> - Remove unnecessary functions and simplify code. > >>>>>> > >>>>>> --- > >>>>>> > >>>>>> drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ > >>>>>> drivers/mmc/host/sdhci-uhs2.h | 2 ++ > >>>>>> 2 files changed, 47 insertions(+) > >>>>>> > >>>>>> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > >>>>>> index e339821d3504..dfc80a7f1bad 100644 > >>>>>> --- a/drivers/mmc/host/sdhci-uhs2.c > >>>>>> +++ b/drivers/mmc/host/sdhci-uhs2.c > >>>>>> @@ -10,7 +10,9 @@ > >>>>>> * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> > >>>>>> */ > >>>>>> > >>>>>> +#include <linux/delay.h> > >>>>>> #include <linux/module.h> > >>>>>> +#include <linux/iopoll.h> > >>>>>> > >>>>>> #include "sdhci.h" > >>>>>> #include "sdhci-uhs2.h" > >>>>>> @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) > >>>>>> } > >>>>>> EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); > >>>>>> > >>>>>> +/*****************************************************************************\ > >>>>>> + * * > >>>>>> + * Low level functions * > >>>>>> + * * > >>>>>> +\*****************************************************************************/ > >>>>>> + > >>>>>> +bool sdhci_uhs2_mode(struct sdhci_host *host) > >>>>>> +{ > >>>>>> + return host->mmc->flags & MMC_UHS2_SUPPORT; > >>>>> > >>>>> The MMC_UHS2_SUPPORT bit looks redundant to me. Instead, I think we > >>>>> should be using mmc->ios.timings, which already indicates whether we > >>>>> are using UHS2 (MMC_TIMING_UHS2_SPEED_*). See patch2 where we added > >>>>> this. > >>>>> > >>>>> That said, I think we should drop the sdhci_uhs2_mode() function > >>>>> altogether and instead use mmc_card_uhs2(), which means we should move > >>>>> it to include/linux/mmc/host.h, so it becomes available for host > >>>>> drivers. > >>>>> > >>>> > >>>> UHS2 mode starts at UHS2 initialization and ends either when UHS2 > >>>> initialization fails, or the card is removed. > >>>> > >>>> So it includes re-initialization and reset when the transfer mode > >>>> currently transitions through MMC_TIMING_LEGACY. > >>>> > >>>> So mmc_card_uhs2() won't work correctly for the host callbacks > >>>> unless something is done about that. > >>> > >>> Right, thanks for clarifying! > >>> > >>> In that case I wonder if we couldn't change the way we update the > >>> ->ios.timing for UHS2. It seems silly to have two (similar) ways to > >>> indicate that we have moved to UHS2. > >> > >> Perhaps something like below: > >> > >> diff --git a/drivers/mmc/core/sd_uhs2.c b/drivers/mmc/core/sd_uhs2.c > >> index aacefdd6bc9e..e39d63d46041 100644 > >> --- a/drivers/mmc/core/sd_uhs2.c > >> +++ b/drivers/mmc/core/sd_uhs2.c > >> @@ -70,7 +70,8 @@ static int sd_uhs2_power_off(struct mmc_host *host) > >> > >> host->ios.vdd = 0; > >> host->ios.clock = 0; > >> - host->ios.timing = MMC_TIMING_LEGACY; > >> + /* Must set UHS2 timing to identify UHS2 mode */ > >> + host->ios.timing = MMC_TIMING_UHS2_SPEED_A; > >> host->ios.power_mode = MMC_POWER_OFF; > >> if (host->flags & MMC_UHS2_SD_TRAN) > >> host->flags &= ~MMC_UHS2_SD_TRAN; > >> @@ -1095,7 +1096,8 @@ static void sd_uhs2_detect(struct mmc_host *host) > >> mmc_claim_host(host); > >> mmc_detach_bus(host); > >> sd_uhs2_power_off(host); > >> - host->flags &= ~MMC_UHS2_SUPPORT; > >> + /* Remove UHS2 timing to indicate the end of UHS2 mode */ > >> + host->ios.timing = MMC_TIMING_LEGACY; > >> mmc_release_host(host); > >> } > >> } > >> @@ -1338,7 +1340,8 @@ static int sd_uhs2_attach(struct mmc_host *host) > >> err: > >> mmc_detach_bus(host); > >> sd_uhs2_power_off(host); > >> - host->flags &= ~MMC_UHS2_SUPPORT; > >> + /* Remove UHS2 timing to indicate the end of UHS2 mode */ > >> + host->ios.timing = MMC_TIMING_LEGACY; > >> return err; > >> } > > > > I wouldn't mind changing to the above. But, maybe an even better > > option is to use the ->timing variable in the struct sdhci_host, as > > it's there already to keep track of the current/previous timing state. > > Would that work too? > > The host does not really have enough information. Okay, let's go with the approach you suggested above/below then! > > > > >> > >> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > >> index 517c497112f4..d1f3318b7d3a 100644 > >> --- a/drivers/mmc/host/sdhci-uhs2.c > >> +++ b/drivers/mmc/host/sdhci-uhs2.c > >> @@ -267,10 +267,11 @@ static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > >> > >> /* UHS2 timing. Note, UHS2 timing is disabled when powering off */ > >> ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); > >> - if (ios->timing == MMC_TIMING_UHS2_SPEED_A || > >> - ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || > >> - ios->timing == MMC_TIMING_UHS2_SPEED_B || > >> - ios->timing == MMC_TIMING_UHS2_SPEED_B_HD) > >> + if (ios->power_mode != MMC_POWER_OFF && > >> + (ios->timing == MMC_TIMING_UHS2_SPEED_A || > >> + ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || > >> + ios->timing == MMC_TIMING_UHS2_SPEED_B || > >> + ios->timing == MMC_TIMING_UHS2_SPEED_B_HD)) > >> ctrl_2 |= SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE; > >> else > >> ctrl_2 &= ~(SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE); > >> > >> Kind regards Uffe
On Tue, Oct 10, 2023 at 7:08 PM Ulf Hansson <ulf.hansson@linaro.org> wrote: > > On Tue, 10 Oct 2023 at 12:29, Adrian Hunter <adrian.hunter@intel.com> wrote: > > > > On 4/10/23 11:35, Ulf Hansson wrote: > > > On Tue, 3 Oct 2023 at 17:03, Adrian Hunter <adrian.hunter@intel.com> wrote: > > >> > > >> On 3/10/23 15:22, Ulf Hansson wrote: > > >>> On Tue, 3 Oct 2023 at 13:37, Adrian Hunter <adrian.hunter@intel.com> wrote: > > >>>> > > >>>> On 3/10/23 13:30, Ulf Hansson wrote: > > >>>>> On Fri, 15 Sept 2023 at 11:44, Victor Shih <victorshihgli@gmail.com> wrote: > > >>>>>> > > >>>>>> From: Victor Shih <victor.shih@genesyslogic.com.tw> > > >>>>>> > > >>>>>> Sdhci_uhs2_reset() does a UHS-II specific reset operation. > > >>>>>> > > >>>>>> Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> > > >>>>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> > > >>>>>> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> > > >>>>>> Acked-by: Adrian Hunter <adrian.hunter@intel.com> > > >>>>>> --- > > >>>>>> > > >>>>>> Updates in V8: > > >>>>>> - Adjust the position of matching brackets. > > >>>>>> > > >>>>>> Updates in V6: > > >>>>>> - Remove unnecessary functions and simplify code. > > >>>>>> > > >>>>>> --- > > >>>>>> > > >>>>>> drivers/mmc/host/sdhci-uhs2.c | 45 +++++++++++++++++++++++++++++++++++ > > >>>>>> drivers/mmc/host/sdhci-uhs2.h | 2 ++ > > >>>>>> 2 files changed, 47 insertions(+) > > >>>>>> > > >>>>>> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > > >>>>>> index e339821d3504..dfc80a7f1bad 100644 > > >>>>>> --- a/drivers/mmc/host/sdhci-uhs2.c > > >>>>>> +++ b/drivers/mmc/host/sdhci-uhs2.c > > >>>>>> @@ -10,7 +10,9 @@ > > >>>>>> * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> > > >>>>>> */ > > >>>>>> > > >>>>>> +#include <linux/delay.h> > > >>>>>> #include <linux/module.h> > > >>>>>> +#include <linux/iopoll.h> > > >>>>>> > > >>>>>> #include "sdhci.h" > > >>>>>> #include "sdhci-uhs2.h" > > >>>>>> @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) > > >>>>>> } > > >>>>>> EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); > > >>>>>> > > >>>>>> +/*****************************************************************************\ > > >>>>>> + * * > > >>>>>> + * Low level functions * > > >>>>>> + * * > > >>>>>> +\*****************************************************************************/ > > >>>>>> + > > >>>>>> +bool sdhci_uhs2_mode(struct sdhci_host *host) > > >>>>>> +{ > > >>>>>> + return host->mmc->flags & MMC_UHS2_SUPPORT; > > >>>>> > > >>>>> The MMC_UHS2_SUPPORT bit looks redundant to me. Instead, I think we > > >>>>> should be using mmc->ios.timings, which already indicates whether we > > >>>>> are using UHS2 (MMC_TIMING_UHS2_SPEED_*). See patch2 where we added > > >>>>> this. > > >>>>> > > >>>>> That said, I think we should drop the sdhci_uhs2_mode() function > > >>>>> altogether and instead use mmc_card_uhs2(), which means we should move > > >>>>> it to include/linux/mmc/host.h, so it becomes available for host > > >>>>> drivers. > > >>>>> > > >>>> > > >>>> UHS2 mode starts at UHS2 initialization and ends either when UHS2 > > >>>> initialization fails, or the card is removed. > > >>>> > > >>>> So it includes re-initialization and reset when the transfer mode > > >>>> currently transitions through MMC_TIMING_LEGACY. > > >>>> > > >>>> So mmc_card_uhs2() won't work correctly for the host callbacks > > >>>> unless something is done about that. > > >>> > > >>> Right, thanks for clarifying! > > >>> > > >>> In that case I wonder if we couldn't change the way we update the > > >>> ->ios.timing for UHS2. It seems silly to have two (similar) ways to > > >>> indicate that we have moved to UHS2. > > >> > > >> Perhaps something like below: > > >> > > >> diff --git a/drivers/mmc/core/sd_uhs2.c b/drivers/mmc/core/sd_uhs2.c > > >> index aacefdd6bc9e..e39d63d46041 100644 > > >> --- a/drivers/mmc/core/sd_uhs2.c > > >> +++ b/drivers/mmc/core/sd_uhs2.c > > >> @@ -70,7 +70,8 @@ static int sd_uhs2_power_off(struct mmc_host *host) > > >> > > >> host->ios.vdd = 0; > > >> host->ios.clock = 0; > > >> - host->ios.timing = MMC_TIMING_LEGACY; > > >> + /* Must set UHS2 timing to identify UHS2 mode */ > > >> + host->ios.timing = MMC_TIMING_UHS2_SPEED_A; > > >> host->ios.power_mode = MMC_POWER_OFF; > > >> if (host->flags & MMC_UHS2_SD_TRAN) > > >> host->flags &= ~MMC_UHS2_SD_TRAN; > > >> @@ -1095,7 +1096,8 @@ static void sd_uhs2_detect(struct mmc_host *host) > > >> mmc_claim_host(host); > > >> mmc_detach_bus(host); > > >> sd_uhs2_power_off(host); > > >> - host->flags &= ~MMC_UHS2_SUPPORT; > > >> + /* Remove UHS2 timing to indicate the end of UHS2 mode */ > > >> + host->ios.timing = MMC_TIMING_LEGACY; > > >> mmc_release_host(host); > > >> } > > >> } > > >> @@ -1338,7 +1340,8 @@ static int sd_uhs2_attach(struct mmc_host *host) > > >> err: > > >> mmc_detach_bus(host); > > >> sd_uhs2_power_off(host); > > >> - host->flags &= ~MMC_UHS2_SUPPORT; > > >> + /* Remove UHS2 timing to indicate the end of UHS2 mode */ > > >> + host->ios.timing = MMC_TIMING_LEGACY; > > >> return err; > > >> } > > > > > > I wouldn't mind changing to the above. But, maybe an even better > > > option is to use the ->timing variable in the struct sdhci_host, as > > > it's there already to keep track of the current/previous timing state. > > > Would that work too? > > > > The host does not really have enough information. > > Okay, let's go with the approach you suggested above/below then! > Hi, Ulf and Adrian I will update this in version 13. Thanks, Victor Shih > > > > > > > >> > > >> diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c > > >> index 517c497112f4..d1f3318b7d3a 100644 > > >> --- a/drivers/mmc/host/sdhci-uhs2.c > > >> +++ b/drivers/mmc/host/sdhci-uhs2.c > > >> @@ -267,10 +267,11 @@ static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > > >> > > >> /* UHS2 timing. Note, UHS2 timing is disabled when powering off */ > > >> ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); > > >> - if (ios->timing == MMC_TIMING_UHS2_SPEED_A || > > >> - ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || > > >> - ios->timing == MMC_TIMING_UHS2_SPEED_B || > > >> - ios->timing == MMC_TIMING_UHS2_SPEED_B_HD) > > >> + if (ios->power_mode != MMC_POWER_OFF && > > >> + (ios->timing == MMC_TIMING_UHS2_SPEED_A || > > >> + ios->timing == MMC_TIMING_UHS2_SPEED_A_HD || > > >> + ios->timing == MMC_TIMING_UHS2_SPEED_B || > > >> + ios->timing == MMC_TIMING_UHS2_SPEED_B_HD)) > > >> ctrl_2 |= SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE; > > >> else > > >> ctrl_2 &= ~(SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE); > > >> > > >> > > Kind regards > Uffe
diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index e339821d3504..dfc80a7f1bad 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -10,7 +10,9 @@ * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> */ +#include <linux/delay.h> #include <linux/module.h> +#include <linux/iopoll.h> #include "sdhci.h" #include "sdhci-uhs2.h" @@ -49,6 +51,49 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) } EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); +/*****************************************************************************\ + * * + * Low level functions * + * * +\*****************************************************************************/ + +bool sdhci_uhs2_mode(struct sdhci_host *host) +{ + return host->mmc->flags & MMC_UHS2_SUPPORT; +} + +/** + * sdhci_uhs2_reset - invoke SW reset + * @host: SDHCI host + * @mask: Control mask + * + * Invoke SW reset, depending on a bit in @mask and wait for completion. + */ +void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask) +{ + unsigned long timeout; + u32 val; + + sdhci_writew(host, mask, SDHCI_UHS2_SW_RESET); + + if (mask & SDHCI_UHS2_SW_RESET_FULL) + host->clock = 0; + + /* Wait max 100 ms */ + timeout = 100000; + + /* hw clears the bit when it's done */ + if (read_poll_timeout_atomic(sdhci_readw, val, !(val & mask), 10, + timeout, true, host, SDHCI_UHS2_SW_RESET)) { + pr_err("%s: %s: Reset 0x%x never completed.\n", __func__, + mmc_hostname(host->mmc), (int)mask); + pr_err("%s: clean reset bit\n", mmc_hostname(host->mmc)); + sdhci_writeb(host, 0, SDHCI_UHS2_SW_RESET); + return; + } +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_reset); + /*****************************************************************************\ * * * Driver init/exit * diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index 2bfe18d29bca..8253d50f7852 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -177,5 +177,7 @@ struct sdhci_host; void sdhci_uhs2_dump_regs(struct sdhci_host *host); +bool sdhci_uhs2_mode(struct sdhci_host *host); +void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask); #endif /* __SDHCI_UHS2_H */