From patchwork Mon Oct 17 09:11:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3305 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347204wrs; Mon, 17 Oct 2022 02:16:52 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4C0sXrW/0NAbrS8PvSS5+bXjIKe03tk0YrrGCXrJp4WfE6FwS+hOM29clhgy6KtNZXGB3A X-Received: by 2002:a17:90a:7849:b0:20d:2d54:65d with SMTP id y9-20020a17090a784900b0020d2d54065dmr32245466pjl.219.1665998212543; Mon, 17 Oct 2022 02:16:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998212; cv=none; d=google.com; s=arc-20160816; b=QkqnLz5LXlBw/igPVSDK7VHSiVXXprZqqxPUSP5a8WZXdejKCkEPEiNkt9UOcTXEV6 nSCYiaApstR6PLD35X5nOJ9N/hf9v5G4s2QJTCuOkvjGoCon3OA/6ojxwlGfcWcNMMqX LvUy/4IE4bCgLUe8wMMpmbKYin6Kd1Uv4nhCrBWhZQ/poEFcSJftFpqsrhlM/2EoYbZQ CcbF92HktvxGzuqrDhLNaOj0jpKizYxiMTiYtyyECQcnbzeg1XFBaGB31l6DoLgc7l4Y p2oiPeky2ZENuC3usC2ebl1Zacp30x1Ys1Lv5WUmzzye9EVmNvxLRvzL4HqjEnDCPIk+ i8SA== 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=x0jM/mUgD0JOQwQmZNoiPwNFGZczmcozFW6ZNuUqVKE=; b=U0vtUz8A+GnVAZ941N8JHyU483hFdJ+A/wToB/vPIZTqtdDpmzslUZXtc54/0UBFo0 qZUH50dFViK3TFh5E47lgri2Hcqv0cQPjW54R6kOnU5J2vYkf278RQYtbVuyh/KnCuUP 3chp+5Smt+vvPdOVfDjXzR7BefIWLbQatJNwj5acUxylPeQzGKfAunH1e4Xlvb+CMnld AnkC8S7nUlTgi+A6TwGSlVil20VLmFKaZyJv8KtC0syt9jJxXObcaVb4yJDRdzaGBqJW dxMADH0mc82Xg5AYC4SIvhGwgJAaoysSc8Ro7S7sPKix92JQQXoejlXgXV1sHaI9Z3pL uaYQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=JwccgKqx; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b16-20020a630c10000000b0043ce223c86dsi12643934pgl.843.2022.10.17.02.16.38; Mon, 17 Oct 2022 02:16:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=JwccgKqx; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230442AbiJQJMP (ORCPT + 99 others); Mon, 17 Oct 2022 05:12:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230341AbiJQJMN (ORCPT ); Mon, 17 Oct 2022 05:12:13 -0400 Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 850CE2192; Mon, 17 Oct 2022 02:12:12 -0700 (PDT) Received: by mail-pj1-x102f.google.com with SMTP id d7-20020a17090a2a4700b0020d268b1f02so13652462pjg.1; Mon, 17 Oct 2022 02:12:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=x0jM/mUgD0JOQwQmZNoiPwNFGZczmcozFW6ZNuUqVKE=; b=JwccgKqx/rfzefXegWsoG2Houuy8cuhPSOOz31K/GblqO475U+7oVPzGlK3jtkLaet JNh+lt8/P88f0kBOjIwCcibUroljzY9y/CIq00Q3Hw40wJjknuuh1JLJ3XkwDKzyy+6U tsYqUC2S2EYB+c2CdFdfEqQyjPgwmjQSdvGxEGhPW8SThGyvRzYDS3NPfmhxq8vGpLTn 2xtzyxvVAPJ5JPXcSzjuiFOQJiSNAHkLdl1HL4hCwGD2i9M9PIboqgNKZIZj8wPmsj8D Z3M5c9TxruQWZvrV7+eDam6Bv5dwfD6JpUI9AHprB4N8K6wLwJ5b2X4yWxQGiF9DAhMR /Xpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=x0jM/mUgD0JOQwQmZNoiPwNFGZczmcozFW6ZNuUqVKE=; b=YaQeaHKig6Crcrh04TluJe1GkCpHcLkx6l/0uy+v1GurnujN9vaESRrnJusVQoP0bd Ay986/4fusI4y1Jz5ca11vixAX5GPHCDCAtWS4sjT/wTRd8hukrLEH21EAW1KV/ZoMJX tg7czajGyy8lL7gvyK2+IKtE9i7MGDOuyV1+rnVxErGp6RDdwN3M7WVn1kIY17qdcNl0 TJobZQBR1y+ixK8pRb0d9rrj1qV+atuM4DbS7n4UkaMTg96dvi5rv5sAyPaS27xqQcs7 rX7KRQN8mMoYeqKsKVGNR9b8RBoq7fDyKoUxWRoGHAdPf2fDByDkLw+RBHWeg1cZsqlm q9Ww== X-Gm-Message-State: ACrzQf0oR5YpF8N4lviflpid9nEhIPO1N+R7B36d75PmzNKDPtFLHuCf 8a8x2vOxxvJg0wh9EUhGcH28Rm8pUKg= X-Received: by 2002:a17:902:8b83:b0:17f:5de5:c5ff with SMTP id ay3-20020a1709028b8300b0017f5de5c5ffmr11377668plb.52.1665997932026; Mon, 17 Oct 2022 02:12:12 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:11 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 Subject: [PATCH V5 01/26] mmc: core: Cleanup printing of speed mode at card insertion Date: Mon, 17 Oct 2022 17:11:28 +0800 Message-Id: <20221017091153.454873-2-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925741702178794?= X-GMAIL-MSGID: =?utf-8?q?1746925741702178794?= From: Ulf Hansson The current print of the bus speed mode in mmc_add_card() has grown over the years and is now difficult to parse. Let's clean up the code and also take the opportunity to properly announce "DDR" for eMMCs as "high speed DDR", which is according to the eMMC spec. Signed-off-by: Ulf Hansson --- drivers/mmc/core/bus.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index d8762fa3d5cd..088ec34299c8 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -299,6 +299,7 @@ int mmc_add_card(struct mmc_card *card) { int ret; const char *type; + const char *speed_mode = ""; const char *uhs_bus_speed_mode = ""; static const char *const uhs_speeds[] = { [UHS_SDR12_BUS_SPEED] = "SDR12 ", @@ -337,27 +338,30 @@ int mmc_add_card(struct mmc_card *card) break; } + if (mmc_card_hs(card)) + speed_mode = "high speed "; + else if (mmc_card_uhs(card)) + speed_mode = "ultra high speed "; + else if (mmc_card_ddr52(card)) + speed_mode = "high speed DDR "; + else if (mmc_card_hs200(card)) + speed_mode = "HS200 "; + else if (mmc_card_hs400es(card)) + speed_mode = "HS400 Enhanced strobe "; + else if (mmc_card_hs400(card)) + speed_mode = "HS400 "; + if (mmc_card_uhs(card) && (card->sd_bus_speed < ARRAY_SIZE(uhs_speeds))) uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed]; - if (mmc_host_is_spi(card->host)) { - pr_info("%s: new %s%s%s card on SPI\n", - mmc_hostname(card->host), - mmc_card_hs(card) ? "high speed " : "", - mmc_card_ddr52(card) ? "DDR " : "", - type); - } else { - pr_info("%s: new %s%s%s%s%s%s card at address %04x\n", - mmc_hostname(card->host), - mmc_card_uhs(card) ? "ultra high speed " : - (mmc_card_hs(card) ? "high speed " : ""), - mmc_card_hs400(card) ? "HS400 " : - (mmc_card_hs200(card) ? "HS200 " : ""), - mmc_card_hs400es(card) ? "Enhanced strobe " : "", - mmc_card_ddr52(card) ? "DDR " : "", + if (mmc_host_is_spi(card->host)) + pr_info("%s: new %s%s card on SPI\n", + mmc_hostname(card->host), speed_mode, type); + else + pr_info("%s: new %s%s%s card at address %04x\n", + mmc_hostname(card->host), speed_mode, uhs_bus_speed_mode, type, card->rca); - } #ifdef CONFIG_DEBUG_FS mmc_add_card_debugfs(card); From patchwork Mon Oct 17 09:11:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3299 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1346863wrs; Mon, 17 Oct 2022 02:16:04 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5ws7h1hOxJF+fsPT7j6kmw4xQPvQfoMCqPiAMVzwunBR7sAuBtztU7epG930BLpOECXPTt X-Received: by 2002:a17:902:ccc7:b0:16c:484f:4c69 with SMTP id z7-20020a170902ccc700b0016c484f4c69mr11281135ple.118.1665998164233; Mon, 17 Oct 2022 02:16:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998164; cv=none; d=google.com; s=arc-20160816; b=OrH61IYik2PWKE1ezjd1Pawa7zWd2ZhXUdSuoVQf7tuCM6x/iICeyiYFeL88vbfpGP /4wY5CPhJ5V2elQwwCeM4Xru3kd6y5KIE2nGF6MoufQUFYys/yQpc4eqp0zBC9xwYyDI d3ZiZpk616kGsaB07NBhV4tjqAG8R9BjR65ZJ6U+4ug7kRYQ+E9KP2Y4pbUhZhu5Z8PA zoeg7ATqj9KsZeaLDoR2JgTyewQk9g3qDEUkvM2ePMZdAPTDqFbNi1VZzYiVBvTHVQTX v8jjtF0kpxH4qYtsRlMR49Yc2q1xNCFoTwjy2fTJrrwZBwl2nvsM7VVYAIHsjnaXpLVa /qMA== 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=GyuHmX+yGFzcCIMwz1gj3PIQwrbXu27pkyl3vUgSxFw=; b=veAmySuhxQ+ULyqJgbHKRqkt9qgWNH88hsk93PlHderKuGh66ToYWQZ1UFvk/BiYmj v2UmakLyl/R2tlUEnTLSnUir7orkywiFyUpVhknHMAeV2ZW7erUSEUIKjy6EOwMxbYKD hjpBqe/CxSaqwTolGZOrBqnro2xsv82phdMZVqCrvVD7OjE+0AU1I/Jpt46BUaFPyosQ aT8M/QO7Zg7ByZt+4WKun5xZoAjk2yzsRMTaC4UqZL+P4Ox7kU6+PqyJKfFYQBp0RuGU LMniwlR/eYkA70vELolBOn92cnft9IObQge8YVppeiC0woColZTOGZCcCLKKgdcdw+aK sFlQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=l6XQbaXy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e31-20020a63545f000000b0045c19daabbesi10795918pgm.133.2022.10.17.02.15.51; Mon, 17 Oct 2022 02:16:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=l6XQbaXy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230341AbiJQJMZ (ORCPT + 99 others); Mon, 17 Oct 2022 05:12:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230389AbiJQJMR (ORCPT ); Mon, 17 Oct 2022 05:12:17 -0400 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DEA9021B0; Mon, 17 Oct 2022 02:12:15 -0700 (PDT) Received: by mail-pf1-x433.google.com with SMTP id 3so10520828pfw.4; Mon, 17 Oct 2022 02:12:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=GyuHmX+yGFzcCIMwz1gj3PIQwrbXu27pkyl3vUgSxFw=; b=l6XQbaXyragIBT6bbSWajzlF22sbVF/i+ECL1hsnlUgZNEpkia5ZaYVAtPp7wmDVAB bYKDq+apckZ4kSUCqSLamgiMdt9TVQft2BGFSjFpHi8BzOrYxrRc042Z2N9hIqO7UQtX 3fdYy/EMpTd69DjcWoDEDPI91EI4zowivpbsAzEg3cS7M1661D6aD8g/Pdoo0TfHbbr+ E1EVPNYBQZSDrZJnwf21L0mXFW/nmShZQ+Dv0PKS4wJ99p2CWC9SMzLmx5DrPDFVVSF8 Q+nW/oNt7SUznDw/I/88wsZPPd9cWbeq3OiGCwztRguKxzOPyiu43oUSR/FEFeZb3A1Y rMVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=GyuHmX+yGFzcCIMwz1gj3PIQwrbXu27pkyl3vUgSxFw=; b=Y4vYEoYZ42Wk7k2Kfvjq75P5umeX/IebQlMux1C/nKGiH9oTeQ6Zz4ci7SRqPO5N5C tQkVCXxrrdzXmvlNQn5Hj7IL9x28RhIJgI6zo6qXFHp4on1RJq5GS6xISE5r9OTEXaTM 9OlI7UBQU7tv32eelwyB31W59FsrEJrbmYR+TdwmUCJ41nOY+mfOsvOgi7sKjjYpZd0E rTFw/vALWA9iJBMb2iKsJMk3clri0a8o2x/mPdda1b7YtLOgN+vw5bF6Q6gjIQlwKtdr EPg5YWlLfs/gATjkwdRegQwSxA+zwzW+xLnGxHoF1KnFMfjFdpSMnUsnRk+0VUFU7DGS 8LMw== X-Gm-Message-State: ACrzQf1+vWA6766LfrJ6u93yUsHOSGglfSwFBw9q6iOLkpD00N27zdMj l8KrGbAxQ5zxpvxiti/CPiuzYFHEsII= X-Received: by 2002:a63:c117:0:b0:46b:208e:fd76 with SMTP id w23-20020a63c117000000b0046b208efd76mr10058911pgf.577.1665997935218; Mon, 17 Oct 2022 02:12:15 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:14 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 Subject: [PATCH V5 02/26] mmc: core: Prepare to support SD UHS-II cards Date: Mon, 17 Oct 2022 17:11:29 +0800 Message-Id: <20221017091153.454873-3-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925691074466283?= X-GMAIL-MSGID: =?utf-8?q?1746925691074466283?= From: Ulf Hansson Updates in V4: - Re-based, updated a comment and removed white-space. - Moved MMC_VQMMC2_VOLTAGE_180 into a later patch in the series. Update in previous version: The SD UHS-II interface was introduced to the SD spec v4.00 several years ago. The interface is fundamentally different from an electrical and a protocol point of view, comparing to the legacy SD interface. However, the legacy SD protocol is supported through a specific transport layer (SD-TRAN) defined in the UHS-II addendum of the spec. This allows the SD card to be managed in a very similar way as a legacy SD card, hence a lot of code can be re-used to support these new types of cards through the mmc subsystem. Moreover, an SD card that supports the UHS-II interface shall also be backwards compatible with the legacy SD interface, which allows a UHS-II card to be inserted into a legacy slot. As a matter of fact, this is already supported by mmc subsystem as of today. To prepare to add support for UHS-II, this change puts the basic foundation in the mmc core in place, allowing it to be more easily reviewed before subsequent changes implements the actual support. Basically, the approach here adds a new UHS-II bus_ops type and adds a separate initialization path for the UHS-II card. The intent is to avoid us from sprinkling the legacy initialization path, but also to simplify implementation of the UHS-II specific bits. At this point, there is only one new host ops added to manage the various ios settings needed for UHS-II. Additional host ops that are needed, are being added from subsequent changes. Signed-off-by: Ulf Hansson --- drivers/mmc/core/Makefile | 2 +- drivers/mmc/core/core.c | 17 ++- drivers/mmc/core/core.h | 1 + drivers/mmc/core/sd_uhs2.c | 289 +++++++++++++++++++++++++++++++++++++ include/linux/mmc/card.h | 7 + include/linux/mmc/host.h | 19 +++ 6 files changed, 333 insertions(+), 2 deletions(-) create mode 100644 drivers/mmc/core/sd_uhs2.c diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 6a907736cd7a..15b067e8b0d1 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -7,7 +7,7 @@ obj-$(CONFIG_MMC) += mmc_core.o mmc_core-y := core.o bus.o host.o \ mmc.o mmc_ops.o sd.o sd_ops.o \ sdio.o sdio_ops.o sdio_bus.o \ - sdio_cis.o sdio_io.o sdio_irq.o \ + sdio_cis.o sdio_io.o sdio_irq.o sd_uhs2.o\ slot-gpio.o regulator.o mmc_core-$(CONFIG_OF) += pwrseq.o obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ef53a2578824..ab2a48e1e876 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2234,6 +2234,18 @@ void mmc_rescan(struct work_struct *work) goto out; } + /* + * Ideally we should favor initialization of legacy SD cards and defer + * UHS-II enumeration. However, it seems like cards doesn't reliably + * announce their support for UHS-II in the response to the ACMD41, + * while initializing the legacy SD interface. Therefore, let's start + * with UHS-II for now. + */ + if (!mmc_attach_sd_uhs2(host)) { + mmc_release_host(host); + goto out; + } + for (i = 0; i < ARRAY_SIZE(freqs); i++) { unsigned int freq = freqs[i]; if (freq > host->f_max) { @@ -2261,10 +2273,13 @@ void mmc_rescan(struct work_struct *work) void mmc_start_host(struct mmc_host *host) { + bool power_up = !(host->caps2 & + (MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_SD_UHS2)); + host->f_init = max(min(freqs[0], host->f_max), host->f_min); host->rescan_disable = 0; - if (!(host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)) { + if (power_up) { mmc_claim_host(host); mmc_power_up(host, host->ocr_avail); mmc_release_host(host); diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index f5f3f623ea49..2d80afc95e58 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -81,6 +81,7 @@ int mmc_detect_card_removed(struct mmc_host *host); int mmc_attach_mmc(struct mmc_host *host); int mmc_attach_sd(struct mmc_host *host); int mmc_attach_sdio(struct mmc_host *host); +int mmc_attach_sd_uhs2(struct mmc_host *host); /* Module parameters */ extern bool use_spi_crc; diff --git a/drivers/mmc/core/sd_uhs2.c b/drivers/mmc/core/sd_uhs2.c new file mode 100644 index 000000000000..800957f74632 --- /dev/null +++ b/drivers/mmc/core/sd_uhs2.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021 Linaro Ltd + * + * Author: Ulf Hansson + * + * Support for SD UHS-II cards + */ +#include + +#include +#include + +#include "core.h" +#include "bus.h" +#include "sd.h" +#include "mmc_ops.h" + +static const unsigned int sd_uhs2_freqs[] = { 52000000, 26000000 }; + +static int sd_uhs2_set_ios(struct mmc_host *host) +{ + struct mmc_ios *ios = &host->ios; + + return host->ops->uhs2_set_ios(host, ios); +} + +static int sd_uhs2_power_up(struct mmc_host *host) +{ + host->ios.vdd = fls(host->ocr_avail) - 1; + host->ios.clock = host->f_init; + host->ios.timing = MMC_TIMING_SD_UHS2; + host->ios.power_mode = MMC_POWER_UP; + + return sd_uhs2_set_ios(host); +} + +static void sd_uhs2_power_off(struct mmc_host *host) +{ + host->ios.vdd = 0; + host->ios.clock = 0; + host->ios.timing = MMC_TIMING_LEGACY; + host->ios.power_mode = MMC_POWER_OFF; + + sd_uhs2_set_ios(host); +} + +/* + * Run the phy initialization sequence, which mainly relies on the UHS-II host + * to check that we reach the expected electrical state, between the host and + * the card. + */ +static int sd_uhs2_phy_init(struct mmc_host *host) +{ + return 0; +} + +/* + * Do the early initialization of the card, by sending the device init broadcast + * command and wait for the process to be completed. + */ +static int sd_uhs2_dev_init(struct mmc_host *host) +{ + return 0; +} + +/* + * Run the enumeration process by sending the enumerate command to the card. + * Note that, we currently support only the point to point connection, which + * means only one card can be attached per host/slot. + */ +static int sd_uhs2_enum(struct mmc_host *host, u32 *node_id) +{ + return 0; +} + +/* + * Read the UHS-II configuration registers (CFG_REG) of the card, by sending it + * commands and by parsing the responses. Store a copy of the relevant data in + * card->uhs2_config. + */ +static int sd_uhs2_config_read(struct mmc_host *host, struct mmc_card *card) +{ + return 0; +} + +/* + * Based on the card's and host's UHS-II capabilities, let's update the + * configuration of the card and the host. This may also include to move to a + * greater speed range/mode. Depending on the updated configuration, we may need + * to do a soft reset of the card via sending it a GO_DORMANT_STATE command. + * + * In the final step, let's check if the card signals "config completion", which + * indicates that the card has moved from config state into active state. + */ +static int sd_uhs2_config_write(struct mmc_host *host, struct mmc_card *card) +{ + return 0; +} + +/* + * Initialize the UHS-II card through the SD-TRAN transport layer. This enables + * commands/requests to be backwards compatible through the legacy SD protocol. + * UHS-II cards has a specific power limit specified for VDD1/VDD2, that should + * be set through a legacy CMD6. Note that, the power limit that becomes set, + * survives a soft reset through the GO_DORMANT_STATE command. + */ +static int sd_uhs2_legacy_init(struct mmc_host *host, struct mmc_card *card) +{ + return 0; +} + +/* + * Allocate the data structure for the mmc_card and run the UHS-II specific + * initialization sequence. + */ +static int sd_uhs2_init_card(struct mmc_host *host) +{ + struct mmc_card *card; + u32 node_id; + int err; + + err = sd_uhs2_dev_init(host); + if (err) + return err; + + err = sd_uhs2_enum(host, &node_id); + if (err) + return err; + + card = mmc_alloc_card(host, &sd_type); + if (IS_ERR(card)) + return PTR_ERR(card); + + card->uhs2_config.node_id = node_id; + card->type = MMC_TYPE_SD; + + err = sd_uhs2_config_read(host, card); + if (err) + goto err; + + err = sd_uhs2_config_write(host, card); + if (err) + goto err; + + err = sd_uhs2_legacy_init(host, card); + if (err) + goto err; + + host->card = card; + return 0; + +err: + mmc_remove_card(card); + return err; +} + +static void sd_uhs2_remove(struct mmc_host *host) +{ + mmc_remove_card(host->card); + host->card = NULL; +} + +static int sd_uhs2_alive(struct mmc_host *host) +{ + return mmc_send_status(host->card, NULL); +} + +static void sd_uhs2_detect(struct mmc_host *host) +{ + int err; + + mmc_get_card(host->card, NULL); + err = _mmc_detect_card_removed(host); + mmc_put_card(host->card, NULL); + + if (err) { + sd_uhs2_remove(host); + + mmc_claim_host(host); + mmc_detach_bus(host); + sd_uhs2_power_off(host); + mmc_release_host(host); + } +} + +static int sd_uhs2_suspend(struct mmc_host *host) +{ + return 0; +} + +static int sd_uhs2_resume(struct mmc_host *host) +{ + return 0; +} + +static int sd_uhs2_runtime_suspend(struct mmc_host *host) +{ + return 0; +} + +static int sd_uhs2_runtime_resume(struct mmc_host *host) +{ + return 0; +} + +static int sd_uhs2_shutdown(struct mmc_host *host) +{ + return 0; +} + +static int sd_uhs2_hw_reset(struct mmc_host *host) +{ + return 0; +} + +static const struct mmc_bus_ops sd_uhs2_ops = { + .remove = sd_uhs2_remove, + .alive = sd_uhs2_alive, + .detect = sd_uhs2_detect, + .suspend = sd_uhs2_suspend, + .resume = sd_uhs2_resume, + .runtime_suspend = sd_uhs2_runtime_suspend, + .runtime_resume = sd_uhs2_runtime_resume, + .shutdown = sd_uhs2_shutdown, + .hw_reset = sd_uhs2_hw_reset, +}; + +static int sd_uhs2_attach(struct mmc_host *host) +{ + int err; + + err = sd_uhs2_power_up(host); + if (err) + goto err; + + err = sd_uhs2_phy_init(host); + if (err) + goto err; + + err = sd_uhs2_init_card(host); + if (err) + goto err; + + mmc_attach_bus(host, &sd_uhs2_ops); + + mmc_release_host(host); + + err = mmc_add_card(host->card); + if (err) + goto remove_card; + + mmc_claim_host(host); + return 0; + +remove_card: + mmc_remove_card(host->card); + host->card = NULL; + mmc_claim_host(host); + mmc_detach_bus(host); +err: + sd_uhs2_power_off(host); + return err; +} + +int mmc_attach_sd_uhs2(struct mmc_host *host) +{ + int i, err = 0; + + if (!(host->caps2 & MMC_CAP2_SD_UHS2)) + return -EOPNOTSUPP; + + /* Turn off the legacy SD interface before trying with UHS-II. */ + mmc_power_off(host); + + /* + * Start UHS-II initialization at 52MHz and possibly make a retry at + * 26MHz according to the spec. It's required that the host driver + * validates ios->clock, to set a rate within the correct range. + */ + for (i = 0; i < ARRAY_SIZE(sd_uhs2_freqs); i++) { + host->f_init = sd_uhs2_freqs[i]; + err = sd_uhs2_attach(host); + if (!err) + break; + } + + return err; +} diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 8a30de08e913..7f6672000a48 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -211,6 +211,11 @@ struct sd_ext_reg { #define SD_EXT_PERF_CMD_QUEUE (1<<4) }; +struct sd_uhs2_config { + u32 node_id; + /* TODO: Extend with more register configs. */ +}; + struct sdio_cccr { unsigned int sdio_vsn; unsigned int sd_vsn; @@ -316,6 +321,8 @@ struct mmc_card { struct sd_ext_reg ext_power; /* SD extension reg for PM */ struct sd_ext_reg ext_perf; /* SD extension reg for PERF */ + struct sd_uhs2_config uhs2_config; /* SD UHS-II config */ + unsigned int sdio_funcs; /* number of SDIO functions */ atomic_t sdio_funcs_probed; /* number of probed SDIO funcs */ struct sdio_cccr cccr; /* common card info */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index eb8bc5b9b0b7..0b4122b26352 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -63,6 +63,7 @@ struct mmc_ios { #define MMC_TIMING_MMC_HS400 10 #define MMC_TIMING_SD_EXP 11 #define MMC_TIMING_SD_EXP_1_2V 12 +#define MMC_TIMING_SD_UHS2 13 unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ @@ -91,6 +92,10 @@ struct mmc_clk_phase_map { struct mmc_clk_phase phase[MMC_NUM_CLK_PHASES]; }; +struct sd_uhs2_caps { + /* TODO: Add UHS-II capabilities for the host. */ +}; + struct mmc_host; enum mmc_err_stat { @@ -145,6 +150,17 @@ struct mmc_host_ops { */ void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios); + /* + * The uhs2_set_ios callback is mandatory to implement for hosts that + * supports the SD UHS-II interface (MMC_CAP2_SD_UHS2), while the + * callback is unused for the other cases. Note that, the struct + * mmc_ios is being re-used for this as well. + * + * Expected return values for the uhs2_set_ios callback are a negative + * errno in case of a failure or zero for success. + */ + int (*uhs2_set_ios)(struct mmc_host *host, struct mmc_ios *ios); + /* * Return values for the get_ro callback should be: * 0 for a read/write card @@ -396,6 +412,7 @@ struct mmc_host { MMC_CAP2_HS200_1_2V_SDR) #define MMC_CAP2_SD_EXP (1 << 7) /* SD express via PCIe */ #define MMC_CAP2_SD_EXP_1_2V (1 << 8) /* SD express 1.2V */ +#define MMC_CAP2_SD_UHS2 (1 << 9) /* SD UHS-II support */ #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ @@ -422,6 +439,8 @@ struct mmc_host { #endif #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28) /* Host with eMMC that has GPT entry at a non-standard location */ + struct sd_uhs2_caps uhs2_caps; /* Host UHS-II capabilities */ + int fixed_drv_type; /* fixed driver type for non-removable media */ mmc_pm_flag_t pm_caps; /* supported pm features */ From patchwork Mon Oct 17 09:11:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3301 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1346947wrs; Mon, 17 Oct 2022 02:16:16 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6awVAvb2wA7ASSjJ6d+PccOQOPJQwcMre2Li2UTBcX2YoURVyMtreUleG9BfQD7Czd7lL2 X-Received: by 2002:a17:90a:72c4:b0:20d:51af:3fc4 with SMTP id l4-20020a17090a72c400b0020d51af3fc4mr32499572pjk.38.1665998175773; Mon, 17 Oct 2022 02:16:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998175; cv=none; d=google.com; s=arc-20160816; b=tGMVGTLuX4Iofxbq2IQFGuNNJW8qqW+exOkTf0vdsQvDRHDsZyteNOqvG25ByW75Kq 5MaF4Om8V+xIMOoXr2pagNJ8goawgLI0pvhUro/u05TeZjtPDNxBj06Shw5P/K9iagej fQSnOfy3Ak+QTCOaqjHmaJZgVS5z7l6oRlvoHf63NUgc5GVjNS2RqOjRKLw9lRIq2G7N z9Ysu1Q9FbgUOskS1fyNpfd2VyHzeDddpp8dfRQlaTH1tvHnZ4BsiX9YINlGyR+Gtgl1 XEKnHyAC5lRA6YxNG+qrAHulJfkRq6Cn1nnJ9zmHoPecdZNhIyYEiCK/xIWhpNIRbwfw +dvQ== 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=EgpjV9k83EmC3yQ4DvMrLoo12ich9kue84KtDrunu4g=; b=AsMhUXWJaoqxisSy0naqc4U4rmp2FA+FVSUSqp14nLgGAVVsX0OuRe4FIlH4mgvld2 vA10jZxQc30a4jr7XFfejsXCO5DqEpjSK5LkuwyjJMKai6SblsFp5aN1EFa92W8PPVG8 dCpx/KbDXwJQPVFoXv0VfMQAtLydSCzDn1VEBd8cRCQujdLgxc4xaDrQHKTaqqJHoswA iiEoyHS2420yUlui6iyBiLIGUymu3h357QRx88EzVvjRUEklg9jkEoOerYcCBVotEj3Y nZPOvIcGlIKfzs1ncGkUt5RPRWPn06jvI7MDok02FzhMzMyzXo4GRPAYjM3JuP2vk3+J 37Yg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=avhubzSX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c19-20020a056a00249300b00541174678fcsi11630778pfv.4.2022.10.17.02.16.03; Mon, 17 Oct 2022 02:16:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=avhubzSX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231126AbiJQJMd (ORCPT + 99 others); Mon, 17 Oct 2022 05:12:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230505AbiJQJMX (ORCPT ); Mon, 17 Oct 2022 05:12:23 -0400 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B65E320F46; Mon, 17 Oct 2022 02:12:19 -0700 (PDT) Received: by mail-pf1-x430.google.com with SMTP id d10so10520731pfh.6; Mon, 17 Oct 2022 02:12:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=EgpjV9k83EmC3yQ4DvMrLoo12ich9kue84KtDrunu4g=; b=avhubzSXytLQG4oLf2aQK8NeqCg/pRWd4hV68c0UYH0QumxgNhCx18nDeGQkJX4c67 H7vhUwuuIUz0pj8qRItSnbqq9CPjDH8+xQJNUul0dW662nA43GWbQJFZVk2DqE0mvELh 598ATlUep4wOB74EhNfYjqA4IkObs+PNbdHt4Xvs9z9iB6c18GavkzEjNWa2JXTg3E7e DD0hOKxvDvyWso+r5jLzVVSvR7qVmeZJ88QXqn3zumFf/lF4r0RBGnvF6yLtcgICt/D2 +95FE9sjJ0xYUnFQHB2B6PQLBJKEAZr0cvE3UWnbxlEIeT5bhN/kyxIGQ9ldUaJ2Aech mGgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=EgpjV9k83EmC3yQ4DvMrLoo12ich9kue84KtDrunu4g=; b=njoZ1AV6WrGZO3SNal7jtp73jXP0pcHSqB/fLXfo3ECwW5gonHYnbzF0t/kTWTVj8V izSt8+9AnXVvd7CoSvhPU/y1IT25yHLgfyIZE/3lAp7aWzwBpUObVKAX8jkLmtQ7AMj9 XYCHaSDsQpZ29uHFOnbQ7/bNZKGZFvLULpKg3irGefbnl9iUTJpb0Kef9SsgE9h06X19 G259vbHsxlTuqXOdu9Af7bjAq+IHKyOQ3jysibSApSgJOBj9x1XaYESuSm4bX9BgvMTd edLJ1H5vw+T09F09yi+/Hjs3uu3Ha7lowoJT4AVOtQ0qhDS6x7nZIf54Mq1tJQ+eLnxP N6cg== X-Gm-Message-State: ACrzQf3ljpeblOK2YeUK/8RHytWZCWPC0EJBJ+vlrvpnqPk33AV0knWq x1saJ+9qtS8eReVk3Za/bJ6hmkNkBUc= X-Received: by 2002:a63:1112:0:b0:43c:7998:ac15 with SMTP id g18-20020a631112000000b0043c7998ac15mr10261548pgl.51.1665997938722; Mon, 17 Oct 2022 02:12:18 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:18 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 Subject: [PATCH V5 03/26] mmc: core: Announce successful insertion of an SD UHS-II card Date: Mon, 17 Oct 2022 17:11:30 +0800 Message-Id: <20221017091153.454873-4-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925703583013472?= X-GMAIL-MSGID: =?utf-8?q?1746925703583013472?= From: Ulf Hansson Updates in V4: - Make mmc_card_uhs2() take struct mmc_host* as in-param. Update in previous version: To inform the users about SD UHS-II cards, let's extend the print at card insertion with a "UHS-II" substring. Within this change, it seems reasonable to convert from using "ultra high speed" into "UHS-I speed", for the UHS-I type, as it should makes it more clear. Note that, the new print for UHS-II cards doesn't include the actual selected speed mode. Instead, this is going to be added from subsequent change. Signed-off-by: Ulf Hansson --- drivers/mmc/core/bus.c | 4 +++- drivers/mmc/core/host.h | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 088ec34299c8..dcfbd014a871 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -341,7 +341,9 @@ int mmc_add_card(struct mmc_card *card) if (mmc_card_hs(card)) speed_mode = "high speed "; else if (mmc_card_uhs(card)) - speed_mode = "ultra high speed "; + speed_mode = "UHS-I speed "; + else if (mmc_card_uhs2(card->host)) + speed_mode = "UHS-II speed "; else if (mmc_card_ddr52(card)) speed_mode = "high speed DDR "; else if (mmc_card_hs200(card)) diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index 48c4952512a5..ba6a80e9b360 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -89,5 +89,9 @@ static inline bool mmc_card_sd_express(struct mmc_host *host) host->ios.timing == MMC_TIMING_SD_EXP_1_2V; } +static inline bool mmc_card_uhs2(struct mmc_host *host) +{ + return host->ios.timing == MMC_TIMING_SD_UHS2; +} #endif From patchwork Mon Oct 17 09:11:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3300 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1346917wrs; Mon, 17 Oct 2022 02:16:12 -0700 (PDT) X-Google-Smtp-Source: AMsMyM68yQB2fd8PCaYWOqAPf3bUD+WY9I1DqCfIrj+8MpJ5mjU5YeTeMg1wR/Cn3rcMVraR2Phw X-Received: by 2002:a17:90a:4607:b0:202:d8b7:2c1b with SMTP id w7-20020a17090a460700b00202d8b72c1bmr12650933pjg.64.1665998172489; Mon, 17 Oct 2022 02:16:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998172; cv=none; d=google.com; s=arc-20160816; b=AeQ54kavU3N0ZezK3PtMgaH/bCW0ulEGkoKKwLiyhrjcD8EQrSERd1KyP3EDdlpoXD R0K1imVOmq56LeMl1BSAKBAq1bgpYB5ECxKZvrFfi1e60b9pLv7q3IIFaoRsz5IYfZev NsQAKsdzoQdcW9H40hM3J3HvA21auLDeqGzloInIEjdKUKXvMdD814LmgoUyo/LSdtaI EhG3+AaTlBQvcWLfZDanFBx0Le06P0VIsJ02i7I6ISTB+yhKBtqqx34FPmz1Nfpq1V7O i8fk6V3//jT7wI2aN1Uf6Pq04ApnYRJ+feGoFaU67MH10fxkoXdf7fs/b50kw5++XyUq Hk9Q== 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=CCH8Igg1orUCvBJ3wNzvtOpE3BVsidt9yGsLk/7NTnE=; b=ZOtYIJIwqfnV8SsSKFi96H6n0xGsesGREIOpLNWbOdg1ygBOWBjYQ9FhuSJhsDsCQ3 6QUPDmCbrzkl8CJ3LONJeotLgvDuScqN0+zu5othIT6l9OmqvlLb6ZMFRLJ3qL4HLaLs g4zrsN8Sadf4gT/hAg+eSRyoVP5gJTUJWZ4Rdz33zkH/ssKt7JNdo94sCdiKZwAVqulu vyAxquwi1nz6jsH3dvsjFm1yHHnWDong0AuGw/Y8KhP0drDB0lC2WTqJyw2kxwReLJ3a +CnnqSG5NdQ+80PtdIXcbKjJtLoXSPYbxRU3eae3cskASnBhR1ymLwloXhk49n5xGz3r WbJw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=qKs8qLtj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s1-20020aa78bc1000000b005355298e9c3si10512118pfd.228.2022.10.17.02.15.57; Mon, 17 Oct 2022 02:16:12 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=qKs8qLtj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230527AbiJQJMz (ORCPT + 99 others); Mon, 17 Oct 2022 05:12:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60564 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230520AbiJQJM1 (ORCPT ); Mon, 17 Oct 2022 05:12:27 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18C0F17060; Mon, 17 Oct 2022 02:12:22 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id o17-20020a17090aac1100b0020d98b0c0f4so12261380pjq.4; Mon, 17 Oct 2022 02:12:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=CCH8Igg1orUCvBJ3wNzvtOpE3BVsidt9yGsLk/7NTnE=; b=qKs8qLtjtotgNP9MVQTnrpi278faVxNJT5w8LPgm8GH2aLKvN0QJaAu1N2Mf1TVdJz s4pC8BMg3FT3R+fr4V74khHjDnj+SCu5jBWfCd0h9kMjEesMdJlSfRGYR3+rQ7d9JFlp iSP/kw1PN5OWWlcGKmpTKKPMUv3kM5K52DNTJwt8EuCOhLzOAGzCRbxWZ9amAePzsbIh fVKsP6GKfcZ0tA3jYCQpqtFmminKCnsTmifeQAJALah/WNHHSPVmkVJNeoEcyoT2FxWp LxSZyAYB1Ve+l8ONKa4GnAA3t75pL8EkiXeSKjILL0SdeC5cE99NQi5Z8myl8lS4yIqp dIQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=CCH8Igg1orUCvBJ3wNzvtOpE3BVsidt9yGsLk/7NTnE=; b=iEKOuSeM9B2MN1cBoukpZwtejWrUw928Mg23a3Wh3jkUHOoMuhL0CUYgKjweZivYW8 jM2T+OQCTKCBluE6Xefebd2Z1ghyu35pSUnwygMD5lFwmjbUgavyN7aRxJY6MhLtZgBF 877rGId6vGL9g6KsW9WJ+qKWJIpT2EEQKu2Ul+Fc5w5eidpj4/EZGzP11cHnVgOj25Fe oYo9DZXh+eAQ62SyPjQg8NWF6aFAhY6Xdq8LSaSw6EsqU1+afW6ie7ih2e0KVGXyJMs1 yKzfY6BcWWPYrQ9K2DsS6/yk8CWIZo3xbBGcQw8QuqyQzCf1ot3a/jfdimY0nJ/MZWdW MThg== X-Gm-Message-State: ACrzQf2ElQ+xE+0qnZbpXtYFkQ9id/gY1s+2NAfKZhmHo1XJ2Ywqhv3H laf+aBMG/d8VswbOuc0GHhg= X-Received: by 2002:a17:90b:3ecc:b0:20d:9da6:56cd with SMTP id rm12-20020a17090b3ecc00b0020d9da656cdmr12233695pjb.246.1665997941902; Mon, 17 Oct 2022 02:12:21 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:21 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 Subject: [PATCH V5 04/26] mmc: core: Extend support for mmc regulators with a vqmmc2 Date: Mon, 17 Oct 2022 17:11:31 +0800 Message-Id: <20221017091153.454873-5-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925699850441076?= X-GMAIL-MSGID: =?utf-8?q?1746925699850441076?= From: Ulf Hansson Updates in V4: - Moved the voltage defines into this patch. Update in previous version: To allow an additional external regulator to be controlled by an mmc host driver, let's add support for a vqmmc2 regulator to the mmc core. For an SD UHS-II interface the vqmmc2 regulator may correspond to the so called vdd2 supply, as described by the SD spec. Initially, only 1.8V is needed, hence limit the new helper function, mmc_regulator_set_vqmmc2() to this too. Note that, to allow for flexibility mmc host drivers need to manage the enable/disable of the vqmmc2 regulator themselves, while the regulator is looked up through the common mmc_regulator_get_supply(). Signed-off-by: Ulf Hansson --- drivers/mmc/core/regulator.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/mmc/host.h | 11 +++++++++++ 2 files changed, 45 insertions(+) diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c index 609201a467ef..3c189682797c 100644 --- a/drivers/mmc/core/regulator.c +++ b/drivers/mmc/core/regulator.c @@ -223,6 +223,33 @@ int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios) } EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc); +/** + * mmc_regulator_set_vqmmc2 - Set vqmmc2 as per the ios->vqmmc2_voltage + * @mmc: The mmc host to regulate + * @ios: The io bus settings + * + * Sets a new voltage level for the vqmmc2 regulator, which may correspond to + * the vdd2 regulator for an SD UHS-II interface. This function is expected to + * be called by mmc host drivers. + * + * Returns a negative error code on failure, zero if the voltage level was + * changed successfully or a positive value if the level didn't need to change. + */ +int mmc_regulator_set_vqmmc2(struct mmc_host *mmc, struct mmc_ios *ios) +{ + if (IS_ERR(mmc->supply.vqmmc2)) + return -EINVAL; + + switch (ios->vqmmc2_voltage) { + case MMC_VQMMC2_VOLTAGE_180: + return mmc_regulator_set_voltage_if_supported( + mmc->supply.vqmmc2, 1700000, 1800000, 1950000); + default: + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc2); + #else static inline int mmc_regulator_get_ocrmask(struct regulator *supply) @@ -249,6 +276,7 @@ int mmc_regulator_get_supply(struct mmc_host *mmc) mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc"); mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc"); + mmc->supply.vqmmc2 = devm_regulator_get_optional(dev, "vqmmc2"); if (IS_ERR(mmc->supply.vmmc)) { if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER) @@ -268,6 +296,12 @@ int mmc_regulator_get_supply(struct mmc_host *mmc) dev_dbg(dev, "No vqmmc regulator found\n"); } + if (IS_ERR(mmc->supply.vqmmc2)) { + if (PTR_ERR(mmc->supply.vqmmc2) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_dbg(dev, "No vqmmc2 regulator found\n"); + } + return 0; } EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 0b4122b26352..cc2cd502ae29 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -71,6 +71,9 @@ struct mmc_ios { #define MMC_SIGNAL_VOLTAGE_180 1 #define MMC_SIGNAL_VOLTAGE_120 2 + unsigned char vqmmc2_voltage; +#define MMC_VQMMC2_VOLTAGE_180 0 + unsigned char drv_type; /* driver type (A, B, C, D) */ #define MMC_SET_DRIVER_TYPE_B 0 @@ -321,6 +324,7 @@ struct mmc_pwrseq; struct mmc_supply { struct regulator *vmmc; /* Card power supply */ struct regulator *vqmmc; /* Optional Vccq supply */ + struct regulator *vqmmc2; /* Optional supply for phy */ }; struct mmc_ctx { @@ -600,6 +604,7 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc, struct regulator *supply, unsigned short vdd_bit); int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios); +int mmc_regulator_set_vqmmc2(struct mmc_host *mmc, struct mmc_ios *ios); #else static inline int mmc_regulator_set_ocr(struct mmc_host *mmc, struct regulator *supply, @@ -613,6 +618,12 @@ static inline int mmc_regulator_set_vqmmc(struct mmc_host *mmc, { return -EINVAL; } + +static inline int mmc_regulator_set_vqmmc2(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + return -EINVAL; +} #endif int mmc_regulator_get_supply(struct mmc_host *mmc); From patchwork Mon Oct 17 09:11:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3304 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347094wrs; Mon, 17 Oct 2022 02:16:36 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5T6Foyb6J7rijx3v6D+ci+l1ZZ+WVohS8RHW7Coph+19Mbpn0pkVoSArcxjaEdwPaWMm3t X-Received: by 2002:a63:3155:0:b0:45a:553a:3479 with SMTP id x82-20020a633155000000b0045a553a3479mr9787784pgx.408.1665998196108; Mon, 17 Oct 2022 02:16:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998196; cv=none; d=google.com; s=arc-20160816; b=NxccRbqaTX32XnGUOJ97c92TJeqxE0jFG5wgBWmxEW+F/ToR9JuQL4HqVNcIGU1atP qurlAhJyeLXNtV0GurWt3hQcSvAG2QsabkakB3h9biRZr+Nec+dHCCGBI8zM1uup2xxd doJHh5nqxaxfPBI6r927IYITI5+LlNLny+fUAqzCHBTHUcxyDlHOS3cb+YYVVgV+x7Lt cDxXLVxY9az5PsMVoW+8opLNmAmFwhxmz0SoYpVK6riNX03uyaFG+T33KhGr+13MOQu8 tCycrguMeO1mR3dcgxGTXXCGJZGvrqQoiFdMVZRYfsIrW3XceFXyZqc5O6a6OHtuHI4o b9zA== 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=fvHUHApd8tU9fGSDgUOoDt1aYP0bNWev0jExqMqhQgM=; b=XSWKm0B2UbPN90Y+JeDVOWLpDUWM5vffc7qRPzUct+sqCyyYNN4p9mPeSxbabDtswe 8k+aQK+oaCm+qkQ8b6Zb+K0A1ks9kT3Nz5PXVy0h5lvEKeuy6tZoKkmCH7IkgNBNEQnX 8NTMq+cudpxI2lYj5gy3XyrpNyLQVeuOnMAh2Q3UDKerreWq5Bjed16IegU9RwRUlEJd 4gi5c5AnWFjFjUM7l2WamjIqXHJ2SMER8mpIUUweYf1G0dCwQEjThhMKCUwb7zAX0kzt ob7+NLtZjXnCQHNYIVTgtZ4GMTKAhTgFrxVGLpjr9jOwmeYu0U1JGRVC4QZwLTxOqz/J tXDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=gUINa1jA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o131-20020a62cd89000000b00565fc1c01c4si11692116pfg.311.2022.10.17.02.16.22; Mon, 17 Oct 2022 02:16:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=gUINa1jA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229769AbiJQJNA (ORCPT + 99 others); Mon, 17 Oct 2022 05:13:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231152AbiJQJMy (ORCPT ); Mon, 17 Oct 2022 05:12:54 -0400 Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61144220C8; Mon, 17 Oct 2022 02:12:26 -0700 (PDT) Received: by mail-pj1-x102f.google.com with SMTP id x31-20020a17090a38a200b0020d2afec803so10402910pjb.2; Mon, 17 Oct 2022 02:12:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=fvHUHApd8tU9fGSDgUOoDt1aYP0bNWev0jExqMqhQgM=; b=gUINa1jARNt2x1guWrxu7Xx7bhzkm3M1/MTaqxpP2QH4PhHHHNKSp1+R35Zie1f1Ie wvu6MWmow/PivymL1Us0gFHutvMQRQviMUCctDFPTdteRh3FXcN1/Oj25L161aXwY/xV +i1b2aenZBRFflJ4vSPNmbnaFSXw8/3ExZtdfc6dhTAlu5GQ4fU1ZkftbKhrHIYY/Mxn hr0j7/K5KOhMjbRtgp7RuVrRuJS07Jg4rpXR+u6bbJ7n/RlPOm/e2Z1wjtEi9fjLZByp /fEZyxKVup+l1l8jGjFeQfHce5AgiMeMc33aoryvBJq4y0Y30o+o3LRSZCINHV9Ed/tQ oRcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=fvHUHApd8tU9fGSDgUOoDt1aYP0bNWev0jExqMqhQgM=; b=xzp42O1wP5eSebhZb5Po4JJSFMv0l5ih1hAhSD1R9JEVNPErzNa2+/4ePhCkMAjGFv vX+kJ6fKf9tPeGPqtyOuLjmX0wpm6MXPGyZ/Fmsb5zmdaIjywQplUSNusk+xvbics/Ha DrU0Z/S5dfXvFsLod31N91EM802ETCfsjxn5DGe2U4+L7Gv6gOfCuk35EK05GdL2Kx1O XOhmnp0reeKvvOF44BnWR/U7fCvhVYN2XjS+Ono3vH0T2S98tSua9w0rPygD+kUX7t35 x0CEr5pLdmpfegVSL9GYwCk0HmYSWcPPT3/rNQ1kUGtuUDinWdcvXa/sOaOH1q0/3VNt i/bg== X-Gm-Message-State: ACrzQf1SKKoraS+GahwsKpba43LBg9JyjNgwc4CC3iqgAsK7QKDun71R FsJkOIxxq1ZfdxsyfHC8opsYqHafJWo= X-Received: by 2002:a17:90b:388e:b0:20d:4a1f:d5ae with SMTP id mu14-20020a17090b388e00b0020d4a1fd5aemr32785714pjb.51.1665997945876; Mon, 17 Oct 2022 02:12:25 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:25 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Jason Lai Subject: [PATCH V5 05/26] mmc: core: Add definitions for SD UHS-II cards Date: Mon, 17 Oct 2022 17:11:32 +0800 Message-Id: <20221017091153.454873-6-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925724113642015?= X-GMAIL-MSGID: =?utf-8?q?1746925724113642015?= Updates in V5: - Added UHS2 interfaces in mmc_host_ops: host.h - Added UHS2 VDD2 power supply in mmc_supply: host.h - Added UHS2-specific OCR and UHS2 VDD2 max current in mmc_host: host.h - Added definition of UHS2 VDD2 1.65v-1.95v in mmc_host: host.h - Added flags/MMC_UHS2_SUPPORT/MMC_UHS2_2L_HD in mmc_host: host.h Add UHS-II specific data structures for commands and defines for registers, as described in Part 1 UHS-II Addendum Version 1.01. UHS-II related definitions are listed below: 1. UHS-II card capability: sd_uhs2_caps{} 2. UHS-II configuration: sd_uhs2_config{} 3. UHS-II Command structure: uhs2_command{} 4. UHS-II register I/O address and register field definitions: sd_uhs2.h Signed-off-by: Ulf Hansson Signed-off-by: Jason Lai Signed-off-by: Victor Shih --- include/linux/mmc/card.h | 42 +++++- include/linux/mmc/core.h | 13 ++ include/linux/mmc/host.h | 70 +++++++++- include/linux/mmc/sd_uhs2.h | 263 ++++++++++++++++++++++++++++++++++++ 4 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 include/linux/mmc/sd_uhs2.h diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 7f6672000a48..9cc9b1d046f1 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -190,6 +190,13 @@ struct sd_switch_caps { #define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400) #define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600) #define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800) + unsigned int sd4_curr_limit; +#define SD4_SET_POWER_LIMIT_0_72W 0 +#define SD4_SET_POWER_LIMIT_1_44W 1 +#define SD4_SET_POWER_LIMIT_2_16W 2 +#define SD4_SET_POWER_LIMIT_2_88W 3 +#define SD4_SET_POWER_LIMIT_1_80W 4 +#define SD4_SET_POWER_NO_CHANGE (-1) }; struct sd_ext_reg { @@ -213,7 +220,35 @@ struct sd_ext_reg { struct sd_uhs2_config { u32 node_id; - /* TODO: Extend with more register configs. */ + + u32 dap; + u32 gap; + u32 n_fcu; + u32 maxblk_len; + u8 n_lanes; + u8 dadr_len; + u8 app_type; + u8 phy_minor_rev; + u8 phy_major_rev; + u8 can_hibernate; + u8 n_lss_sync; + u8 n_lss_dir; + u8 link_minor_rev; + u8 link_major_rev; + u8 dev_type; + u8 n_data_gap; + + u32 n_fcu_set; + u32 maxblk_len_set; + u8 n_lanes_set; + u8 speed_range_set; + u8 n_lss_sync_set; + u8 n_lss_dir_set; + u8 n_data_gap_set; + u8 pwrctrl_mode_set; + u8 max_retry_set; + + u8 cfg_complete; }; struct sdio_cccr { @@ -322,6 +357,9 @@ struct mmc_card { struct sd_ext_reg ext_perf; /* SD extension reg for PERF */ struct sd_uhs2_config uhs2_config; /* SD UHS-II config */ + u8 uhs2_state; /* SD UHS-II states */ +#define MMC_UHS2_INITIALIZED BIT(1) +#define MMC_UHS2_SPEED_B BIT(2) unsigned int sdio_funcs; /* number of SDIO functions */ atomic_t sdio_funcs_probed; /* number of probed SDIO funcs */ @@ -363,4 +401,6 @@ bool mmc_card_is_blockaddr(struct mmc_card *card); #define mmc_card_sdio(c) ((c)->type == MMC_TYPE_SDIO) #define mmc_card_sd_combo(c) ((c)->type == MMC_TYPE_SD_COMBO) +#define mmc_card_can_poweroff_notify(c) ((c)->ext_power.feature_support & SD_EXT_POWER_OFF_NOTIFY) + #endif /* LINUX_MMC_CARD_H */ diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 6efec0b9820c..2a0581d87706 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -23,6 +23,14 @@ enum mmc_blk_status { MMC_BLK_NEW_REQUEST, }; +struct uhs2_command { + u16 header; + u16 arg; + __be32 *payload; + u32 payload_len; + u32 packet_len; +}; + struct mmc_command { u32 opcode; u32 arg; @@ -109,6 +117,11 @@ struct mmc_command { unsigned int busy_timeout; /* busy detect timeout in ms */ struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ + + struct uhs2_command *uhs2_cmd; /* UHS2 command */ + u8 *uhs2_resp; /* UHS2 native cmd resp */ + u8 uhs2_resp_len; /* UHS2 native cmd resp len */ + u8 uhs2_tmode0_flag; /* UHS2 transfer mode flag */ }; struct mmc_data { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index cc2cd502ae29..cf5adf26b6e4 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -16,6 +16,7 @@ #include #include #include +#include struct mmc_ios { unsigned int clock; /* clock rate */ @@ -96,7 +97,48 @@ struct mmc_clk_phase_map { }; struct sd_uhs2_caps { - /* TODO: Add UHS-II capabilities for the host. */ + u32 dap; + u32 gap; + u32 group_desc; + u32 maxblk_len; + u32 n_fcu; + u8 n_lanes; + u8 addr64; + u8 card_type; + u8 phy_rev; + u8 speed_range; + u8 can_hibernate; + u8 n_lss_sync; + u8 n_lss_dir; + u8 link_rev; + u8 host_type; + u8 n_data_gap; + + u32 maxblk_len_set; + u32 n_fcu_set; + u8 n_lanes_set; + u8 n_lss_sync_set; + u8 n_lss_dir_set; + u8 n_data_gap_set; + u8 max_retry_set; +}; + +struct sd_uhs2_ios { + bool is_2L_HD_mode; + bool is_APP_CMD; + unsigned int power_delay_ms; /* waiting for stable power */ +}; + +enum sd_uhs2_operation { + UHS2_PHY_INIT = 0, + UHS2_SET_CONFIG, + UHS2_ENABLE_INT, + UHS2_DISABLE_INT, + UHS2_ENABLE_CLK, + UHS2_DISABLE_CLK, + UHS2_CHECK_DORMANT, + UHS2_SET_SPEED_B, + UHS2_POST_ATTACH_SD, }; struct mmc_host; @@ -231,6 +273,20 @@ struct mmc_host_ops { /* Initialize an SD express card, mandatory for MMC_CAP2_SD_EXP. */ int (*init_sd_express)(struct mmc_host *host, struct mmc_ios *ios); + + /* UHS2 interfaces */ + int (*uhs2_detect_init)(struct mmc_host *host); + int (*uhs2_set_reg)(struct mmc_host *host, enum sd_uhs2_operation act); + int (*uhs2_disable_clk)(struct mmc_host *host); + int (*uhs2_enable_clk)(struct mmc_host *host); + + /* + * The uhs2_control callback is used to execute SD UHS-II specific + * operations. It's mandatory to implement for hosts that supports the + * SD UHS-II interface (MMC_CAP2_SD_UHS2). Expected return values are a + * negative errno in case of a failure or zero for success. + */ + int (*uhs2_control)(struct mmc_host *host, enum sd_uhs2_operation op); }; struct mmc_cqe_ops { @@ -323,6 +379,7 @@ struct mmc_pwrseq; struct mmc_supply { struct regulator *vmmc; /* Card power supply */ + struct regulator *vmmc2; /* UHS2 VDD2 power supply */ struct regulator *vqmmc; /* Optional Vccq supply */ struct regulator *vqmmc2; /* Optional supply for phy */ }; @@ -344,10 +401,12 @@ struct mmc_host { u32 ocr_avail_sdio; /* SDIO-specific OCR */ u32 ocr_avail_sd; /* SD-specific OCR */ u32 ocr_avail_mmc; /* MMC-specific OCR */ + u32 ocr_avail_uhs2; /* UHS2-specific OCR */ struct wakeup_source *ws; /* Enable consume of uevents */ u32 max_current_330; u32 max_current_300; u32 max_current_180; + u32 max_current_180_vdd2; /* UHS2 vdd2 max curt. */ #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ @@ -366,6 +425,7 @@ struct mmc_host { #define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ #define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ #define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ +#define MMC_VDD2_165_195 0x00000080 /* UHS2 VDD2 1.65 ~ 1.95 */ u32 caps; /* Host capabilities */ @@ -443,7 +503,12 @@ struct mmc_host { #endif #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28) /* Host with eMMC that has GPT entry at a non-standard location */ + int flags; +#define MMC_UHS2_SUPPORT (1 << 0) +#define MMC_UHS2_2L_HD (1 << 2) + struct sd_uhs2_caps uhs2_caps; /* Host UHS-II capabilities */ + struct sd_uhs2_ios uhs2_ios; /* Host UHS-II capabilities */ int fixed_drv_type; /* fixed driver type for non-removable media */ @@ -695,4 +760,7 @@ int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); int mmc_send_abort_tuning(struct mmc_host *host, u32 opcode); int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); +#define mmc_uhs2_2L_HD_mode(h) ((h)->uhs2_ios.is_2L_HD_mode) +#define mmc_uhs2_APP_cmd(h) ((h)->uhs2_ios.is_APP_CMD) + #endif /* LINUX_MMC_HOST_H */ diff --git a/include/linux/mmc/sd_uhs2.h b/include/linux/mmc/sd_uhs2.h new file mode 100644 index 000000000000..8fcf702cf4a5 --- /dev/null +++ b/include/linux/mmc/sd_uhs2.h @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Header file for UHS-II packets, Host Controller registers and I/O + * accessors. + * + * Copyright (C) 2014 Intel Corp, All Rights Reserved. + */ +#ifndef LINUX_MMC_UHS2_H +#define LINUX_MMC_UHS2_H + +/* LINK Layer definition */ +/* + * UHS2 Header: + * Refer to UHS-II Addendum Version 1.02 Figure 5-2, the format of CCMD Header is described below: + * bit [3:0] : DID(Destination ID = Node ID of UHS2 card) + * bit [6:4] : TYP(Packet Type) + * 000b: CCMD(Control command packet) + * 001b: DCMD(Data command packet) + * 010b: RES(Response packet) + * 011b: DATA(Data payload packet) + * 111b: MSG(Message packet) + * Others: Reserved + * bit [7] : NP(Native Packet) + * bit [10:8] : TID(Transaction ID) + * bit [11] : Reserved + * bit [15:12]: SID(Source ID 0: Node ID of Host) + * + * Broadcast CCMD issued by Host is represented as DID=SID=0. + */ +/* + * UHS2 Argument: + * Refer to UHS-II Addendum Version 1.02 Figure 6-5, the format of CCMD Argument is described below: + * bit [3:0] : MSB of IOADR + * bit [5:4] : PLEN(Payload Length) + * 00b: 0 byte + * 01b: 4 bytes + * 10b: 8 bytes + * 11b: 16 bytes + * bit [6] : Reserved + * bit [7] : R/W(Read/Write) + * 0: Control read command + * 1: Control write command + * bit [15:8] : LSB of IOADR + * + * I/O Address specifies the address of register in UHS-II I/O space accessed by CCMD. + * The unit of I/O Address is 4 Bytes. It is transmitted in MSB first, LSB last. + */ +#define UHS2_NATIVE_PACKET_POS 7 +#define UHS2_NATIVE_PACKET (1 << UHS2_NATIVE_PACKET_POS) + +#define UHS2_PACKET_TYPE_POS 4 +#define UHS2_PACKET_TYPE_CCMD (0 << UHS2_PACKET_TYPE_POS) +#define UHS2_PACKET_TYPE_DCMD (1 << UHS2_PACKET_TYPE_POS) +#define UHS2_PACKET_TYPE_RES (2 << UHS2_PACKET_TYPE_POS) +#define UHS2_PACKET_TYPE_DATA (3 << UHS2_PACKET_TYPE_POS) +#define UHS2_PACKET_TYPE_MSG (7 << UHS2_PACKET_TYPE_POS) + +#define UHS2_DEST_ID_MASK 0x0F +#define UHS2_DEST_ID 0x1 + +#define UHS2_SRC_ID_POS 12 +#define UHS2_SRC_ID_MASK 0xF000 + +#define UHS2_TRANS_ID_POS 8 +#define UHS2_TRANS_ID_MASK 0x0700 + +/* UHS2 MSG */ +#define UHS2_MSG_CTG_POS 5 +#define UHS2_MSG_CTG_LMSG 0x00 +#define UHS2_MSG_CTG_INT 0x60 +#define UHS2_MSG_CTG_AMSG 0x80 + +#define UHS2_MSG_CTG_FCREQ 0x00 +#define UHS2_MSG_CTG_FCRDY 0x01 +#define UHS2_MSG_CTG_STAT 0x02 + +#define UHS2_MSG_CODE_POS 8 +#define UHS2_MSG_CODE_FC_UNRECOVER_ERR 0x8 +#define UHS2_MSG_CODE_STAT_UNRECOVER_ERR 0x8 +#define UHS2_MSG_CODE_STAT_RECOVER_ERR 0x1 + +/* TRANS Layer definition */ + +/* Native packets*/ +#define UHS2_NATIVE_CMD_RW_POS 7 +#define UHS2_NATIVE_CMD_WRITE (1 << UHS2_NATIVE_CMD_RW_POS) +#define UHS2_NATIVE_CMD_READ (0 << UHS2_NATIVE_CMD_RW_POS) + +#define UHS2_NATIVE_CMD_PLEN_POS 4 +#define UHS2_NATIVE_CMD_PLEN_4B (1 << UHS2_NATIVE_CMD_PLEN_POS) +#define UHS2_NATIVE_CMD_PLEN_8B (2 << UHS2_NATIVE_CMD_PLEN_POS) +#define UHS2_NATIVE_CMD_PLEN_16B (3 << UHS2_NATIVE_CMD_PLEN_POS) + +#define UHS2_NATIVE_CCMD_GET_MIOADR_MASK 0xF00 +#define UHS2_NATIVE_CCMD_MIOADR_MASK 0x0F + +#define UHS2_NATIVE_CCMD_LIOADR_POS 8 +#define UHS2_NATIVE_CCMD_GET_LIOADR_MASK 0x0FF + +#define UHS2_CCMD_DEV_INIT_COMPLETE_FLAG BIT(11) +#define UHS2_DEV_INIT_PAYLOAD_LEN 1 +#define UHS2_DEV_INIT_RESP_LEN 6 +#define UHS2_DEV_ENUM_PAYLOAD_LEN 1 +#define UHS2_DEV_ENUM_RESP_LEN 8 +#define UHS2_CFG_WRITE_PAYLOAD_LEN 2 +#define UHS2_CFG_WRITE_PHY_SET_RESP_LEN 4 +#define UHS2_CFG_WRITE_GENERIC_SET_RESP_LEN 5 +#define UHS2_GO_DORMANT_PAYLOAD_LEN 1 + +/* + * UHS2 Argument: + * Refer to UHS-II Addendum Version 1.02 Figure 6-8, the format of DCMD Argument is described below: + * bit [3:0] : Reserved + * bit [6:3] : TMODE(Transfer Mode) + * bit 3: DAM(Data Access Mode) + * bit 4: TLUM(TLEN Unit Mode) + * bit 5: LM(Length Mode) + * bit 6: DM(Duplex Mode) + * bit [7] : R/W(Read/Write) + * 0: Control read command + * 1: Control write command + * bit [15:8] : Reserved + * + * I/O Address specifies the address of register in UHS-II I/O space accessed by CCMD. + * The unit of I/O Address is 4 Bytes. It is transmitted in MSB first, LSB last. + */ +#define UHS2_DCMD_DM_POS 6 +#define UHS2_DCMD_2L_HD_MODE (1 << UHS2_DCMD_DM_POS) +#define UHS2_DCMD_LM_POS 5 +#define UHS2_DCMD_LM_TLEN_EXIST (1 << UHS2_DCMD_LM_POS) +#define UHS2_DCMD_TLUM_POS 4 +#define UHS2_DCMD_TLUM_BYTE_MODE (1 << UHS2_DCMD_TLUM_POS) +#define UHS2_NATIVE_DCMD_DAM_POS 3 +#define UHS2_NATIVE_DCMD_DAM_IO (1 << UHS2_NATIVE_DCMD_DAM_POS) + +/* + * Per UHS2 spec, DCMD payload should be MSB first. There may be + * two types of data be assembled to MSB: + * 1. TLEN: Input block size for single read/write and number of blocks + * for multiple read/write to calculate TLEN as MSB first per spec. + * 2. SD command argument. + */ +static inline __be32 uhs2_dcmd_convert_msb(u32 input) +{ + u32 ret = 0; + + ret = ((input & 0xFF) << 24) | + (((input >> 8) & 0xFF) << 16) | + (((input >> 16) & 0xFF) << 8) | + ((input >> 24) & 0xFF); + return cpu_to_be32(ret); +} + +#define UHS2_RES_NACK_POS 7 +#define UHS2_RES_NACK_MASK (0x1 << UHS2_RES_NACK_POS) + +#define UHS2_RES_ECODE_POS 4 +#define UHS2_RES_ECODE_MASK 0x7 +#define UHS2_RES_ECODE_COND 1 +#define UHS2_RES_ECODE_ARG 2 +#define UHS2_RES_ECODE_GEN 3 + +/* IOADR of device registers */ +#define UHS2_IOADR_GENERIC_CAPS 0x00 +#define UHS2_IOADR_PHY_CAPS 0x02 +#define UHS2_IOADR_LINK_CAPS 0x04 +#define UHS2_IOADR_RSV_CAPS 0x06 +#define UHS2_IOADR_GENERIC_SETTINGS 0x08 +#define UHS2_IOADR_PHY_SETTINGS 0x0A +#define UHS2_IOADR_LINK_SETTINGS 0x0C +#define UHS2_IOADR_PRESET 0x40 + +/* SD application packets */ +#define UHS2_SD_CMD_INDEX_POS 8 + +#define UHS2_SD_CMD_APP_POS 14 +#define UHS2_SD_CMD_APP (1 << UHS2_SD_CMD_APP_POS) + +/* UHS-II Device Registers */ +#define UHS2_DEV_CONFIG_REG 0x000 + +/* General Caps and Settings registers */ +#define UHS2_DEV_CONFIG_GEN_CAPS (UHS2_DEV_CONFIG_REG + 0x000) +#define UHS2_DEV_CONFIG_N_LANES_POS 8 +#define UHS2_DEV_CONFIG_N_LANES_MASK 0x3F +#define UHS2_DEV_CONFIG_2L_HD_FD 0x1 +#define UHS2_DEV_CONFIG_2D1U_FD 0x2 +#define UHS2_DEV_CONFIG_1D2U_FD 0x4 +#define UHS2_DEV_CONFIG_2D2U_FD 0x8 +#define UHS2_DEV_CONFIG_DADR_POS 14 +#define UHS2_DEV_CONFIG_DADR_MASK 0x1 +#define UHS2_DEV_CONFIG_APP_POS 16 +#define UHS2_DEV_CONFIG_APP_MASK 0xFF +#define UHS2_DEV_CONFIG_APP_SD_MEM 0x1 + +#define UHS2_DEV_CONFIG_GEN_SET (UHS2_DEV_CONFIG_REG + 0x008) +#define UHS2_DEV_CONFIG_GEN_SET_N_LANES_POS 8 +#define UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD 0x0 +#define UHS2_DEV_CONFIG_GEN_SET_2D1U_FD 0x2 +#define UHS2_DEV_CONFIG_GEN_SET_1D2U_FD 0x3 +#define UHS2_DEV_CONFIG_GEN_SET_2D2U_FD 0x4 +#define UHS2_DEV_CONFIG_GEN_SET_CFG_COMPLETE BIT(31) + +/* PHY Caps and Settings registers */ +#define UHS2_DEV_CONFIG_PHY_CAPS (UHS2_DEV_CONFIG_REG + 0x002) +#define UHS2_DEV_CONFIG_PHY_MINOR_MASK 0xF +#define UHS2_DEV_CONFIG_PHY_MAJOR_POS 4 +#define UHS2_DEV_CONFIG_PHY_MAJOR_MASK 0x3 +#define UHS2_DEV_CONFIG_CAN_HIBER_POS 15 +#define UHS2_DEV_CONFIG_CAN_HIBER_MASK 0x1 +#define UHS2_DEV_CONFIG_PHY_CAPS1 (UHS2_DEV_CONFIG_REG + 0x003) +#define UHS2_DEV_CONFIG_N_LSS_SYN_MASK 0xF +#define UHS2_DEV_CONFIG_N_LSS_DIR_POS 4 +#define UHS2_DEV_CONFIG_N_LSS_DIR_MASK 0xF + +#define UHS2_DEV_CONFIG_PHY_SET (UHS2_DEV_CONFIG_REG + 0x00A) +#define UHS2_DEV_CONFIG_PHY_SET_SPEED_POS 6 +#define UHS2_DEV_CONFIG_PHY_SET_SPEED_A 0x0 +#define UHS2_DEV_CONFIG_PHY_SET_SPEED_B 0x1 + +/* LINK-TRAN Caps and Settings registers */ +#define UHS2_DEV_CONFIG_LINK_TRAN_CAPS (UHS2_DEV_CONFIG_REG + 0x004) +#define UHS2_DEV_CONFIG_LT_MINOR_MASK 0xF +#define UHS2_DEV_CONFIG_LT_MAJOR_POS 4 +#define UHS2_DEV_CONFIG_LT_MAJOR_MASK 0x3 +#define UHS2_DEV_CONFIG_N_FCU_POS 8 +#define UHS2_DEV_CONFIG_N_FCU_MASK 0xFF +#define UHS2_DEV_CONFIG_DEV_TYPE_POS 16 +#define UHS2_DEV_CONFIG_DEV_TYPE_MASK 0x7 +#define UHS2_DEV_CONFIG_MAX_BLK_LEN_POS 20 +#define UHS2_DEV_CONFIG_MAX_BLK_LEN_MASK 0xFFF +#define UHS2_DEV_CONFIG_LINK_TRAN_CAPS1 (UHS2_DEV_CONFIG_REG + 0x005) +#define UHS2_DEV_CONFIG_N_DATA_GAP_MASK 0xFF + +#define UHS2_DEV_CONFIG_LINK_TRAN_SET (UHS2_DEV_CONFIG_REG + 0x00C) +#define UHS2_DEV_CONFIG_LT_SET_MAX_BLK_LEN 0x200 +#define UHS2_DEV_CONFIG_LT_SET_MAX_RETRY_POS 16 + +/* Preset register */ +#define UHS2_DEV_CONFIG_PRESET (UHS2_DEV_CONFIG_REG + 0x040) + +#define UHS2_DEV_INT_REG 0x100 + +#define UHS2_DEV_STATUS_REG 0x180 + +#define UHS2_DEV_CMD_REG 0x200 +#define UHS2_DEV_CMD_FULL_RESET (UHS2_DEV_CMD_REG + 0x000) +#define UHS2_DEV_CMD_GO_DORMANT_STATE (UHS2_DEV_CMD_REG + 0x001) +#define UHS2_DEV_CMD_DORMANT_HIBER BIT(7) +#define UHS2_DEV_CMD_DEVICE_INIT (UHS2_DEV_CMD_REG + 0x002) +#define UHS2_DEV_INIT_COMPLETE_FLAG BIT(11) +#define UHS2_DEV_CMD_ENUMERATE (UHS2_DEV_CMD_REG + 0x003) +#define UHS2_DEV_CMD_TRANS_ABORT (UHS2_DEV_CMD_REG + 0x004) + +#define UHS2_RCLK_MAX 52000000 +#define UHS2_RCLK_MIN 26000000 + +struct sd_uhs2_wait_active_state_data { + struct mmc_host *host; + struct mmc_command *cmd; +}; + +#endif /* LINUX_MMC_UHS2_H */ From patchwork Mon Oct 17 09:11:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3303 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347041wrs; Mon, 17 Oct 2022 02:16:29 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5Sbaav+mBS4fPqjRDnNAVG2b9S68YYxphCvMlRvYTW+8SmKeDzCQCMsa+YoLYfHuy6bl3P X-Received: by 2002:a05:6a00:16c4:b0:535:890:d4a with SMTP id l4-20020a056a0016c400b0053508900d4amr11726726pfc.0.1665998189525; Mon, 17 Oct 2022 02:16:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998189; cv=none; d=google.com; s=arc-20160816; b=PTzNFdx/6ZcEUAvu/+a44ZePsplmufdF9OmqLeNaJ8R7nRwSHLZBehqtjQELhL7w10 qXcaIwP9FIzyAbK+/xHki+fqsPvF9a0DHCG4OHX9kwQ50dt2apQdp/TdUmddWkp1ijk5 wte45n+kA+07WxiLqm9qh93f5EixkYhBTXj1ndsFODgix8tBxMPFEwuXg8q7RzRJ9mEl 9gKhALCbpBd5jkS41Un4W+/A52I8yZ1y1VqB2EBtXsDZOwHpq2u3xGSgEK1eJ9AIclEu 1kLuKLNmlwoRubwi1zZ1+CYUguvra7eFuNF0NLl5kfF8axkXAaj9nOIENAeXBQNFIMCv uaTg== 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=Cwsiv8Ld576WdHTsb9zAgdw1W1DAekXFvKnp5mZ52hs=; b=lqAXnY3vKuAAXGkPw7uXDLru/n8+33Sop49ANbR/DbD0IwQw5Q3GCewEGufoCE9k/y Q4ZBpt5aDhpgJHvgNI3CYywkyXqSCftf6ydAfJZr2//8mlHfOqIXpQo6/WOkQrQumxzQ CfVzhejIQ3J9MvLur937iE11ZnXkyx83c2k2/hVO9EED6jqUr3Ss3VINR3uugILJjjoy 3hG+NbiMhByHn4H8w3FYmFnD5qjPuerCjaxdQ4ElV0RpkdFgafsE48Vj4TcKFf87un2a VTHj5D+92M2TqNYcdWF9FCy9/JF3eKAXS0neTd08t+mTw2f+z5zZXiiNAVALxfVnzssy 19Nw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=LFzunMIN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k19-20020a056a00169300b005637df79509si11125548pfc.197.2022.10.17.02.16.15; Mon, 17 Oct 2022 02:16:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=LFzunMIN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230386AbiJQJN3 (ORCPT + 99 others); Mon, 17 Oct 2022 05:13:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33168 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231177AbiJQJM5 (ORCPT ); Mon, 17 Oct 2022 05:12:57 -0400 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5771B23EBE; Mon, 17 Oct 2022 02:12:29 -0700 (PDT) Received: by mail-pf1-x430.google.com with SMTP id d10so10521098pfh.6; Mon, 17 Oct 2022 02:12:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=Cwsiv8Ld576WdHTsb9zAgdw1W1DAekXFvKnp5mZ52hs=; b=LFzunMINE7RMDKsJ8reUfOtXCCfueykGnJjuOymE94LytHQUogzton93wQGnbwUd8r 5+wM+dpinnJggs0/PbhqYN04LxqGqGlAQwh5bJU/xoUxqxMQZKg1F8XxocS/E1lUWW5O JF+0FEVF5VcyPshzkBY3ARg3qospgrm/wBx7eFAFQ5apbDW+cfhbYN6beAZlBbErNwAA 0NtJuelabu01Egj986kPO+Jale3J0iBe82pHa092f68qKQv5oSOVJKeXBCmA2U3b+ifj Yf0HPXw7UCvWMZehGuidCpUPzsMBfqVqdxVpm+lSbzIGa8WTjueKIw69wuBmhtRIztXc +FUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=Cwsiv8Ld576WdHTsb9zAgdw1W1DAekXFvKnp5mZ52hs=; b=BQ1qb6fepxLnvYjAXp/68r5RGOjGObDrpCcetaivGWFZETb2MZL9QftWd2fIil+U/7 E/EaGUGsutj3j7+o7mPNjg6+ZPFsaq+ZuMXRo+cVSe9SuMc9Dyad8aiVP2hrAhP0MLTU NaaAULTn2mOL1jwzD8EbGcZAwpOyp/+aszZPx3UdbCUb36406ZzmaZ/kznP+RTpNhuh2 /9WVPUot1ofeqjKGGRbyjDzCFe53o0yG3D25cAezsCx77b8wEqYYm85DE5hakdbBebvx aitK2vmdLz+uoYDwu9ZwPam593ZpUtlotXLc8GArm0OJ7Oxdky5h6UNN5S/DKRug1GTQ tDfQ== X-Gm-Message-State: ACrzQf3yHpCWFi249u3s8AElgNW0EfRtuPpmySE59dXQ1X3rPUuBtAAa PW/SPngcu1u/3p1fRV90FK2R+SSHrO4= X-Received: by 2002:a05:6a00:228f:b0:566:6ecd:29d9 with SMTP id f15-20020a056a00228f00b005666ecd29d9mr11756971pfe.62.1665997949202; Mon, 17 Oct 2022 02:12:29 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:28 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Jason Lai Subject: [PATCH V5 06/26] mmc: core: Support UHS-II card control and access Date: Mon, 17 Oct 2022 17:11:33 +0800 Message-Id: <20221017091153.454873-7-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925717581983852?= X-GMAIL-MSGID: =?utf-8?q?1746925717581983852?= Updates in V5: - Added uhs2_tmode0_flag in mmc_blk_rw_rq_prep: block.c - Added mechanism for confirming the completion of Card initialization in mmc_start_request: core.c - Added mechanism for confirming the completion of Card initialization in mmc_cqe_start_req: core.c - Added uhs2_tmode0_flag in mmc_send_adtc_data: mmc_ops.c - Added mechanism for confirming the completion of Card initialization in mmc_app_cmd: sd_ops.c - Added uhs2_tmode0_flag in mmc_app_send_scr: sd_ops.c - Added uhs2_tmode0_flag in mmc_app_sd_status: sd_ops.c - Added UHS2_PHY_INIT of uhs2_control for detect UHS2 in sd_uhs2_go_dormant: sd_uhs2.c - Modified the ocr/rocr flow in sd_uhs2_legacy_init: sd_uhs2.c - Added mmc_decode_cid in sd_uhs2_legacy_init: sd_uhs2.c - Added remove MMC_UHS2_INITIALIZED of host->flags in sd_uhs2_remove: sd_uhs2.c - Added MMC_UHS2_INITIALIZED of host->flags and MMC_UHS2_INITIALIZED of host->card->uhs2_state in sd_uhs2_init_card: sd_uhs2.c - Added MMC_UHS2_SUPPORT of host->flags in sd_uhs2_attach: sd_uhs2.c Update in V4: 1. Rename sd_uhs2_prepare_cmd() into mmc_uhs2_prepare_cmd(). 2. Rename ->uhs2_host_operation() into ->uhs2_control(). 3. Declare ->uhs2_set_ios() which should be implemented in mmc/host/sdhci-uhs2.c. 4. Implement call back functions in sd_uhs2_ops. 5. Replace variables which are used as constant with constant definition. 6. Change data type of uhs2_cmd->payload from u32 to __be32 because of the use of cpu_to_be32(). 7. Add comments to explain format of UHS-II CMD Header and Argument. 8. Add comments to explain format of UHS-II CMD response. 9. Remove unnecessary debug info. 10. Use sd_uhs2_select_voltage() to replace mmc_select_voltage(). 11. Use __mmc_poll_for_busy() to replace while loop. 12. Add processing of uhs2_cmd when starting request. 13. Use macro 'mmc_card_can_poweroff_notify' to replace function "sd_can_poweroff_notify()" and put it to include/linux/mmc/card.h. 14. Embed UHS-II access functionality into the MMC request processing flow. Update in V3: UHS-II card initialization flow is divided into 2 categories: PHY & Card. Part 1 - PHY Initialization: Every host controller may need their own avtivation operation to establish LINK between controller and card. So we add a new member function(uhs2_detect_init) in struct mmc_host_ops for host controller use. Part 2 - Card Initialization: This part can be divided into 6 substeps. 1. Send UHS-II CCMD DEVICE_INIT to card. 2. Send UHS-II CCMD ENUMERATE to card. 3. Send UHS-II Native Read CCMD to obtain capabilities in CFG_REG of card. 4. Host compares capabilities of host controller and card, then write the negotiated values to Setting field in CFG_REG of card through UHS-II Native Write CCMD. 5. Switch host controller's clock to Range B if it is supported by both host controller and card. 6. Execute legacy SD initialization flow. Part 3 - Provide a function to tranaform legacy SD command packet into UHS-II SD-TRAN DCMD packet. Most of the code added above came from Intel's original patch[5]. [5] https://patchwork.kernel.org/project/linux-mmc/patch/1419672479-30852-2- git-send-email-yi.y.sun@intel.com/ Signed-off-by: Ulf Hansson Signed-off-by: Jason Lai Signed-off-by: Victor Shih --- drivers/mmc/core/block.c | 6 +- drivers/mmc/core/core.c | 32 + drivers/mmc/core/mmc_ops.c | 25 +- drivers/mmc/core/mmc_ops.h | 1 + drivers/mmc/core/sd.c | 11 +- drivers/mmc/core/sd.h | 3 + drivers/mmc/core/sd_ops.c | 18 + drivers/mmc/core/sd_ops.h | 3 + drivers/mmc/core/sd_uhs2.c | 1165 +++++++++++++++++++++++++++++++++++- 9 files changed, 1217 insertions(+), 47 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index ce89611a136e..ed38cf33f256 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1598,6 +1598,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, struct request *req = mmc_queue_req_to_req(mqrq); struct mmc_blk_data *md = mq->blkdata; bool do_rel_wr, do_data_tag; + bool do_multi; + + do_multi = (card->uhs2_state & MMC_UHS2_INITIALIZED) ? true : false; mmc_blk_data_prep(mq, mqrq, recovery_mode, &do_rel_wr, &do_data_tag); @@ -1608,7 +1611,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, brq->cmd.arg <<= 9; brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - if (brq->data.blocks > 1 || do_rel_wr) { + if (brq->data.blocks > 1 || do_rel_wr || do_multi) { /* SPI multiblock writes terminate using a special * token, not a STOP_TRANSMISSION request. */ @@ -1621,6 +1624,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, brq->mrq.stop = NULL; readcmd = MMC_READ_SINGLE_BLOCK; writecmd = MMC_WRITE_BLOCK; + brq->cmd.uhs2_tmode0_flag = 1; } brq->cmd.opcode = rq_data_dir(req) == READ ? readcmd : writecmd; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ab2a48e1e876..d3f8f6c78bb1 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -335,6 +335,8 @@ static int mmc_mrq_prep(struct mmc_host *host, struct mmc_request *mrq) int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) { + struct uhs2_command uhs2_cmd; + __be32 payload[4]; /* for maximum size */ int err; init_completion(&mrq->cmd_completion); @@ -352,6 +354,20 @@ int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) if (err) return err; + if (host->card) { + if (host->card->uhs2_state & MMC_UHS2_INITIALIZED) { + uhs2_cmd.payload = payload; + mrq->cmd->uhs2_cmd = &uhs2_cmd; + mmc_uhs2_prepare_cmd(host, mrq); + } + } else { + if (host->flags & MMC_UHS2_INITIALIZED) { + uhs2_cmd.payload = payload; + mrq->cmd->uhs2_cmd = &uhs2_cmd; + mmc_uhs2_prepare_cmd(host, mrq); + } + } + led_trigger_event(host->led, LED_FULL); __mmc_start_request(host, mrq); @@ -431,6 +447,8 @@ EXPORT_SYMBOL(mmc_wait_for_req_done); */ int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq) { + struct uhs2_command uhs2_cmd; + __be32 payload[4]; /* for maximum size */ int err; /* @@ -451,6 +469,20 @@ int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq) if (err) goto out_err; + if (host->card) { + if (host->card->uhs2_state & MMC_UHS2_INITIALIZED) { + uhs2_cmd.payload = payload; + mrq->cmd->uhs2_cmd = &uhs2_cmd; + mmc_uhs2_prepare_cmd(host, mrq); + } + } else { + if (host->flags & MMC_UHS2_INITIALIZED) { + uhs2_cmd.payload = payload; + mrq->cmd->uhs2_cmd = &uhs2_cmd; + mmc_uhs2_prepare_cmd(host, mrq); + } + } + err = host->cqe_ops->cqe_request(host, mrq); if (err) goto out_err; diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 81c55bfd6e0c..daa1f4ccd99a 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -144,10 +144,24 @@ int mmc_set_dsr(struct mmc_host *host) return mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); } +int __mmc_go_idle(struct mmc_host *host) +{ + struct mmc_command cmd = {}; + int err; + + cmd.opcode = MMC_GO_IDLE_STATE; + cmd.arg = 0; + cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; + + err = mmc_wait_for_cmd(host, &cmd, 0); + mmc_delay(1); + + return err; +} + int mmc_go_idle(struct mmc_host *host) { int err; - struct mmc_command cmd = {}; /* * Non-SPI hosts need to prevent chipselect going active during @@ -163,13 +177,7 @@ int mmc_go_idle(struct mmc_host *host) mmc_delay(1); } - cmd.opcode = MMC_GO_IDLE_STATE; - cmd.arg = 0; - cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC; - - err = mmc_wait_for_cmd(host, &cmd, 0); - - mmc_delay(1); + err = __mmc_go_idle(host); if (!mmc_host_is_spi(host)) { mmc_set_chip_select(host, MMC_CS_DONTCARE); @@ -300,6 +308,7 @@ int mmc_send_adtc_data(struct mmc_card *card, struct mmc_host *host, u32 opcode, * not R1 plus a data block. */ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + cmd.uhs2_tmode0_flag = 1; data.blksz = len; data.blocks = 1; diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 09ffbc00908b..abda7492d578 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h @@ -25,6 +25,7 @@ struct mmc_command; int mmc_select_card(struct mmc_card *card); int mmc_deselect_cards(struct mmc_host *host); int mmc_set_dsr(struct mmc_host *host); +int __mmc_go_idle(struct mmc_host *host); int mmc_go_idle(struct mmc_host *host); int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); int mmc_set_relative_addr(struct mmc_card *card); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 3662bf5320ce..cab4725209c1 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -207,7 +207,7 @@ static int mmc_decode_csd(struct mmc_card *card) /* * Given a 64-bit response, decode to our card SCR structure. */ -static int mmc_decode_scr(struct mmc_card *card) +int mmc_decode_scr(struct mmc_card *card) { struct sd_scr *scr = &card->scr; unsigned int scr_struct; @@ -1611,11 +1611,6 @@ static void mmc_sd_detect(struct mmc_host *host) } } -static int sd_can_poweroff_notify(struct mmc_card *card) -{ - return card->ext_power.feature_support & SD_EXT_POWER_OFF_NOTIFY; -} - static int sd_busy_poweroff_notify_cb(void *cb_data, bool *busy) { struct sd_busy_data *data = cb_data; @@ -1639,7 +1634,7 @@ static int sd_busy_poweroff_notify_cb(void *cb_data, bool *busy) return 0; } -static int sd_poweroff_notify(struct mmc_card *card) +int sd_poweroff_notify(struct mmc_card *card) { struct sd_busy_data cb_data; u8 *reg_buf; @@ -1687,7 +1682,7 @@ static int _mmc_sd_suspend(struct mmc_host *host) if (mmc_card_suspended(card)) goto out; - if (sd_can_poweroff_notify(card)) + if (mmc_card_can_poweroff_notify(card)) err = sd_poweroff_notify(card); else if (!mmc_host_is_spi(host)) err = mmc_deselect_cards(host); diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h index 1af5a038bae9..b573a809a0f4 100644 --- a/drivers/mmc/core/sd.h +++ b/drivers/mmc/core/sd.h @@ -17,4 +17,7 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, unsigned mmc_sd_get_max_clock(struct mmc_card *card); int mmc_sd_switch_hs(struct mmc_card *card); +/* These call back functions were also used by UHS2 sd card */ +int sd_poweroff_notify(struct mmc_card *card); + #endif diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index ef8d1dce5af1..85af5a2ea8ff 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -27,6 +27,22 @@ int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) if (WARN_ON(card && card->host != host)) return -EINVAL; + /* + * UHS2 packet has APP bit so only set APP_CMD flag here. + * Will set the APP bit when assembling UHS2 packet. + */ + if (card) { + if (card->uhs2_state & MMC_UHS2_INITIALIZED) { + host->uhs2_ios.is_APP_CMD = true; + return 0; + } + } else { + if (host->flags & MMC_UHS2_INITIALIZED) { + host->uhs2_ios.is_APP_CMD = true; + return 0; + } + } + cmd.opcode = MMC_APP_CMD; if (card) { @@ -281,6 +297,7 @@ int mmc_app_send_scr(struct mmc_card *card) cmd.opcode = SD_APP_SEND_SCR; cmd.arg = 0; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + cmd.uhs2_tmode0_flag = 1; data.blksz = 8; data.blocks = 1; @@ -344,6 +361,7 @@ int mmc_app_sd_status(struct mmc_card *card, void *ssr) cmd.opcode = SD_APP_SD_STATUS; cmd.arg = 0; cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_ADTC; + cmd.uhs2_tmode0_flag = 1; data.blksz = 64; data.blocks = 1; diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index 3ba7b3cf4652..29c802dec988 100644 --- a/drivers/mmc/core/sd_ops.h +++ b/drivers/mmc/core/sd_ops.h @@ -11,6 +11,7 @@ #include struct mmc_card; +struct mmc_command; struct mmc_host; int mmc_app_set_bus_width(struct mmc_card *card, int width); @@ -19,10 +20,12 @@ int mmc_send_if_cond(struct mmc_host *host, u32 ocr); int mmc_send_if_cond_pcie(struct mmc_host *host, u32 ocr); int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca); int mmc_app_send_scr(struct mmc_card *card); +int mmc_decode_scr(struct mmc_card *card); int mmc_sd_switch(struct mmc_card *card, int mode, int group, u8 value, u8 *resp); int mmc_app_sd_status(struct mmc_card *card, void *ssr); int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); +void mmc_uhs2_prepare_cmd(struct mmc_host *host, struct mmc_request *mrq); #endif diff --git a/drivers/mmc/core/sd_uhs2.c b/drivers/mmc/core/sd_uhs2.c index 800957f74632..bccdd4283a67 100644 --- a/drivers/mmc/core/sd_uhs2.c +++ b/drivers/mmc/core/sd_uhs2.c @@ -1,48 +1,125 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2021 Linaro Ltd - * * Author: Ulf Hansson * + * Copyright (C) 2014 Intel Corp, All Rights Reserved. + * Author: Yi Sun + * + * Copyright (C) 2020 Genesys Logic, Inc. + * Authors: Ben Chuang + * + * Copyright (C) 2020 Linaro Limited + * Author: AKASHI Takahiro + * + * Copyright (C) 2022 Genesys Logic, Inc. + * Authors: Jason Lai + * * Support for SD UHS-II cards */ #include +#include #include #include +#include +#include +#include +#include "card.h" #include "core.h" #include "bus.h" #include "sd.h" +#include "sd_ops.h" #include "mmc_ops.h" +#define UHS2_WAIT_CFG_COMPLETE_PERIOD_US (1 * 1000) /* 1ms */ +#define UHS2_WAIT_CFG_COMPLETE_TIMEOUT_MS 100 /* 100ms */ + static const unsigned int sd_uhs2_freqs[] = { 52000000, 26000000 }; +int sd_uhs2_reinit(struct mmc_host *host); -static int sd_uhs2_set_ios(struct mmc_host *host) +/* + * Internal function that does the actual ios call to the host driver, + * optionally printing some debug output. + */ +static inline int sd_uhs2_set_ios(struct mmc_host *host) { struct mmc_ios *ios = &host->ios; + pr_debug("%s: clock %uHz powermode %u Vdd %u timing %u\n", + mmc_hostname(host), ios->clock, ios->power_mode, ios->vdd, ios->timing); + return host->ops->uhs2_set_ios(host, ios); } static int sd_uhs2_power_up(struct mmc_host *host) { + int err; + + if (host->ios.power_mode == MMC_POWER_ON) + return 0; + host->ios.vdd = fls(host->ocr_avail) - 1; host->ios.clock = host->f_init; host->ios.timing = MMC_TIMING_SD_UHS2; - host->ios.power_mode = MMC_POWER_UP; + host->ios.power_mode = MMC_POWER_ON; - return sd_uhs2_set_ios(host); + err = sd_uhs2_set_ios(host); + + mmc_delay(host->uhs2_ios.power_delay_ms); + + return err; } -static void sd_uhs2_power_off(struct mmc_host *host) +static int sd_uhs2_power_off(struct mmc_host *host) { + if (host->ios.power_mode == MMC_POWER_OFF) + return 0; + host->ios.vdd = 0; host->ios.clock = 0; host->ios.timing = MMC_TIMING_LEGACY; host->ios.power_mode = MMC_POWER_OFF; - sd_uhs2_set_ios(host); + return sd_uhs2_set_ios(host); +} + +/** + * sd_uhs2_cmd_assemble() - build up UHS-II command packet which is embedded in + * mmc_command structure + * @cmd: MMC command to executed + * @uhs2_cmd: UHS2 command corresponded to MMC command + * @header: Header field of UHS-II command cxpacket + * @arg: Argument field of UHS-II command packet + * @payload: Payload field of UHS-II command packet + * @plen: Payload length + * @resp: Response buffer is allocated by caller and it is used to keep + * the response of CM-TRAN command. For SD-TRAN command, uhs2_resp + * should be null and SD-TRAN command response should be stored in + * resp of mmc_command. + * @resp_len: Response buffer length + * + * The uhs2_command structure contains message packets which are transmited/ + * received on UHS-II bus. This function fills in the contents of uhs2_command + * structure and embededs UHS2 command into mmc_command structure, which is used + * in legacy SD operation functions. + * + */ +static void sd_uhs2_cmd_assemble(struct mmc_command *cmd, + struct uhs2_command *uhs2_cmd, + u16 header, u16 arg, __be32 *payload, + u8 plen, u8 *resp, u8 resp_len) +{ + uhs2_cmd->header = header; + uhs2_cmd->arg = arg; + uhs2_cmd->payload = payload; + uhs2_cmd->payload_len = plen * sizeof(u32); + uhs2_cmd->packet_len = uhs2_cmd->payload_len + 4; + + cmd->uhs2_cmd = uhs2_cmd; + cmd->uhs2_resp = resp; + cmd->uhs2_resp_len = resp_len; } /* @@ -52,7 +129,15 @@ static void sd_uhs2_power_off(struct mmc_host *host) */ static int sd_uhs2_phy_init(struct mmc_host *host) { - return 0; + int err = 0; + + err = host->ops->uhs2_control(host, UHS2_PHY_INIT); + if (err) { + pr_err("%s: failed to initial phy for UHS-II!\n", + mmc_hostname(host)); + } + + return err; } /* @@ -61,6 +146,88 @@ static int sd_uhs2_phy_init(struct mmc_host *host) */ static int sd_uhs2_dev_init(struct mmc_host *host) { + struct mmc_command cmd = {0}; + struct uhs2_command uhs2_cmd = {}; + u32 cnt; + u32 dap, gap, resp_gap; + u16 header, arg; + __be32 payload[UHS2_DEV_INIT_PAYLOAD_LEN]; + u8 gd = 0; + u8 resp[UHS2_DEV_ENUM_RESP_LEN] = {0}; + int err; + + dap = host->uhs2_caps.dap; + gap = host->uhs2_caps.gap; + + /* + * Refer to UHS-II Addendum Version 1.02 Figure 6-21 to see DEVICE_INIT CCMD format. + * Head: + * - Control Write(R/W=1) with 4-Byte payload(PLEN=01b). + * - IOADR = CMD_BASE + 002h + * Payload: + * - bit [3:0] : GAP(Group Allocated Power) + * - bit [7:4] : GD(Group Descriptor) + * - bit [11] : Complete Flag + * - bit [15:12]: DAP(Device Allocated Power) + */ + header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD; + arg = ((UHS2_DEV_CMD_DEVICE_INIT & 0xFF) << 8) | + UHS2_NATIVE_CMD_WRITE | + UHS2_NATIVE_CMD_PLEN_4B | + (UHS2_DEV_CMD_DEVICE_INIT >> 8); + + /* + * Refer to UHS-II Addendum Version 1.02 section 6.3.1. + * Max. time from DEVICE_INIT CCMD EOP reception on Device + * Rx to its SOP transmission on Device Tx(Tfwd_init_cmd) is + * 1 second. + */ + cmd.busy_timeout = 1000; + + /* + * Refer to UHS-II Addendum Version 1.02 section 6.2.6.3. + * When the number of the DEVICE_INIT commands is reach to + * 30 tiems, Host shall stop issuing DEVICE_INIT command + * and regard it as an error. + */ + for (cnt = 0; cnt < 30; cnt++) { + payload[0] = ((dap & 0xF) << 12) | + UHS2_DEV_INIT_COMPLETE_FLAG | + ((gd & 0xF) << 4) | + (gap & 0xF); + + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, + payload, UHS2_DEV_INIT_PAYLOAD_LEN, + resp, UHS2_DEV_INIT_RESP_LEN); + + err = mmc_wait_for_cmd(host, &cmd, 0); + + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + if (resp[3] != (UHS2_DEV_CMD_DEVICE_INIT & 0xFF)) { + pr_err("%s: DEVICE_INIT response is wrong!\n", + mmc_hostname(host)); + return -EIO; + } + + if (resp[5] & 0x8) { + host->uhs2_caps.group_desc = gd; + return 0; + } + resp_gap = resp[4] & 0x0F; + if (gap == resp_gap) + gd++; + } + if (cnt == 30) { + pr_err("%s: DEVICE_INIT fail, already 30 times!\n", + mmc_hostname(host)); + return -EIO; + } + return 0; } @@ -71,6 +238,52 @@ static int sd_uhs2_dev_init(struct mmc_host *host) */ static int sd_uhs2_enum(struct mmc_host *host, u32 *node_id) { + struct mmc_command cmd = {0}; + struct uhs2_command uhs2_cmd = {}; + u16 header, arg; + __be32 payload[UHS2_DEV_ENUM_PAYLOAD_LEN]; + u8 id_f = 0xF, id_l = 0x0; + u8 resp[UHS2_DEV_ENUM_RESP_LEN] = {0}; + int err; + + /* + * Refer to UHS-II Addendum Version 1.02 Figure 6-28 to see ENUMERATE CCMD format. + * Header: + * - Control Write(R/W=1) with 4-Byte payload(PLEN=01b). + * - IOADR = CMD_BASE + 003h + * Payload: + * - bit [3:0]: ID_L(Last Node ID) + * - bit [7:4]: ID_F(First Node ID) + */ + header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD; + arg = ((UHS2_DEV_CMD_ENUMERATE & 0xFF) << 8) | + UHS2_NATIVE_CMD_WRITE | + UHS2_NATIVE_CMD_PLEN_4B | + (UHS2_DEV_CMD_ENUMERATE >> 8); + + payload[0] = (id_f << 4) | id_l; + payload[0] = cpu_to_be32(payload[0]); + + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, payload, UHS2_DEV_ENUM_PAYLOAD_LEN, + resp, UHS2_DEV_ENUM_RESP_LEN); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + if (resp[3] != (UHS2_DEV_CMD_ENUMERATE & 0xFF)) { + pr_err("%s: ENUMERATE response is wrong!\n", + mmc_hostname(host)); + return -EIO; + } + + id_f = (resp[4] >> 4) & 0xF; + id_l = resp[4] & 0xF; + *node_id = id_f; + return 0; } @@ -81,6 +294,181 @@ static int sd_uhs2_enum(struct mmc_host *host, u32 *node_id) */ static int sd_uhs2_config_read(struct mmc_host *host, struct mmc_card *card) { + struct mmc_command cmd = {0}; + struct uhs2_command uhs2_cmd = {}; + u16 header, arg; + u32 cap; + int err; + + /* + * Use Control Read CCMD to read Generic Capability from Configuration Register. + * - Control Write(R/W=1) with 4-Byte payload(PLEN=01b). + * - IOADR = Generic Capability Register(CFG_BASE + 000h) + */ + header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD | card->uhs2_config.node_id; + arg = ((UHS2_DEV_CONFIG_GEN_CAPS & 0xFF) << 8) | + UHS2_NATIVE_CMD_READ | + UHS2_NATIVE_CMD_PLEN_4B | + (UHS2_DEV_CONFIG_GEN_CAPS >> 8); + + /* + * There is no payload because per spec, there should be + * no payload field for read CCMD. + * Plen is set in arg. Per spec, plen for read CCMD + * represents the len of read data which is assigned in payload + * of following RES (p136). + */ + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, NULL, 0, NULL, 0); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + /* + * Generic Capability Register: + * bit [7:0] : Reserved + * bit [13:8] : Device-Specific Number of Lanes and Functionality + * bit 8: 2L-HD + * bit 9: 2D-1U FD + * bit 10: 1D-2U FD + * bit 11: 2D-2U FD + * Others: Reserved + * bit [14] : DADR Length + * 0: 4 bytes + * 1: Reserved + * bit [23:16]: Application Type + * bit 16: 0=Non-SD memory, 1=SD memory + * bit 17: 0=Non-SDIO, 1=SDIO + * bit 18: 0=Card, 1=Embedded + * bit [63:24]: Reserved + */ + cap = cmd.resp[0]; + card->uhs2_config.n_lanes = + (cap >> UHS2_DEV_CONFIG_N_LANES_POS) & + UHS2_DEV_CONFIG_N_LANES_MASK; + card->uhs2_config.dadr_len = + (cap >> UHS2_DEV_CONFIG_DADR_POS) & + UHS2_DEV_CONFIG_DADR_MASK; + card->uhs2_config.app_type = + (cap >> UHS2_DEV_CONFIG_APP_POS) & + UHS2_DEV_CONFIG_APP_MASK; + + /* + * Use Control Read CCMD to read PHY Capability from Configuration Register. + * - Control Write(R/W=1) with 8-Byte payload(PLEN=10b). + * - IOADR = PHY Capability Register(CFG_BASE + 002h) + */ + arg = ((UHS2_DEV_CONFIG_PHY_CAPS & 0xFF) << 8) | + UHS2_NATIVE_CMD_READ | + UHS2_NATIVE_CMD_PLEN_8B | + (UHS2_DEV_CONFIG_PHY_CAPS >> 8); + + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, NULL, 0, NULL, 0); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + /* + * PHY Capability Register: + * bit [3:0] : PHY Minor Revision + * bit [5:4] : PHY Major Revision + * bit [15] : Support Hibernate Mode + * 0: Not support Hibernate Mode + * 1: Support Hibernate Mode + * bit [31:16]: Reserved + * bit [35:32]: Device-Specific N_LSS_SYN + * bit [39:36]: Device-Specific N_LSS_DIR + * bit [63:40]: Reserved + */ + cap = cmd.resp[0]; + card->uhs2_config.phy_minor_rev = + cap & UHS2_DEV_CONFIG_PHY_MINOR_MASK; + card->uhs2_config.phy_major_rev = + (cap >> UHS2_DEV_CONFIG_PHY_MAJOR_POS) & + UHS2_DEV_CONFIG_PHY_MAJOR_MASK; + card->uhs2_config.can_hibernate = + (cap >> UHS2_DEV_CONFIG_CAN_HIBER_POS) & + UHS2_DEV_CONFIG_CAN_HIBER_MASK; + + cap = cmd.resp[1]; + card->uhs2_config.n_lss_sync = + cap & UHS2_DEV_CONFIG_N_LSS_SYN_MASK; + card->uhs2_config.n_lss_dir = + (cap >> UHS2_DEV_CONFIG_N_LSS_DIR_POS) & + UHS2_DEV_CONFIG_N_LSS_DIR_MASK; + if (card->uhs2_config.n_lss_sync == 0) + card->uhs2_config.n_lss_sync = 16 << 2; + else + card->uhs2_config.n_lss_sync <<= 2; + + if (card->uhs2_config.n_lss_dir == 0) + card->uhs2_config.n_lss_dir = 16 << 3; + else + card->uhs2_config.n_lss_dir <<= 3; + + /* + * Use Control Read CCMD to read LINK/TRAN Capability from Configuration Register. + * - Control Write(R/W=1) with 8-Byte payload(PLEN=10b). + * - IOADR = LINK/TRAN Capability Register(CFG_BASE + 004h) + */ + arg = ((UHS2_DEV_CONFIG_LINK_TRAN_CAPS & 0xFF) << 8) | + UHS2_NATIVE_CMD_READ | + UHS2_NATIVE_CMD_PLEN_8B | + (UHS2_DEV_CONFIG_LINK_TRAN_CAPS >> 8); + + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, NULL, 0, NULL, 0); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + /* + * LINK/TRAN Capability Register: + * bit [3:0] : LINK_TRAN Minor Revision + * bit [5:4] : LINK/TRAN Major Revision + * bit [7:6] : Reserved + * bit [15:8] : Device-Specific N_FCU + * bit [18:16]: Device Type + * 001b=Host + * 010b=Device + * 011b=Reserved for CMD issuable Device + * bit [19] : Reserved + * bit [31:20]: Device-Specific MAX_BLKLEN + * bit [39:32]: Device-Specific N_DATA_GAP + * bit [63:40]: Reserved + */ + cap = cmd.resp[0]; + card->uhs2_config.link_minor_rev = + cap & UHS2_DEV_CONFIG_LT_MINOR_MASK; + card->uhs2_config.link_major_rev = + (cap >> UHS2_DEV_CONFIG_LT_MAJOR_POS) & + UHS2_DEV_CONFIG_LT_MAJOR_MASK; + card->uhs2_config.n_fcu = + (cap >> UHS2_DEV_CONFIG_N_FCU_POS) & + UHS2_DEV_CONFIG_N_FCU_MASK; + card->uhs2_config.dev_type = + (cap >> UHS2_DEV_CONFIG_DEV_TYPE_POS) & + UHS2_DEV_CONFIG_DEV_TYPE_MASK; + card->uhs2_config.maxblk_len = + (cap >> UHS2_DEV_CONFIG_MAX_BLK_LEN_POS) & + UHS2_DEV_CONFIG_MAX_BLK_LEN_MASK; + + cap = cmd.resp[1]; + card->uhs2_config.n_data_gap = + cap & UHS2_DEV_CONFIG_N_DATA_GAP_MASK; + if (card->uhs2_config.n_fcu == 0) + card->uhs2_config.n_fcu = 256; + return 0; } @@ -95,9 +483,407 @@ static int sd_uhs2_config_read(struct mmc_host *host, struct mmc_card *card) */ static int sd_uhs2_config_write(struct mmc_host *host, struct mmc_card *card) { + struct mmc_command cmd = {0}; + struct uhs2_command uhs2_cmd = {}; + u16 header, arg; + __be32 payload[UHS2_CFG_WRITE_PAYLOAD_LEN]; + u8 nMinDataGap; + int err; + u8 resp[5] = {0}; + + /* + * Use Control Write CCMD to set Generic Setting in Configuration Register. + * - Control Write(R/W=1) with 8-Byte payload(PLEN=10b). + * - IOADR = Generic Setting Register(CFG_BASE + 008h) + * - Payload = New contents to be written to Generic Setting Register + */ + header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD | card->uhs2_config.node_id; + arg = ((UHS2_DEV_CONFIG_GEN_SET & 0xFF) << 8) | + UHS2_NATIVE_CMD_WRITE | + UHS2_NATIVE_CMD_PLEN_8B | + (UHS2_DEV_CONFIG_GEN_SET >> 8); + + if (card->uhs2_config.n_lanes == UHS2_DEV_CONFIG_2L_HD_FD && + host->uhs2_caps.n_lanes == UHS2_DEV_CONFIG_2L_HD_FD) { + /* Support HD */ + host->uhs2_ios.is_2L_HD_mode = true; + nMinDataGap = 1; + } else { + /* Only support 2L-FD so far */ + host->uhs2_ios.is_2L_HD_mode = false; + nMinDataGap = 3; + } + + /* + * Most UHS-II cards only support FD and 2L-HD mode. Other lane numbers + * defined in UHS-II addendem Ver1.01 are optional. + */ + host->uhs2_caps.n_lanes_set = UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD; + card->uhs2_config.n_lanes_set = UHS2_DEV_CONFIG_GEN_SET_2L_FD_HD; + + payload[0] = card->uhs2_config.n_lanes_set << UHS2_DEV_CONFIG_N_LANES_POS; + payload[1] = 0; + payload[0] = cpu_to_be32(payload[0]); + payload[1] = cpu_to_be32(payload[1]); + + /* + * There is no payload because per spec, there should be + * no payload field for read CCMD. + * Plen is set in arg. Per spec, plen for read CCMD + * represents the len of read data which is assigned in payload + * of following RES (p136). + */ + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, payload, UHS2_CFG_WRITE_PAYLOAD_LEN, + NULL, 0); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + /* + * Use Control Write CCMD to set PHY Setting in Configuration Register. + * - Control Write(R/W=1) with 8-Byte payload(PLEN=10b). + * - IOADR = PHY Setting Register(CFG_BASE + 00Ah) + * - Payload = New contents to be written to PHY Setting Register + */ + arg = ((UHS2_DEV_CONFIG_PHY_SET & 0xFF) << 8) | + UHS2_NATIVE_CMD_WRITE | + UHS2_NATIVE_CMD_PLEN_8B | + (UHS2_DEV_CONFIG_PHY_SET >> 8); + + if (host->uhs2_caps.speed_range == UHS2_DEV_CONFIG_PHY_SET_SPEED_B) { + card->uhs2_state |= MMC_UHS2_SPEED_B; + card->uhs2_config.speed_range_set = + UHS2_DEV_CONFIG_PHY_SET_SPEED_B; + } else { + card->uhs2_config.speed_range_set = UHS2_DEV_CONFIG_PHY_SET_SPEED_A; + card->uhs2_state &= ~MMC_UHS2_SPEED_B; + } + + payload[0] = card->uhs2_config.speed_range_set << UHS2_DEV_CONFIG_PHY_SET_SPEED_POS; + + card->uhs2_config.n_lss_sync_set = (max(card->uhs2_config.n_lss_sync, + host->uhs2_caps.n_lss_sync) >> 2) & + UHS2_DEV_CONFIG_N_LSS_SYN_MASK; + host->uhs2_caps.n_lss_sync_set = card->uhs2_config.n_lss_sync_set; + + card->uhs2_config.n_lss_dir_set = (max(card->uhs2_config.n_lss_dir, + host->uhs2_caps.n_lss_dir) >> 3) & + UHS2_DEV_CONFIG_N_LSS_DIR_MASK; + host->uhs2_caps.n_lss_dir_set = card->uhs2_config.n_lss_dir_set; + + payload[1] = (card->uhs2_config.n_lss_dir_set << UHS2_DEV_CONFIG_N_LSS_DIR_POS) | + card->uhs2_config.n_lss_sync_set; + payload[0] = cpu_to_be32(payload[0]); + payload[1] = cpu_to_be32(payload[1]); + + memset(resp, 0, sizeof(resp)); + + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, payload, UHS2_CFG_WRITE_PAYLOAD_LEN, + resp, UHS2_CFG_WRITE_PHY_SET_RESP_LEN); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + if ((resp[2] & 0x80)) { + pr_err("%s: %s: UHS2 CMD not accepted, resp= 0x%x!\n", + mmc_hostname(host), __func__, resp[2]); + return -EIO; + } + + /* + * Use Control Write CCMD to set LINK/TRAN Setting in Configuration Register. + * - Control Write(R/W=1) with 8-Byte payload(PLEN=10b). + * - IOADR = LINK/TRAN Setting Register(CFG_BASE + 00Ch) + * - Payload = New contents to be written to LINK/TRAN Setting Register + */ + arg = ((UHS2_DEV_CONFIG_LINK_TRAN_SET & 0xFF) << 8) | + UHS2_NATIVE_CMD_WRITE | + UHS2_NATIVE_CMD_PLEN_8B | + (UHS2_DEV_CONFIG_LINK_TRAN_SET >> 8); + + if (card->uhs2_config.app_type == UHS2_DEV_CONFIG_APP_SD_MEM) + card->uhs2_config.maxblk_len_set = UHS2_DEV_CONFIG_LT_SET_MAX_BLK_LEN; + else + card->uhs2_config.maxblk_len_set = min(card->uhs2_config.maxblk_len, + host->uhs2_caps.maxblk_len); + host->uhs2_caps.maxblk_len_set = card->uhs2_config.maxblk_len_set; + + card->uhs2_config.n_fcu_set = min(card->uhs2_config.n_fcu, host->uhs2_caps.n_fcu); + host->uhs2_caps.n_fcu_set = card->uhs2_config.n_fcu_set; + + card->uhs2_config.n_data_gap_set = max(nMinDataGap, card->uhs2_config.n_data_gap); + host->uhs2_caps.n_data_gap_set = card->uhs2_config.n_data_gap_set; + + host->uhs2_caps.max_retry_set = 3; + card->uhs2_config.max_retry_set = host->uhs2_caps.max_retry_set; + + payload[0] = (card->uhs2_config.maxblk_len_set << UHS2_DEV_CONFIG_MAX_BLK_LEN_POS) | + (card->uhs2_config.max_retry_set << UHS2_DEV_CONFIG_LT_SET_MAX_RETRY_POS) | + (card->uhs2_config.n_fcu_set << UHS2_DEV_CONFIG_N_FCU_POS); + payload[1] = card->uhs2_config.n_data_gap_set; + payload[0] = cpu_to_be32(payload[0]); + payload[1] = cpu_to_be32(payload[1]); + + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, payload, UHS2_CFG_WRITE_PAYLOAD_LEN, + NULL, 0); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + /* + * Use Control Write CCMD to set Config Completion(payload bit 63) in Generic Setting + * Register. + * Header: + * - Control Write(R/W=1) with 8-Byte payload(PLEN=10b). + * - IOADR = PGeneric Setting Register(CFG_BASE + 008h) + * Payload: + * - bit [63]: Config Completion + * + * DLSM transits to Active state immediately when Config Completion is set to 1. + */ + arg = ((UHS2_DEV_CONFIG_GEN_SET & 0xFF) << 8) | + UHS2_NATIVE_CMD_WRITE | + UHS2_NATIVE_CMD_PLEN_8B | + (UHS2_DEV_CONFIG_GEN_SET >> 8); + + payload[0] = 0; + payload[1] = UHS2_DEV_CONFIG_GEN_SET_CFG_COMPLETE; + payload[0] = cpu_to_be32(payload[0]); + payload[1] = cpu_to_be32(payload[1]); + + memset(resp, 0, sizeof(resp)); + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, payload, UHS2_CFG_WRITE_PAYLOAD_LEN, + resp, UHS2_CFG_WRITE_GENERIC_SET_RESP_LEN); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + /* Set host Config Setting registers */ + err = host->ops->uhs2_control(host, UHS2_SET_CONFIG); + if (err) { + pr_err("%s: %s: UHS2 SET_CONFIG fail!\n", mmc_hostname(host), __func__); + return err; + } + return 0; } +static int sd_uhs2_go_dormant(struct mmc_host *host, u32 node_id) +{ + struct mmc_command cmd = {0}; + struct uhs2_command uhs2_cmd = {}; + u16 header, arg; + __be32 payload[1]; + int err; + + /* Disable Normal INT */ + err = host->ops->uhs2_control(host, UHS2_DISABLE_INT); + if (err) { + pr_err("%s: %s: UHS2 DISABLE_INT fail!\n", + mmc_hostname(host), __func__); + return err; + } + + /* + * Refer to UHS-II Addendum Version 1.02 Figure 6-17 to see GO_DORMANT_STATE CCMD format. + * Header: + * - Control Write(R/W=1) with 4-Byte payload(PLEN=01b). + * - IOADR = CMD_BASE + 001h + * Payload: + * - bit [7]: HBR(Entry to Hibernate Mode) + * 1: Host intends to enter Hibernate mode during Dormant state. + * The default setting is 0 because hibernate is currently not supported. + */ + header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD | node_id; + arg = ((UHS2_DEV_CMD_GO_DORMANT_STATE & 0xFF) << 8) | + UHS2_NATIVE_CMD_WRITE | + UHS2_NATIVE_CMD_PLEN_4B | + (UHS2_DEV_CMD_GO_DORMANT_STATE >> 8); + + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, payload, UHS2_GO_DORMANT_PAYLOAD_LEN, + NULL, 0); + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) { + pr_err("%s: %s: UHS2 CMD send fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + /* Check Dormant State in Present */ + err = host->ops->uhs2_control(host, UHS2_CHECK_DORMANT); + if (err) + return err; + + /* Disable UHS2 card clock */ + err = host->ops->uhs2_control(host, UHS2_DISABLE_CLK); + if (err) + return err; + + /* Restore sd clock */ + mmc_delay(5); + err = host->ops->uhs2_control(host, UHS2_ENABLE_CLK); + if (err) + return err; + + /* Enable Normal INT */ + err = host->ops->uhs2_control(host, UHS2_ENABLE_INT); + if (err) + return err; + + /* Detect UHS2 */ + err = host->ops->uhs2_control(host, UHS2_PHY_INIT); + if (err) + return err; + + return 0; +} + +static int __sd_uhs2_wait_active_state_cb(void *cb_data, bool *busy) +{ + struct sd_uhs2_wait_active_state_data *data = cb_data; + struct mmc_host *host = data->host; + struct mmc_command *cmd = data->cmd; + int err; + + err = mmc_wait_for_cmd(host, cmd, 0); + if (err) + return err; + + if (cmd->resp[1] & UHS2_DEV_CONFIG_GEN_SET_CFG_COMPLETE) + *busy = false; + else + *busy = true; + + return 0; +} + +static int sd_uhs2_change_speed(struct mmc_host *host, u32 node_id) +{ + struct mmc_command cmd = {0}; + struct uhs2_command uhs2_cmd = {}; + u16 header, arg; + int err; + struct sd_uhs2_wait_active_state_data cb_data = { + .host = host, + .cmd = &cmd + }; + + /* Change Speed Range at controller side. */ + err = host->ops->uhs2_control(host, UHS2_SET_SPEED_B); + if (err) { + pr_err("%s: %s: UHS2 SET_SPEED fail!\n", mmc_hostname(host), __func__); + return err; + } + + err = sd_uhs2_go_dormant(host, node_id); + if (err) { + pr_err("%s: %s: UHS2 GO_DORMANT_STATE fail, err= 0x%x!\n", + mmc_hostname(host), __func__, err); + return err; + } + + /* + * Use Control Read CCMD to check Config Completion(bit 63) in Generic Setting Register. + * - Control Read(R/W=0) with 8-Byte payload(PLEN=10b). + * - IOADR = Generic Setting Register(CFG_BASE + 008h) + * + * When UHS-II card been switched to new speed mode, it will set Config Completion to 1. + */ + header = UHS2_NATIVE_PACKET | UHS2_PACKET_TYPE_CCMD | node_id; + arg = ((UHS2_DEV_CONFIG_GEN_SET & 0xFF) << 8) | + UHS2_NATIVE_CMD_READ | + UHS2_NATIVE_CMD_PLEN_8B | + (UHS2_DEV_CONFIG_GEN_SET >> 8); + + sd_uhs2_cmd_assemble(&cmd, &uhs2_cmd, header, arg, NULL, 0, NULL, 0); + err = __mmc_poll_for_busy(host, UHS2_WAIT_CFG_COMPLETE_PERIOD_US, + UHS2_WAIT_CFG_COMPLETE_TIMEOUT_MS, + &__sd_uhs2_wait_active_state_cb, &cb_data); + if (err) { + pr_err("%s: %s: Not switch to Active in 100 ms\n", mmc_hostname(host), __func__); + return err; + } + + return 0; +} + +static int sd_uhs2_get_ro(struct mmc_host *host) +{ + /* + * Some systems don't feature a write-protect pin and don't need one. + * E.g. because they only have micro-SD card slot. For those systems + * assume that the SD card is always read-write. + */ + if (host->caps2 & MMC_CAP2_NO_WRITE_PROTECT) + return 0; + + if (!host->ops->get_ro) + return -1; + + return host->ops->get_ro(host); +} + +/* + * Mask off any voltages we don't support and select + * the lowest voltage + */ +u32 sd_uhs2_select_voltage(struct mmc_host *host, u32 ocr) +{ + int bit; + int err; + + /* + * Sanity check the voltages that the card claims to + * support. + */ + if (ocr & 0x7F) { + dev_warn(mmc_dev(host), "card claims to support voltages below defined range\n"); + ocr &= ~0x7F; + } + + ocr &= host->ocr_avail; + if (!ocr) { + dev_warn(mmc_dev(host), "no support for card's volts\n"); + return 0; + } + + if (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) { + bit = ffs(ocr) - 1; + ocr &= 3 << bit; + /* Power cycle */ + err = sd_uhs2_power_off(host); + if (err) + return 0; + err = sd_uhs2_reinit(host); + if (err) + return 0; + } else { + bit = fls(ocr) - 1; + ocr &= 3 << bit; + if (bit != host->ios.vdd) + dev_warn(mmc_dev(host), "exceeding card's volts\n"); + } + + return ocr; +} + /* * Initialize the UHS-II card through the SD-TRAN transport layer. This enables * commands/requests to be backwards compatible through the legacy SD protocol. @@ -107,14 +893,143 @@ static int sd_uhs2_config_write(struct mmc_host *host, struct mmc_card *card) */ static int sd_uhs2_legacy_init(struct mmc_host *host, struct mmc_card *card) { + int err; + u32 cid[4]; + u32 ocr; + u32 rocr; + u8 status[64]; + int ro; + + /* Send CMD0 to reset SD card */ + err = __mmc_go_idle(host); + if (err) + return err; + + mmc_delay(1); + + /* Send CMD8 to communicate SD interface operation condition */ + err = mmc_send_if_cond(host, host->ocr_avail); + if (err) { + dev_warn(mmc_dev(host), "CMD8 error\n"); + return err; + } + + /* + * Probe SD card working voltage. + */ + err = mmc_send_app_op_cond(host, 0, &ocr); + if (err) + return err; + + card->ocr = ocr; + + /* + * Some SD cards claims an out of spec VDD voltage range. Let's treat + * these bits as being in-valid and especially also bit7. + */ + ocr &= ~0x7FFF; + rocr = sd_uhs2_select_voltage(host, ocr); + /* + * Some cards have zero value of rocr in UHS-II mode. Assign host's + * ocr value to rocr. + */ + if (!rocr) + rocr = host->ocr_avail; + + rocr |= (SD_OCR_CCS | SD_OCR_XPC); + + /* Wait SD power on ready */ + ocr = rocr; + + err = mmc_send_app_op_cond(host, ocr, &rocr); + if (err) + return err; + + err = mmc_send_cid(host, cid); + if (err) + return err; + + memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); + mmc_decode_cid(card); + + /* + * For native busses: get card RCA and quit open drain mode. + */ + err = mmc_send_relative_addr(host, &card->rca); + if (err) + return err; + + err = mmc_sd_get_csd(card); + if (err) + return err; + + /* + * Select card, as all following commands rely on that. + */ + err = mmc_select_card(card); + if (err) + return err; + + /* + * Fetch SCR from card. + */ + err = mmc_app_send_scr(card); + if (err) + return err; + + err = mmc_decode_scr(card); + if (err) + return err; + + /* + * Switch to high power consumption mode. + * Even switch failed, sd card can still work at lower power consumption mode, but + * performance will be lower than high power consumption mode. + */ + if (!(card->csd.cmdclass & CCC_SWITCH)) { + pr_warn("%s: card lacks mandatory switch function, performance might suffer\n", + mmc_hostname(card->host)); + } else { + /* send CMD6 to set Maximum Power Consumption to get better performance */ + err = mmc_sd_switch(card, 0, 3, SD4_SET_POWER_LIMIT_1_80W, status); + if (!err) + err = mmc_sd_switch(card, 1, 3, SD4_SET_POWER_LIMIT_1_80W, status); + + err = 0; + } + + /* + * Check if read-only switch is active. + */ + ro = sd_uhs2_get_ro(host); + if (ro < 0) { + pr_warn("%s: host does not support read-only switch, assuming write-enable\n", + mmc_hostname(host)); + } else if (ro > 0) { + mmc_card_set_readonly(card); + } + + /* + * NOTE: + * Should we read Externsion Register to check power notification feature here? + */ + return 0; } +static void sd_uhs2_remove(struct mmc_host *host) +{ + mmc_remove_card(host->card); + host->card = NULL; + if (host->flags & MMC_UHS2_INITIALIZED) + host->flags &= ~MMC_UHS2_INITIALIZED; +} + /* * Allocate the data structure for the mmc_card and run the UHS-II specific * initialization sequence. */ -static int sd_uhs2_init_card(struct mmc_host *host) +static int sd_uhs2_init_card(struct mmc_host *host, struct mmc_card *oldcard) { struct mmc_card *card; u32 node_id; @@ -128,9 +1043,14 @@ static int sd_uhs2_init_card(struct mmc_host *host) if (err) return err; - card = mmc_alloc_card(host, &sd_type); - if (IS_ERR(card)) - return PTR_ERR(card); + if (oldcard) { + card = oldcard; + } else { + card = mmc_alloc_card(host, &sd_type); + if (IS_ERR(card)) + return PTR_ERR(card); + } + host->card = card; card->uhs2_config.node_id = node_id; card->type = MMC_TYPE_SD; @@ -143,22 +1063,47 @@ static int sd_uhs2_init_card(struct mmc_host *host) if (err) goto err; + /* Change to Speed Range B if it is supported */ + if (card->uhs2_state & MMC_UHS2_SPEED_B) { + err = sd_uhs2_change_speed(host, node_id); + if (err) + return err; + } + + host->card->uhs2_state |= MMC_UHS2_INITIALIZED; + host->flags |= MMC_UHS2_INITIALIZED; + err = sd_uhs2_legacy_init(host, card); if (err) goto err; - host->card = card; return 0; err: - mmc_remove_card(card); + if (host->card->uhs2_state & MMC_UHS2_INITIALIZED) + host->card->uhs2_state &= ~MMC_UHS2_INITIALIZED; + if (host->flags & MMC_UHS2_INITIALIZED) + host->flags &= ~MMC_UHS2_INITIALIZED; + sd_uhs2_remove(host); return err; } -static void sd_uhs2_remove(struct mmc_host *host) +int sd_uhs2_reinit(struct mmc_host *host) { - mmc_remove_card(host->card); - host->card = NULL; + struct mmc_card *card = host->card; + int err; + + sd_uhs2_power_up(host); + err = sd_uhs2_phy_init(host); + if (err) + return err; + + err = sd_uhs2_init_card(host, card); + if (err) + return err; + + mmc_card_set_present(card); + return err; } static int sd_uhs2_alive(struct mmc_host *host) @@ -184,34 +1129,176 @@ static void sd_uhs2_detect(struct mmc_host *host) } } +static int _sd_uhs2_suspend(struct mmc_host *host) +{ + struct mmc_card *card = host->card; + int err = 0; + + mmc_claim_host(host); + + if (mmc_card_suspended(card)) + goto out; + + if (mmc_card_can_poweroff_notify(card)) + err = sd_poweroff_notify(card); + + if (!err) { + sd_uhs2_power_off(host); + mmc_card_set_suspended(card); + } + +out: + mmc_release_host(host); + return err; +} + +/* + * Callback for suspend + */ static int sd_uhs2_suspend(struct mmc_host *host) { - return 0; + int err; + + err = _sd_uhs2_suspend(host); + if (!err) { + pm_runtime_disable(&host->card->dev); + pm_runtime_set_suspended(&host->card->dev); + } + + return err; +} + +/* + * This function tries to determine if the same card is still present + * and, if so, restore all state to it. + */ +static int _mmc_sd_uhs2_resume(struct mmc_host *host) +{ + int err = 0; + + mmc_claim_host(host); + + if (!mmc_card_suspended(host->card)) + goto out; + + /* Power up UHS2 SD card and re-initialize it. */ + err = sd_uhs2_reinit(host); + mmc_card_clr_suspended(host->card); + +out: + mmc_release_host(host); + return err; } +/* + * Callback for resume + */ static int sd_uhs2_resume(struct mmc_host *host) { + pm_runtime_enable(&host->card->dev); return 0; } +/* + * Callback for runtime_suspend. + */ static int sd_uhs2_runtime_suspend(struct mmc_host *host) { - return 0; + int err; + + if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) + return 0; + + err = _sd_uhs2_suspend(host); + if (err) + pr_err("%s: error %d doing aggressive suspend\n", mmc_hostname(host), err); + + return err; } static int sd_uhs2_runtime_resume(struct mmc_host *host) { - return 0; + int err; + + err = _mmc_sd_uhs2_resume(host); + if (err && err != -ENOMEDIUM) + pr_err("%s: error %d doing runtime resume\n", mmc_hostname(host), err); + + return err; } -static int sd_uhs2_shutdown(struct mmc_host *host) +static int sd_uhs2_hw_reset(struct mmc_host *host) { - return 0; + int err; + + sd_uhs2_power_off(host); + /* Wait at least 1 ms according to SD spec */ + mmc_delay(1); + sd_uhs2_power_up(host); + + err = sd_uhs2_reinit(host); + + return err; } -static int sd_uhs2_hw_reset(struct mmc_host *host) +/* + * mmc_uhs2_prepare_cmd - prepare for SD command packet + * @host: MMC host + * @mrq: MMC request + * + * Initialize and fill in a header and a payload of SD command packet. + * The caller should allocate uhs2_command in host->cmd->uhs2_cmd in + * advance. + * + * Return: 0 on success, non-zero error on failure + */ +void mmc_uhs2_prepare_cmd(struct mmc_host *host, struct mmc_request *mrq) { - return 0; + struct mmc_command *cmd; + struct uhs2_command *uhs2_cmd; + u16 header, arg; + __be32 *payload; + u8 plen; + + cmd = mrq->cmd; + header = host->card->uhs2_config.node_id; + if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) + header |= UHS2_PACKET_TYPE_DCMD; + else + header |= UHS2_PACKET_TYPE_CCMD; + + arg = cmd->opcode << UHS2_SD_CMD_INDEX_POS; + if (host->uhs2_ios.is_APP_CMD) { + arg |= UHS2_SD_CMD_APP; + host->uhs2_ios.is_APP_CMD = false; + } + + uhs2_cmd = cmd->uhs2_cmd; + payload = uhs2_cmd->payload; + plen = 2; /* at the maximum */ + + if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC && + !cmd->uhs2_tmode0_flag) { + if (host->uhs2_ios.is_2L_HD_mode) + arg |= UHS2_DCMD_2L_HD_MODE; + + arg |= UHS2_DCMD_LM_TLEN_EXIST; + + if (cmd->data->blocks == 1 && + cmd->data->blksz != 512 && + cmd->opcode != MMC_READ_SINGLE_BLOCK && + cmd->opcode != MMC_WRITE_BLOCK) { + arg |= UHS2_DCMD_TLUM_BYTE_MODE; + payload[1] = cpu_to_be32(cmd->data->blksz); + } else { + payload[1] = cpu_to_be32(cmd->data->blocks); + } + } else { + plen = 1; + } + + payload[0] = cpu_to_be32(cmd->arg); + sd_uhs2_cmd_assemble(cmd, uhs2_cmd, header, arg, payload, plen, NULL, 0); } static const struct mmc_bus_ops sd_uhs2_ops = { @@ -222,7 +1309,7 @@ static const struct mmc_bus_ops sd_uhs2_ops = { .resume = sd_uhs2_resume, .runtime_suspend = sd_uhs2_runtime_suspend, .runtime_resume = sd_uhs2_runtime_resume, - .shutdown = sd_uhs2_shutdown, + .shutdown = sd_uhs2_suspend, .hw_reset = sd_uhs2_hw_reset, }; @@ -230,6 +1317,8 @@ static int sd_uhs2_attach(struct mmc_host *host) { int err; + host->flags |= MMC_UHS2_SUPPORT; + err = sd_uhs2_power_up(host); if (err) goto err; @@ -238,7 +1327,7 @@ static int sd_uhs2_attach(struct mmc_host *host) if (err) goto err; - err = sd_uhs2_init_card(host); + err = sd_uhs2_init_card(host, NULL); if (err) goto err; @@ -251,21 +1340,34 @@ static int sd_uhs2_attach(struct mmc_host *host) goto remove_card; mmc_claim_host(host); + + host->ops->uhs2_control(host, UHS2_POST_ATTACH_SD); + return 0; remove_card: - mmc_remove_card(host->card); - host->card = NULL; + sd_uhs2_remove(host); mmc_claim_host(host); - mmc_detach_bus(host); + err: + mmc_detach_bus(host); sd_uhs2_power_off(host); - return err; + host->flags &= ~MMC_UHS2_SUPPORT; + return 1; } +/** + * mmc_attach_sd_uhs2 - select UHS2 interface + * @host: MMC host + * + * Try to select UHS2 interface and initialize the bus for a given + * frequency, @freq. + * + * Return: 0 on success, non-zero error on failure + */ int mmc_attach_sd_uhs2(struct mmc_host *host) { - int i, err = 0; + int i, err; if (!(host->caps2 & MMC_CAP2_SD_UHS2)) return -EOPNOTSUPP; @@ -280,6 +1382,9 @@ int mmc_attach_sd_uhs2(struct mmc_host *host) */ for (i = 0; i < ARRAY_SIZE(sd_uhs2_freqs); i++) { host->f_init = sd_uhs2_freqs[i]; + pr_info("%s: %s: trying to init UHS-II card at %u Hz\n", + mmc_hostname(host), __func__, host->f_init); + err = sd_uhs2_attach(host); if (!err) break; From patchwork Mon Oct 17 09:11:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3307 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347399wrs; Mon, 17 Oct 2022 02:17:27 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5vTOb4QN05xwlZCMNHoGc4WrdPvTFS20hETjOnVfrXypZ6O8DqNDAoawb0m49sZnImj1dT X-Received: by 2002:a17:90b:4a8f:b0:20d:2f93:3bb with SMTP id lp15-20020a17090b4a8f00b0020d2f9303bbmr32130420pjb.149.1665998247390; Mon, 17 Oct 2022 02:17:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998247; cv=none; d=google.com; s=arc-20160816; b=ezOw2kSYeWXTB/VUJPZa7kMVCldCFtN1mXqAkEUq5P+gHKfEKmBcQ4fVMlZSZCWbYQ jkt0TsHRJuuVADUHz2h07KrCmfRu0Mek5hIi72j/MgZb2n1fsGzRJgEBpN4uQ7FCF2dK AOubI2Dn1itY/dPUqJZzO5uYVsrOgrZIjihFILH1sGq5VJG9lTOIsuLoStyvomGvr1El mRwnfU1V2RO2DzwTxRxKwBFxfRl2lYgBBW13n6mIGvG1XtsRE3NEhzZER/6K8VCeMwZ7 bKYOoD8lRKQxcmgGwzY3xFFS75UUlokp1o+AWa/Xr1LUZ2Rq4rml4rENzexBZPzYPrHQ 2Omg== 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=pndTdcmBYUOsi9vNLnQJgPVCRSImYXTUpjmesPh3caE=; b=QWLUntc20dyW4QHq4lBsGVSrd34CySGl+Q0P5FdraNyfINuDtFyK92Oo8D38J32LUZ j0G6/Gka2fI/6fwxx8NG968uQndPALP2FB1CatGYeDeKVJChq6D5sGqDcGEnsnh3dqdf AsZ2BNZzfYo7ZEpkwD6wIQqTMFPFo7UB8XxbOZKV0IBeHaxrEFVFJyiT8bHzNpCxovFA Ysvou4rr3te2ySdZEllksc9kKZNbUb8PccMzFzj42UwTiN9HMmTluVLw34UG8do5zbrx OqDJa05xQhLXfcNWie165v77kaU3EjdYlFEaEOUa/GveS0SbSBQQ+YEPeG1fF7oerwRr mpAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=LAXvw8QG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j192-20020a638bc9000000b00462c469b730si11076766pge.648.2022.10.17.02.17.14; Mon, 17 Oct 2022 02:17:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=LAXvw8QG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230134AbiJQJNZ (ORCPT + 99 others); Mon, 17 Oct 2022 05:13:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33266 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231149AbiJQJM4 (ORCPT ); Mon, 17 Oct 2022 05:12:56 -0400 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 89ED8437E4; Mon, 17 Oct 2022 02:12:33 -0700 (PDT) Received: by mail-pl1-x632.google.com with SMTP id h2so2850199plb.2; Mon, 17 Oct 2022 02:12:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=pndTdcmBYUOsi9vNLnQJgPVCRSImYXTUpjmesPh3caE=; b=LAXvw8QGYk11KMqBW7bNTaSM/zDE+VPJ6iDcnIizkW9yp4ucFxVKGPd+GoRIE2Ya+4 YyspgneS3DTh+k8gC6IAEDo8W9g+1Mveb6h/FurqE/j4sP5lBju36AaodTaS+mW6ODEe B9UhvJXYw7VczXn3t/iBDcNzoOorQFLev9SGSscmDb2VaxWjlSi2gZ4+dbVl3WmkEpVc KUVXacPFor4BkiV1L3JN6AsiXFCz8dPmfllaW632mLEhMjxJoQLB90V6TyvN596te4OY mfUFitcmXMsg8TDFAlrkAYexONm63gcu1ssTt4WILvmYZHbV9/A3St8MeqXSKePcwalP iIVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=pndTdcmBYUOsi9vNLnQJgPVCRSImYXTUpjmesPh3caE=; b=phuIhUCg8C6xM/WcXnXd4BYU2OF7m10HiRu2LdQmdMxISqhL5m1BPCzBar0jTj+ZiF lRyE1yNpOeEhG1rWVd8e/e/dTFBjnbiucASkg2BaSL0GtFqOwj0ohPFUDPSRgmwRtZ7v xuvqWrvthXPggiWIZP6lXuJeHE2ztJ8I8cEpCsRyx40pJ009d6EfE3mN+n7mpzrUB4Zu Y95ax1IO0P8/7lHDpTWcxX7BSaDPIt7pT8t3Ba1uaffvbx1cIMnLHwHLscwK52gDqpG1 xi4X61NHWcKCJhzH1uNudh2YwkE/FDDPejXBaU583e9vjdKdTH4fYLMyNzuqUeyPO1t6 szQg== X-Gm-Message-State: ACrzQf3JTPhfFoQNF+KYUHcvxhOqp0HWzPdgEIl9xPenuj7RW8s3y47Z mHyRDZwbiC/FkgwwgcD1fDc= X-Received: by 2002:a17:902:b206:b0:184:6344:7aab with SMTP id t6-20020a170902b20600b0018463447aabmr11243936plr.103.1665997952001; Mon, 17 Oct 2022 02:12:32 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:31 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 07/26] mmc: sdhci: add a kernel configuration for enabling UHS-II support Date: Mon, 17 Oct 2022 17:11:34 +0800 Message-Id: <20221017091153.454873-8-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925777995965816?= X-GMAIL-MSGID: =?utf-8?q?1746925777995965816?= From: AKASHI Takahiro This kernel configuration, CONFIG_MMC_SDHCI_UHS2, will be used in the following commits to indicate UHS-II specific code in sdhci controllers. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro --- drivers/mmc/host/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index e63608834411..d89e7bf91c35 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -89,6 +89,15 @@ config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER This is the case for the Nintendo Wii SDHCI. +config MMC_SDHCI_UHS2 + tristate "UHS2 support on SDHCI controller" + depends on MMC_SDHCI + help + This option is selected by SDHCI controller drivers that want to + support UHS2-capable devices. + + If you have a controller with this feature, say Y or M here. + config MMC_SDHCI_PCI tristate "SDHCI support on PCI bus" depends on MMC_SDHCI && PCI From patchwork Mon Oct 17 09:11:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3314 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347762wrs; Mon, 17 Oct 2022 02:18:22 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4lPQjIpGWxPeNtbk875WheKorNTsZ/6TiyI9hwl9zU8T74kncoQa8nJtQBLBn82NT84aHF X-Received: by 2002:aa7:951c:0:b0:562:ca32:3d3f with SMTP id b28-20020aa7951c000000b00562ca323d3fmr11460757pfp.33.1665998302452; Mon, 17 Oct 2022 02:18:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998302; cv=none; d=google.com; s=arc-20160816; b=Cc+iEPJru0lS22wd1dTkvAfFZeDlvvxq5iWkk6844/A5onWJdqryfug++i6KO5JWpF R4luKfmlK3s57GPiP+gbmof7kI0vKQMCEcnCcE48yurv8euFELN1riZNYDXQPB3z96om tFPfNJu75xLTn5vZpxLal1bcAiWnOKS0o3lcn0ow42qP5X1AecKhihb0ikfeNmYD4jQV e6UxilsiF9bpkzFb4cyz9E/HkRv0R+ztZwoDDNwpxC4yeA4MfkAr9ZgZ7m/4VEaO0np7 ttsBkCvT8i9PPeOx7aw1BKIwaqDTzH/JTiLb3a+YZQ8SzZuBiVfrlz5bR9TOJPiF05eT awrA== 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=4IgPegljF0RLQpEgdiqez/xPme+wwmfVw0dJ4ckzbm8=; b=jaC3j3tX9YlI9/pEAKJJqanRMFV/i/IP/VwwbERgVqpUr7LGxKvvMAKt3y7vPWDgId Rv+rzCReO2ANLHDBuF0O3oeJSbnyhQxbCgQa/9b/8fYW/SUV+WJfqa2Dn58ZBAD79mC9 Eder5VoP4pZSGK7YJT61Dk+jCBqu1xxov5H040pd7gu0jfBI6ijAPNeZNCHw/6CUguo+ dWc6ZUmoidG3tEnUMKXt1ht7PDLHMYrnSvkpyC62+Nmw3OehL++zLMH3GzkWiGyMH0IT ZDwk5opiM2A0D62Dbp3bya5Rfmc9BSuxBaJcfsWPhp3luBv0blnHpZabU787ViKGNAVv WSpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=hIiZVFf7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h17-20020a170902f55100b0016a6381f70esi12715915plf.42.2022.10.17.02.17.56; Mon, 17 Oct 2022 02:18:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=hIiZVFf7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230212AbiJQJNs (ORCPT + 99 others); Mon, 17 Oct 2022 05:13:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60574 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231163AbiJQJM7 (ORCPT ); Mon, 17 Oct 2022 05:12:59 -0400 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10AAA476D0; Mon, 17 Oct 2022 02:12:35 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id a5-20020a17090aa50500b002008eeb040eso12359125pjq.1; Mon, 17 Oct 2022 02:12:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=4IgPegljF0RLQpEgdiqez/xPme+wwmfVw0dJ4ckzbm8=; b=hIiZVFf7GdqW6t84DortDCZDVtFUxz4wxQxkivoQ3s80sSmxZm6JW4SCcHerHpOfaH ZSCKv2I+Pb+tAK6ikGz0ozY2OYjQox/0IRYsk5zMl9e4bPCe0so/Qbb2jIxkKnIAFbhv +1lYRY79u/pAvojVJ/SQyBld1Xp94lfJsLXmp+o2EE9I2XoAsEikx7Gz95BC9Eh7+sRi 1BvfnJuBq0aKUHcnJ9nZ8L1aUa5VX5Xz+4praUOTRJWXH6JF/aR+tYb56MNX9Liw32Gb XE5QjU4elFzJ1qbqIW55mHqImNj436LFSJO3EuCQoH9CnrAH7hLxOfNmZodkV+0/EGJw xNNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=4IgPegljF0RLQpEgdiqez/xPme+wwmfVw0dJ4ckzbm8=; b=r3rqmX/10fixYqFX00/MllEr0bbufiGG5Tt+mdC56EBSJQws1HQUzbSpUEerL/5Oru tyf1xJJ1K/J/BgFooB64dgjh1heZX1zsbUrFyqJ9RtGKtJx1nZD9WGyjcvTP/ZLVss85 v//+SnLYPtn98p8oN2dKLzdlvzFyoxCCrQ73pg4z1zvUQMF92P4wlLtPQ6FkxphFz2uW EOV3ZnfzcyaIuKbDLdEMPRQ2m88hV73bTCMbh5P4FN5c8t7e4ewN4wvqpVrFg25StZp0 zHid5lDbZ3hed37SAuTrdPj5t5UkSNjxu8r1g08gyIVRBC6GDuZluGViuBkt6CK8oyk3 YdBQ== X-Gm-Message-State: ACrzQf2mHhr2Vwe9E2HE3mvVnTmgTxzirh9b2eWnV9kwBHMWLqhI2C5p WguVqrmqQrnGpwM57D8TXeA= X-Received: by 2002:a17:903:2d1:b0:183:2b26:575d with SMTP id s17-20020a17090302d100b001832b26575dmr11085196plk.77.1665997954727; Mon, 17 Oct 2022 02:12:34 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:34 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 08/26] mmc: sdhci: add UHS-II related definitions in headers Date: Mon, 17 Oct 2022 17:11:35 +0800 Message-Id: <20221017091153.454873-9-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,UPPERCASE_50_75 autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925835741165129?= X-GMAIL-MSGID: =?utf-8?q?1746925835741165129?= Add UHS-II related definitions in shdci.h and sdhci-uhs2.h. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.h | 210 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.h | 73 +++++++++++- 2 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 drivers/mmc/host/sdhci-uhs2.h diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h new file mode 100644 index 000000000000..5610affebdf3 --- /dev/null +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * linux/drivers/mmc/host/sdhci-uhs2.h - Secure Digital Host Controller + * Interface driver + * + * Header file for Host Controller UHS2 related registers and I/O accessors. + * + * Copyright (C) 2014 Intel Corp, All Rights Reserved. + */ +#ifndef __SDHCI_UHS2_H +#define __SDHCI_UHS2_H + +#include + +/* + * UHS-II Controller registers + * 0x74 preset in sdhci.h + * 0x80 + * 0x84-0xB4 + * 0xB8-0xCF + * 0xE0-0xE7 + */ +/* UHS2 */ +#define SDHCI_UHS2_BLOCK_SIZE 0x80 +#define SDHCI_UHS2_MAKE_BLKSZ(dma, blksz) \ + ((((dma) & 0x7) << 12) | ((blksz) & 0xFFF)) + +#define SDHCI_UHS2_BLOCK_COUNT 0x84 + +#define SDHCI_UHS2_CMD_PACKET 0x88 +#define SDHCI_UHS2_CMD_PACK_MAX_LEN 20 + +#define SDHCI_UHS2_TRANS_MODE 0x9C +#define SDHCI_UHS2_TRNS_DMA BIT(0) +#define SDHCI_UHS2_TRNS_BLK_CNT_EN BIT(1) +#define SDHCI_UHS2_TRNS_DATA_TRNS_WRT BIT(4) +#define SDHCI_UHS2_TRNS_BLK_BYTE_MODE BIT(5) +#define SDHCI_UHS2_TRNS_RES_R5 BIT(6) +#define SDHCI_UHS2_TRNS_RES_ERR_CHECK_EN BIT(7) +#define SDHCI_UHS2_TRNS_RES_INT_DIS BIT(8) +#define SDHCI_UHS2_TRNS_WAIT_EBSY BIT(14) +#define SDHCI_UHS2_TRNS_2L_HD BIT(15) + +#define SDHCI_UHS2_COMMAND 0x9E +#define SDHCI_UHS2_COMMAND_SUB_CMD 0x0004 +#define SDHCI_UHS2_COMMAND_DATA 0x0020 +#define SDHCI_UHS2_COMMAND_TRNS_ABORT 0x0040 +#define SDHCI_UHS2_COMMAND_CMD12 0x0080 +#define SDHCI_UHS2_COMMAND_DORMANT 0x00C0 +#define SDHCI_UHS2_COMMAND_PACK_LEN_MASK GENMASK(12, 8) +#define SDHCI_UHS2_COMMAND_PACK_LEN_SHIFT 8 + +#define SDHCI_UHS2_RESPONSE 0xA0 +#define SDHCI_UHS2_RESPONSE_MAX_LEN 20 + +#define SDHCI_UHS2_MSG_SELECT 0xB4 +#define SDHCI_UHS2_MSG_SELECT_CURR 0x0 +#define SDHCI_UHS2_MSG_SELECT_ONE 0x1 +#define SDHCI_UHS2_MSG_SELECT_TWO 0x2 +#define SDHCI_UHS2_MSG_SELECT_THREE 0x3 + +#define SDHCI_UHS2_MSG 0xB8 + +#define SDHCI_UHS2_DEV_INT_STATUS 0xBC + +#define SDHCI_UHS2_DEV_SELECT 0xBE +#define SDHCI_UHS2_DEV_SELECT_DEV_SEL_MASK GENMASK(3, 0) +#define SDHCI_UHS2_DEV_SELECT_INT_MSG_EN BIT(7) + +#define SDHCI_UHS2_DEV_INT_CODE 0xBF + +#define SDHCI_UHS2_SW_RESET 0xC0 +#define SDHCI_UHS2_SW_RESET_FULL 0x0001 +#define SDHCI_UHS2_SW_RESET_SD 0x0002 + +#define SDHCI_UHS2_TIMER_CTRL 0xC2 +#define SDHCI_UHS2_TIMER_CTRL_DEADLOCK_SHIFT 4 + +#define SDHCI_UHS2_ERR_INT_STATUS 0xC4 +#define SDHCI_UHS2_ERR_INT_STATUS_EN 0xC8 +#define SDHCI_UHS2_ERR_INT_SIG_EN 0xCC +#define SDHCI_UHS2_ERR_INT_STATUS_HEADER BIT(0) +#define SDHCI_UHS2_ERR_INT_STATUS_RES BIT(1) +#define SDHCI_UHS2_ERR_INT_STATUS_RETRY_EXP BIT(2) +#define SDHCI_UHS2_ERR_INT_STATUS_CRC BIT(3) +#define SDHCI_UHS2_ERR_INT_STATUS_FRAME BIT(4) +#define SDHCI_UHS2_ERR_INT_STATUS_TID BIT(5) +#define SDHCI_UHS2_ERR_INT_STATUS_UNRECOVER BIT(7) +#define SDHCI_UHS2_ERR_INT_STATUS_EBUSY BIT(8) +#define SDHCI_UHS2_ERR_INT_STATUS_ADMA BIT(15) +#define SDHCI_UHS2_ERR_INT_STATUS_RES_TIMEOUT BIT(16) +#define SDHCI_UHS2_ERR_INT_STATUS_DEADLOCK_TIMEOUT BIT(17) +#define SDHCI_UHS2_ERR_INT_STATUS_VENDOR BIT(27) +#define SDHCI_UHS2_ERR_INT_STATUS_MASK \ + (SDHCI_UHS2_ERR_INT_STATUS_HEADER | \ + SDHCI_UHS2_ERR_INT_STATUS_RES | \ + SDHCI_UHS2_ERR_INT_STATUS_RETRY_EXP | \ + SDHCI_UHS2_ERR_INT_STATUS_CRC | \ + SDHCI_UHS2_ERR_INT_STATUS_FRAME | \ + SDHCI_UHS2_ERR_INT_STATUS_TID | \ + SDHCI_UHS2_ERR_INT_STATUS_UNRECOVER | \ + SDHCI_UHS2_ERR_INT_STATUS_EBUSY | \ + SDHCI_UHS2_ERR_INT_STATUS_ADMA | \ + SDHCI_UHS2_ERR_INT_STATUS_RES_TIMEOUT | \ + SDHCI_UHS2_ERR_INT_STATUS_DEADLOCK_TIMEOUT) +#define SDHCI_UHS2_ERR_INT_STATUS_CMD_MASK \ + (SDHCI_UHS2_ERR_INT_STATUS_HEADER | \ + SDHCI_UHS2_ERR_INT_STATUS_RES | \ + SDHCI_UHS2_ERR_INT_STATUS_FRAME | \ + SDHCI_UHS2_ERR_INT_STATUS_TID | \ + SDHCI_UHS2_ERR_INT_STATUS_RES_TIMEOUT) +/* CRC Error occurs during a packet receiving */ +#define SDHCI_UHS2_ERR_INT_STATUS_DATA_MASK \ + (SDHCI_UHS2_ERR_INT_STATUS_RETRY_EXP | \ + SDHCI_UHS2_ERR_INT_STATUS_CRC | \ + SDHCI_UHS2_ERR_INT_STATUS_UNRECOVER | \ + SDHCI_UHS2_ERR_INT_STATUS_EBUSY | \ + SDHCI_UHS2_ERR_INT_STATUS_ADMA | \ + SDHCI_UHS2_ERR_INT_STATUS_DEADLOCK_TIMEOUT) + +#define SDHCI_UHS2_SET_PTR 0xE0 +#define SDHCI_UHS2_GEN_SET_POWER_LOW 0x0001 +#define SDHCI_UHS2_GEN_SET_N_LANES_POS 8 +#define SDHCI_UHS2_GEN_SET_2L_FD_HD 0x0 +#define SDHCI_UHS2_GEN_SET_2D1U_FD 0x2 +#define SDHCI_UHS2_GEN_SET_1D2U_FD 0x3 +#define SDHCI_UHS2_GEN_SET_2D2U_FD 0x4 + +#define SDHCI_UHS2_PHY_SET_SPEED_POS 6 +#define SDHCI_UHS2_PHY_SET_HIBER_EN BIT(12) +#define SDHCI_UHS2_PHY_SET_N_LSS_SYN_MASK GENMASK(19, 16) +#define SDHCI_UHS2_PHY_SET_N_LSS_SYN_POS 16 +#define SDHCI_UHS2_PHY_SET_N_LSS_DIR_MASK GENMASK(23, 20) +#define SDHCI_UHS2_PHY_SET_N_LSS_DIR_POS 20 + +#define SDHCI_UHS2_TRAN_SET_N_FCU_MASK GENMASK(15, 8) +#define SDHCI_UHS2_TRAN_SET_N_FCU_POS 8 +#define SDHCI_UHS2_TRAN_SET_RETRY_CNT_MASK GENMASK(17, 16) +#define SDHCI_UHS2_TRAN_SET_RETRY_CNT_POS 16 + +#define SDHCI_UHS2_TRAN_SET_1_N_DAT_GAP_MASK GENMASK(7, 0) + +#define SDHCI_UHS2_HOST_CAPS_PTR 0xE2 +#define SDHCI_UHS2_HOST_CAPS_GEN_OFFSET 0 +#define SDHCI_UHS2_HOST_CAPS_GEN_DAP_MASK GENMASK(3, 0) +#define SDHCI_UHS2_HOST_CAPS_GEN_GAP_MASK GENMASK(7, 4) +#define SDHCI_UHS2_HOST_CAPS_GEN_GAP(gap) ((gap) * 360) +#define SDHCI_UHS2_HOST_CAPS_GEN_GAP_SHIFT 4 +#define SDHCI_UHS2_HOST_CAPS_GEN_LANE_MASK GENMASK(13, 8) +#define SDHCI_UHS2_HOST_CAPS_GEN_LANE_SHIFT 8 +#define SDHCI_UHS2_HOST_CAPS_GEN_2L_HD_FD 1 +#define SDHCI_UHS2_HOST_CAPS_GEN_2D1U_FD 2 +#define SDHCI_UHS2_HOST_CAPS_GEN_1D2U_FD 4 +#define SDHCI_UHS2_HOST_CAPS_GEN_2D2U_FD 8 +#define SDHCI_UHS2_HOST_CAPS_GEN_ADDR_64 BIT(14) +#define SDHCI_UHS2_HOST_CAPS_GEN_BOOT BIT(15) +#define SDHCI_UHS2_HOST_CAPS_GEN_DEV_TYPE_MASK GENMASK(17, 16) +#define SDHCI_UHS2_HOST_CAPS_GEN_DEV_TYPE_SHIFT 16 +#define SDHCI_UHS2_HOST_CAPS_GEN_DEV_TYPE_RMV 0 +#define SDHCI_UHS2_HOST_CAPS_GEN_DEV_TYPE_EMB 1 +#define SDHCI_UHS2_HOST_CAPS_GEN_DEV_TYPE_EMB_RMV 2 +#define SDHCI_UHS2_HOST_CAPS_GEN_NUM_DEV_MASK GENMASK(21, 18) +#define SDHCI_UHS2_HOST_CAPS_GEN_NUM_DEV_SHIFT 18 +#define SDHCI_UHS2_HOST_CAPS_GEN_BUS_TOPO_MASK GENMASK(23, 22) +#define SDHCI_UHS2_HOST_CAPS_GEN_BUS_TOPO_SHIFT 22 +#define SDHCI_UHS2_HOST_CAPS_GEN_BUS_TOPO_P2P 0 +#define SDHCI_UHS2_HOST_CAPS_GEN_BUS_TOPO_RING 1 +#define SDHCI_UHS2_HOST_CAPS_GEN_BUS_TOPO_HUB 2 +#define SDHCI_UHS2_HOST_CAPS_GEN_BUS_TOPO_HUB_RING 3 + +#define SDHCI_UHS2_HOST_CAPS_PHY_OFFSET 4 +#define SDHCI_UHS2_HOST_CAPS_PHY_REV_MASK GENMASK(5, 0) +#define SDHCI_UHS2_HOST_CAPS_PHY_RANGE_MASK GENMASK(7, 6) +#define SDHCI_UHS2_HOST_CAPS_PHY_RANGE_SHIFT 6 +#define SDHCI_UHS2_HOST_CAPS_PHY_RANGE_A 0 +#define SDHCI_UHS2_HOST_CAPS_PHY_RANGE_B 1 +#define SDHCI_UHS2_HOST_CAPS_PHY_N_LSS_SYN_MASK GENMASK(19, 16) +#define SDHCI_UHS2_HOST_CAPS_PHY_N_LSS_SYN_SHIFT 16 +#define SDHCI_UHS2_HOST_CAPS_PHY_N_LSS_DIR_MASK GENMASK(23, 20) +#define SDHCI_UHS2_HOST_CAPS_PHY_N_LSS_DIR_SHIFT 20 +#define SDHCI_UHS2_HOST_CAPS_TRAN_OFFSET 8 +#define SDHCI_UHS2_HOST_CAPS_TRAN_LINK_REV_MASK GENMASK(5, 0) +#define SDHCI_UHS2_HOST_CAPS_TRAN_N_FCU_MASK GENMASK(15, 8) +#define SDHCI_UHS2_HOST_CAPS_TRAN_N_FCU_SHIFT 8 +#define SDHCI_UHS2_HOST_CAPS_TRAN_HOST_TYPE_MASK GENMASK(18, 16) +#define SDHCI_UHS2_HOST_CAPS_TRAN_HOST_TYPE_SHIFT 16 +#define SDHCI_UHS2_HOST_CAPS_TRAN_BLK_LEN_MASK GENMASK(31, 20) +#define SDHCI_UHS2_HOST_CAPS_TRAN_BLK_LEN_SHIFT 20 + +#define SDHCI_UHS2_HOST_CAPS_TRAN_1_OFFSET 12 +#define SDHCI_UHS2_HOST_CAPS_TRAN_1_N_DATA_GAP_MASK GENMASK(7, 0) + +#define SDHCI_UHS2_TEST_PTR 0xE4 +#define SDHCI_UHS2_TEST_ERR_HEADER BIT(0) +#define SDHCI_UHS2_TEST_ERR_RES BIT(1) +#define SDHCI_UHS2_TEST_ERR_RETRY_EXP BIT(2) +#define SDHCI_UHS2_TEST_ERR_CRC BIT(3) +#define SDHCI_UHS2_TEST_ERR_FRAME BIT(4) +#define SDHCI_UHS2_TEST_ERR_TID BIT(5) +#define SDHCI_UHS2_TEST_ERR_UNRECOVER BIT(7) +#define SDHCI_UHS2_TEST_ERR_EBUSY BIT(8) +#define SDHCI_UHS2_TEST_ERR_ADMA BIT(15) +#define SDHCI_UHS2_TEST_ERR_RES_TIMEOUT BIT(16) +#define SDHCI_UHS2_TEST_ERR_DEADLOCK_TIMEOUT BIT(17) +#define SDHCI_UHS2_TEST_ERR_VENDOR BIT(27) + +#define SDHCI_UHS2_EMBED_CTRL 0xE6 +#define SDHCI_UHS2_VENDOR 0xE8 + +#endif /* __SDHCI_UHS2_H */ diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 95a08f09df30..64c2d7e78e29 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -43,8 +43,27 @@ #define SDHCI_TRNS_READ 0x10 #define SDHCI_TRNS_MULTI 0x20 +/* + * Defined in Host Version 4.10. + * 1 - R5 (SDIO) + * 0 - R1 (Memory) + */ +#define SDHCI_TRNS_RES_TYPE 0x40 +#define SDHCI_TRNS_RES_ERR_CHECK 0x80 +#define SDHCI_TRNS_RES_INT_DIS 0x0100 + #define SDHCI_COMMAND 0x0E #define SDHCI_CMD_RESP_MASK 0x03 + +/* + * Host Version 4.10 adds this bit to distinguish a main command or + * sub command. + * CMD53(SDIO) - main command + * CMD52(SDIO) - sub command which doesn't have data block or doesn't + * indicate busy. + */ +#define SDHCI_CMD_SUB_CMD 0x04 + #define SDHCI_CMD_CRC 0x08 #define SDHCI_CMD_INDEX 0x10 #define SDHCI_CMD_DATA 0x20 @@ -60,11 +79,19 @@ #define SDHCI_RESPONSE 0x10 +#define SDHCI_RESPONSE_CM_TRAN_ABORT_OFFSET 0x10 +#define SDHCI_RESPONSE_CM_TRAN_ABORT_SIZE 4 +#define SDHCI_RESPONSE_SD_TRAN_ABORT_OFFSET 0x18 +#define SDHCI_RESPONSE_SD_TRAN_ABORT_SIZE 8 + #define SDHCI_BUFFER 0x20 #define SDHCI_PRESENT_STATE 0x24 #define SDHCI_CMD_INHIBIT 0x00000001 #define SDHCI_DATA_INHIBIT 0x00000002 + +#define SDHCI_DATA_HIGH_LVL_MASK 0x000000F0 + #define SDHCI_DOING_WRITE 0x00000100 #define SDHCI_DOING_READ 0x00000200 #define SDHCI_SPACE_AVAILABLE 0x00000400 @@ -80,6 +107,13 @@ #define SDHCI_DATA_0_LVL_MASK 0x00100000 #define SDHCI_CMD_LVL 0x01000000 +#define SDHCI_HOST_REGULATOR_STABLE 0x02000000 +#define SDHCI_CMD_NOT_ISSUE_ERR 0x08000000 +#define SDHCI_SUB_CMD_STATUS 0x10000000 +#define SDHCI_UHS2_IN_DORMANT_STATE 0x20000000 +#define SDHCI_UHS2_LANE_SYNC 0x40000000 +#define SDHCI_UHS2_IF_DETECT 0x80000000 + #define SDHCI_HOST_CONTROL 0x28 #define SDHCI_CTRL_LED 0x01 #define SDHCI_CTRL_4BITBUS 0x02 @@ -100,6 +134,11 @@ #define SDHCI_POWER_300 0x0C #define SDHCI_POWER_330 0x0E +/* VDD2 - UHS2 */ +#define SDHCI_VDD2_POWER_ON 0x10 +#define SDHCI_VDD2_POWER_180 0xA0 +#define SDHCI_VDD2_POWER_120 0x80 + #define SDHCI_BLOCK_GAP_CONTROL 0x2A #define SDHCI_WAKE_UP_CONTROL 0x2B @@ -110,7 +149,7 @@ #define SDHCI_CLOCK_CONTROL 0x2C #define SDHCI_DIVIDER_SHIFT 8 #define SDHCI_DIVIDER_HI_SHIFT 6 -#define SDHCI_DIV_MASK 0xFF +#define SDHCI_DIV_MASK 0xFF #define SDHCI_DIV_MASK_LEN 8 #define SDHCI_DIV_HI_MASK 0x300 #define SDHCI_PROG_CLOCK_MODE 0x0020 @@ -139,6 +178,10 @@ #define SDHCI_INT_CARD_REMOVE 0x00000080 #define SDHCI_INT_CARD_INT 0x00000100 #define SDHCI_INT_RETUNE 0x00001000 + +/* Host Version 4.10 */ +#define SDHCI_INT_FX_EVENT 0x00002000 + #define SDHCI_INT_CQE 0x00004000 #define SDHCI_INT_ERROR 0x00008000 #define SDHCI_INT_TIMEOUT 0x00010000 @@ -152,6 +195,9 @@ #define SDHCI_INT_AUTO_CMD_ERR 0x01000000 #define SDHCI_INT_ADMA_ERROR 0x02000000 +/* Host Version 4.0 */ +#define SDHCI_INT_RESPONSE_ERROR 0x08000000 + #define SDHCI_INT_NORMAL_MASK 0x00007FFF #define SDHCI_INT_ERROR_MASK 0xFFFF8000 @@ -178,6 +224,9 @@ #define SDHCI_AUTO_CMD_END_BIT 0x00000008 #define SDHCI_AUTO_CMD_INDEX 0x00000010 +/* Host Version 4.10 */ +#define SDHCI_ACMD_RESPONSE_ERROR 0x0020 + #define SDHCI_HOST_CONTROL2 0x3E #define SDHCI_CTRL_UHS_MASK 0x0007 #define SDHCI_CTRL_UHS_SDR12 0x0000 @@ -186,6 +235,7 @@ #define SDHCI_CTRL_UHS_SDR104 0x0003 #define SDHCI_CTRL_UHS_DDR50 0x0004 #define SDHCI_CTRL_HS400 0x0005 /* Non-standard */ +#define SDHCI_CTRL_UHS_2 0x0007 /* UHS-2 */ #define SDHCI_CTRL_VDD_180 0x0008 #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 #define SDHCI_CTRL_DRV_TYPE_B 0x0000 @@ -194,9 +244,12 @@ #define SDHCI_CTRL_DRV_TYPE_D 0x0030 #define SDHCI_CTRL_EXEC_TUNING 0x0040 #define SDHCI_CTRL_TUNED_CLK 0x0080 +#define SDHCI_CTRL_UHS2_INTERFACE_EN 0x0100 /* UHS-2 */ +#define SDHCI_CTRL_ADMA2_LEN_MODE 0x0400 #define SDHCI_CMD23_ENABLE 0x0800 #define SDHCI_CTRL_V4_MODE 0x1000 #define SDHCI_CTRL_64BIT_ADDR 0x2000 +#define SDHCI_CTRL_ASYNC_INT_EN 0x4000 #define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 #define SDHCI_CAPABILITIES 0x40 @@ -219,11 +272,13 @@ #define SDHCI_CAN_VDD_180 0x04000000 #define SDHCI_CAN_64BIT_V4 0x08000000 #define SDHCI_CAN_64BIT 0x10000000 +#define SDHCI_CAN_ASYNC_INT 0x20000000 #define SDHCI_CAPABILITIES_1 0x44 #define SDHCI_SUPPORT_SDR50 0x00000001 #define SDHCI_SUPPORT_SDR104 0x00000002 #define SDHCI_SUPPORT_DDR50 0x00000004 +#define SDHCI_SUPPORT_UHS2 0x00000008 /* UHS-2 support */ #define SDHCI_DRIVER_TYPE_A 0x00000010 #define SDHCI_DRIVER_TYPE_C 0x00000020 #define SDHCI_DRIVER_TYPE_D 0x00000040 @@ -232,19 +287,28 @@ #define SDHCI_RETUNING_MODE_MASK GENMASK(15, 14) #define SDHCI_CLOCK_MUL_MASK GENMASK(23, 16) #define SDHCI_CAN_DO_ADMA3 0x08000000 +#define SDHCI_SUPPORT_VDD2_180 0x10000000 /* UHS-2 1.8V VDD2 */ +#define SDHCI_RSVD_FOR_VDD2 0x20000000 /* Rsvd for future VDD2 */ #define SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */ #define SDHCI_MAX_CURRENT 0x48 +#define SDHCI_MAX_CURRENT_1 0x4C #define SDHCI_MAX_CURRENT_LIMIT GENMASK(7, 0) #define SDHCI_MAX_CURRENT_330_MASK GENMASK(7, 0) #define SDHCI_MAX_CURRENT_300_MASK GENMASK(15, 8) #define SDHCI_MAX_CURRENT_180_MASK GENMASK(23, 16) +#define SDHCI_MAX_CURRENT_VDD2_180_MASK GENMASK(7, 0) /* UHS2 */ #define SDHCI_MAX_CURRENT_MULTIPLIER 4 /* 4C-4F reserved for more max current */ #define SDHCI_SET_ACMD12_ERROR 0x50 +/* Host Version 4.10 */ +#define SDHCI_SET_ACMD_RESPONSE_ERROR 0x20 #define SDHCI_SET_INT_ERROR 0x52 +/* Host Version 4.10 */ +#define SDHCI_SET_INT_TUNING_ERROR 0x0400 +#define SDHCI_SET_INT_RESPONSE_ERROR 0x0800 #define SDHCI_ADMA_ERROR 0x54 @@ -262,10 +326,16 @@ #define SDHCI_PRESET_FOR_SDR104 0x6C #define SDHCI_PRESET_FOR_DDR50 0x6E #define SDHCI_PRESET_FOR_HS400 0x74 /* Non-standard */ + +/* TODO: 0x74 is used for UHS2 in 4.10. How about HS400? */ +/* UHS2 */ +#define SDHCI_PRESET_FOR_UHS2 0x74 #define SDHCI_PRESET_DRV_MASK GENMASK(15, 14) #define SDHCI_PRESET_CLKGEN_SEL BIT(10) #define SDHCI_PRESET_SDCLK_FREQ_MASK GENMASK(9, 0) +#define SDHCI_ADMA3_ADDRESS 0x78 + #define SDHCI_SLOT_INT_STATUS 0xFC #define SDHCI_HOST_VERSION 0xFE @@ -661,6 +731,7 @@ struct sdhci_ops { void (*request_done)(struct sdhci_host *host, struct mmc_request *mrq); void (*dump_vendor_regs)(struct sdhci_host *host); + void (*dump_uhs2_regs)(struct sdhci_host *host); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS From patchwork Mon Oct 17 09:11:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3310 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347528wrs; Mon, 17 Oct 2022 02:17:48 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5yBhX0i5NZANIphEvM3M5j+ka8X99YTQT7t53WDfOe4GetuepnpCQeV26dIXrhT7712njx X-Received: by 2002:a17:90b:224d:b0:20d:8828:3051 with SMTP id hk13-20020a17090b224d00b0020d88283051mr12410564pjb.89.1665998268332; Mon, 17 Oct 2022 02:17:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998268; cv=none; d=google.com; s=arc-20160816; b=l4nBkZkOkd7h19MHLLO5QZqeT7/D8hoiRhkwH6WtnoHpdnU5jfZ9XA9xkxUTtKX1PG WILyoDlp/KIT0oOFPzECTe/YsuTBdkXulmJ4Ugvq4rGYLpdGrVB86iP569LXjje4J6QU H2opvfZj8w8bmUTwJk8sr2W5/k/RuXmc/SUKOHVHu3F7GswPUUznCefJ3IRYZAhN9tr5 FfWqDNuRtMRU3giWsr6w5u9UqAxGk5EAR8is9CyoZcqCiigysFQh43Ve4XTKiwA31Qu7 FGoUJAMUZHH+eCqk8Cl6mleWNQY2VVbF5Owxa7BQHuXxlFudK5xuD6a/mqLjN4dwufSd ovgA== 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=VbX3cykqxMRH6bMF8u/S2MS3pREEeejjqIbnD23P3/8=; b=i0LBFeOX7tRDV1gy8FhU5gQsPY8H15BbjKW8BsdUtRLGnFO4BOmV3C3jZDam3wyafU 1eUDGfNjXl034t2EkvhZ4s8hxReiT+wbphWFAF4oni3tJ/5b0YFSgxMRVJGbz0Xsk2Mp HIM6rh/O2SBbXjG1aFGeULjj677NhOk7z1VFooQUrxfKl6fG0UMFFUiZFUwvr73A3pRK N5skLDqAn+VqG+AMbbm2VoRlRQ6AKngdwESWcsg+VyUCP8v4gyatfn5C+SK24OiKrOam 7tafFNbiEwSGsVo0cto7I35nmq7nj567u18KsvkxdO6qwGHXBGsx66qZPv5EpAk7DDuF 1xog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="lJ/fZTzQ"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n18-20020a170902e55200b0016d9c8479b5si13301109plf.344.2022.10.17.02.17.27; Mon, 17 Oct 2022 02:17:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="lJ/fZTzQ"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230140AbiJQJNm (ORCPT + 99 others); Mon, 17 Oct 2022 05:13:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230523AbiJQJM6 (ORCPT ); Mon, 17 Oct 2022 05:12:58 -0400 Received: from mail-pg1-x531.google.com (mail-pg1-x531.google.com [IPv6:2607:f8b0:4864:20::531]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2E6204B9B1; Mon, 17 Oct 2022 02:12:39 -0700 (PDT) Received: by mail-pg1-x531.google.com with SMTP id 129so9918590pgc.5; Mon, 17 Oct 2022 02:12:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=VbX3cykqxMRH6bMF8u/S2MS3pREEeejjqIbnD23P3/8=; b=lJ/fZTzQhpKNFK5Y7vzvy2IxjVPNTZMxXdoskyurdQjVFWGdRta3keIlfdihKlJehB rltXVx7xJ8ODKeRPTv5xP37gLaXqWDUhgpOkTVJsJwzZofzpJy4J2cax+PcqfUUCh1vA c5fcTQ39cC1mffHfmrXj7kFd8lqNKaMWqlucqhVAUw4IRjj67T4boYFCK0iI8SlVsaaa B3O7YqNfvt/KLdUnPXnMU/6EN6c8e3F+Vf0/kzlel3tEZQwKgf07sxCWHxhDHA2ZF0y3 yqZ+2bH4UzUkuKwhVwnYdzVlUDK0kD4jxiy9IqWMxtHzTzWgBrnxO1+zQWjcni8/Up2i JO1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=VbX3cykqxMRH6bMF8u/S2MS3pREEeejjqIbnD23P3/8=; b=tZ/ocHWY2Uy5js0PpI+FoHTC+ubutHdupI7z41XJyvS6Si5df4E9oszEai1N7KJEBI MnC0OUDVcUTV6PXXyzIJYhD/HSuEkva7+Tw75yMgYMZ27bS5d5EuQOe9fbLU+lS+IeRd 9fqLGFpv5PJSIpKj7wdTJvUkE/JPnxWayFiVfV1isWs5O3p56CJ//lvm9f2FGnfuQ5m2 A0vAOfmEUMm6KQgC72GtHQMGMMA+YRVBhrL88b8fRP8JgNopbBJFkLbXOsmt7OltN4WU rrji0JSTi+1fXU3UG2sCvK6z0Se48jP9ig2oY01sXYgW89cRKuhZJMKqTi+WtBtXEriY TZyQ== X-Gm-Message-State: ACrzQf0TC8+BDNUt5E4TYmUKIwk+vnDNGwDB9PG3kKWRalX0Z6gNn9S6 12A8EkIr5f1h+RGHJbPQ848= X-Received: by 2002:a05:6a00:2906:b0:52a:bc7f:f801 with SMTP id cg6-20020a056a00290600b0052abc7ff801mr11884010pfb.49.1665997957479; Mon, 17 Oct 2022 02:12:37 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:37 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 09/26] mmc: sdhci: add UHS-II module Date: Mon, 17 Oct 2022 17:11:36 +0800 Message-Id: <20221017091153.454873-10-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925800144979858?= X-GMAIL-MSGID: =?utf-8?q?1746925800144979858?= From: AKASHI Takahiro This patch adds sdhci-uhs2.c as a module for UHS-II support. This is a skelton for further development in this patch series. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro --- drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-uhs2.c | 46 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 drivers/mmc/host/sdhci-uhs2.c diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 4e4ceb32c4b4..c4ae7c6d9c04 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_MXC) += mxcmmc.o obj-$(CONFIG_MMC_MXS) += mxs-mmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o +obj-$(CONFIG_MMC_SDHCI_UHS2) += sdhci-uhs2.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o sdhci-pci-y += sdhci-pci-core.o sdhci-pci-o2micro.o sdhci-pci-arasan.o \ sdhci-pci-dwc-mshc.o sdhci-pci-gli.o diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c new file mode 100644 index 000000000000..f29d3a4ed43c --- /dev/null +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * linux/drivers/mmc/host/sdhci_uhs2.c - Secure Digital Host Controller + * Interface driver + * + * Copyright (C) 2014 Intel Corp, All Rights Reserved. + * Copyright (C) 2020 Genesys Logic, Inc. + * Authors: Ben Chuang + * Copyright (C) 2020 Linaro Limited + * Author: AKASHI Takahiro + */ + +#include + +#include "sdhci.h" +#include "sdhci-uhs2.h" + +#define DRIVER_NAME "sdhci_uhs2" +#define DBG(f, x...) \ + pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x) + +/*****************************************************************************\ + * * + * Driver init/exit * + * * +\*****************************************************************************/ + +static int sdhci_uhs2_host_ops_init(struct sdhci_host *host) +{ + return 0; +} + +static int __init sdhci_uhs2_mod_init(void) +{ + return 0; +} +module_init(sdhci_uhs2_mod_init); + +static void __exit sdhci_uhs2_exit(void) +{ +} +module_exit(sdhci_uhs2_exit); + +MODULE_AUTHOR("Intel, Genesys Logic, Linaro"); +MODULE_DESCRIPTION("MMC UHS-II Support"); +MODULE_LICENSE("GPL v2"); From patchwork Mon Oct 17 09:11:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3309 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347522wrs; Mon, 17 Oct 2022 02:17:47 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6B6++0ObSpm+8e8M/eCwYV0z+X6pDtdjV0jB73cpr4YFdDN3GNV/EpU1lRRBP7dtdxlqq1 X-Received: by 2002:aa7:9152:0:b0:565:895b:e524 with SMTP id 18-20020aa79152000000b00565895be524mr11610426pfi.85.1665998267589; Mon, 17 Oct 2022 02:17:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998267; cv=none; d=google.com; s=arc-20160816; b=UbdUitRz7juXeTv7MZaxFR9lXwXEVbRlMoxQEWEQTSYOcKseCA8bH6UHg3/VU25sRQ dvb7Wdx/9nZhwyk8/VlyUhpBFXyNFueF++DTCKxzn7Si0bDSl015ravjI9YCm//16795 Yynw9PMFC46Oql3la/UkJsmYBLArPoz4teXSy8YTCDilZDSNgA99OpnetfeYEYGy5XFe qff+BuM8H+3ftuxT89WYn90NPpNfIF6e260lc1BIQ2LywGpokXi2am53qIvXiLuFp4sb Y6oOT7WYKF19X3dGC5+EqEDVQHiz4TDBDfKBbsfrXFdDlig8KFmC8QVFM+7iSRF8YG0f r2Lg== 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=fOTNf+6VnP/vTvWfdvOpxW6WQddN6b+2+N82o5+rT0M=; b=vp+t2AzVFObCisGkZXu7cEtHk8Q6eQelwY3yFNnBy6d71D0/LnmEbZGWZP7zKhMJXM P68bkM0hUpBNggoh/qwm+m50HLIDzJvd+DW6pzm5Dw5ibdvLToRMKLJPUd63XWk+hd+m JGmyFj9J+9OpfilrUYpicFXtR1BFb1ZnxxFtbUa0w7qRqAD35WFSRvxu+uiT8vTDMsKc VkrPYcs2LK38Xl6QSxItVTSi++dXPcSMTSzFR/L7IYTLzAo6TSkelVfm0fTVg68Nkdwm px56Ix5AQPJa3dIAHDCDQvW0Zw4YaJRClE0BzT2QjZlw/1D7UldCSvHV0BFKRIe8N+cx XaGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Vc0eBh7z; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p8-20020a170902a40800b00178297641d4si10425318plq.287.2022.10.17.02.17.34; Mon, 17 Oct 2022 02:17:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Vc0eBh7z; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231206AbiJQJOF (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33296 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231209AbiJQJNY (ORCPT ); Mon, 17 Oct 2022 05:13:24 -0400 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B67694C602; Mon, 17 Oct 2022 02:12:47 -0700 (PDT) Received: by mail-pf1-x430.google.com with SMTP id y1so10527246pfr.3; Mon, 17 Oct 2022 02:12:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=fOTNf+6VnP/vTvWfdvOpxW6WQddN6b+2+N82o5+rT0M=; b=Vc0eBh7zxohAwx3v92L+He6gpFrm3iWDLS8sKZWmdc+BHfJj7bci+Bfk7lMNXNA2Ec q/Y0dztPRaBWvGZKAVQQe/wqu5K9uJdXhtAb4S75J1XiC8jdYP+caLBQS5AiOLW5Ajlv blhC5/2nfZeEa1Qgdy40pihEv8lNnHGaAIGuOe0k+MKd95wEEgXdYpr3tUk58KOQueVf 7UrDtnqVEOcsSsaFB/ZsyQvg6gSpU8/4LBc2TMQMY+StPJOZNUYKXEAHPngz5iC9sDHb yFB5PsMG7QelqIySWQ368GjTXcC8dEkyQMUdXdVxW8Gtt5NUEL4cJD3hjh/lQzuYMWlu Ug7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=fOTNf+6VnP/vTvWfdvOpxW6WQddN6b+2+N82o5+rT0M=; b=q2uyOwLdJ/YAmZYoCNYCeNacXdlFC7BnPq9dMGpQu3iYcRVW2L0abIwrgvxnJLNLe8 3RX5RDOjR4oJK45V4O9zcNXq9zc95LOo+N1La8z5scByMPokyWGjuwGESbWJt3mlfrra d8LFk7GhgXRknSmCmL0KL2FI9yGboEDY3JtSAdSXIxPX9OpQ3z9GiSPRjl1YcU+obmiC OemKE3ki2vNKyWHHoevH89powmgbHCwM8zjO5RRgyBE4WDsLHsPtM7myifD0vtJ5yYOy XP5dB4Jq3itIifjSrogxs79/wMsu6DEN7GMlGxzu6i1Y0N6RJw8ngooiqJOgmVuRgeKn parQ== X-Gm-Message-State: ACrzQf27cvW9Stey+rQZVe9Dv9iXaUjMxY/GZGE135KWtDMjQ6h3zw2Z jTxjK6MAS3BAho80bRRgDln1PgbL56I= X-Received: by 2002:a05:6a00:c91:b0:562:aa06:2848 with SMTP id a17-20020a056a000c9100b00562aa062848mr11915432pfv.2.1665997960487; Mon, 17 Oct 2022 02:12:40 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:40 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 10/26] mmc: sdhci-uhs2: dump UHS-II registers Date: Mon, 17 Oct 2022 17:11:37 +0800 Message-Id: <20221017091153.454873-11-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925799749697748?= X-GMAIL-MSGID: =?utf-8?q?1746925799749697748?= From: AKASHI Takahiro Dump UHS-II specific registers, if available, in sdhci_dumpregs() for informative/debugging use. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro --- drivers/mmc/host/sdhci-uhs2.c | 30 ++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 4 ++++ drivers/mmc/host/sdhci.c | 3 +++ 3 files changed, 37 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index f29d3a4ed43c..08905ed081fb 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -18,6 +18,36 @@ #define DRIVER_NAME "sdhci_uhs2" #define DBG(f, x...) \ pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x) +#define SDHCI_UHS2_DUMP(f, x...) \ + pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x) + +void sdhci_uhs2_dump_regs(struct sdhci_host *host) +{ + if (!host->mmc || !(host->mmc->flags & MMC_UHS2_SUPPORT)) + return; + + SDHCI_UHS2_DUMP("==================== UHS2 ==================\n"); + SDHCI_UHS2_DUMP("Blk Size: 0x%08x | Blk Cnt: 0x%08x\n", + sdhci_readw(host, SDHCI_UHS2_BLOCK_SIZE), + sdhci_readl(host, SDHCI_UHS2_BLOCK_COUNT)); + SDHCI_UHS2_DUMP("Cmd: 0x%08x | Trn mode: 0x%08x\n", + sdhci_readw(host, SDHCI_UHS2_COMMAND), + sdhci_readw(host, SDHCI_UHS2_TRANS_MODE)); + SDHCI_UHS2_DUMP("Int Stat: 0x%08x | Dev Sel : 0x%08x\n", + sdhci_readw(host, SDHCI_UHS2_DEV_INT_STATUS), + sdhci_readb(host, SDHCI_UHS2_DEV_SELECT)); + SDHCI_UHS2_DUMP("Dev Int Code: 0x%08x\n", + sdhci_readb(host, SDHCI_UHS2_DEV_INT_CODE)); + SDHCI_UHS2_DUMP("Reset: 0x%08x | Timer: 0x%08x\n", + sdhci_readw(host, SDHCI_UHS2_SW_RESET), + sdhci_readw(host, SDHCI_UHS2_TIMER_CTRL)); + SDHCI_UHS2_DUMP("ErrInt: 0x%08x | ErrIntEn: 0x%08x\n", + sdhci_readl(host, SDHCI_UHS2_ERR_INT_STATUS), + sdhci_readl(host, SDHCI_UHS2_ERR_INT_STATUS_EN)); + SDHCI_UHS2_DUMP("ErrSigEn: 0x%08x\n", + sdhci_readl(host, SDHCI_UHS2_ERR_INT_SIG_EN)); +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); /*****************************************************************************\ * * diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index 5610affebdf3..afdb05d6056b 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -207,4 +207,8 @@ #define SDHCI_UHS2_EMBED_CTRL 0xE6 #define SDHCI_UHS2_VENDOR 0xE8 +struct sdhci_host; + +void sdhci_uhs2_dump_regs(struct sdhci_host *host); + #endif /* __SDHCI_UHS2_H */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 251172890af7..4434838475bf 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -110,6 +110,9 @@ void sdhci_dumpregs(struct sdhci_host *host) } } + if (host->ops->dump_uhs2_regs) + host->ops->dump_uhs2_regs(host); + if (host->ops->dump_vendor_regs) host->ops->dump_vendor_regs(host); From patchwork Mon Oct 17 09:11:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3325 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348795wrs; Mon, 17 Oct 2022 02:21:51 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6+4WcnBYbZyI0gwJgpHkTYx3UMUX5kpFT1sStl1oEaZwnJbL6YWjbBTlQkVdS2yID2Xuux X-Received: by 2002:aa7:8b13:0:b0:55f:69de:d17c with SMTP id f19-20020aa78b13000000b0055f69ded17cmr11522322pfd.20.1665998511034; Mon, 17 Oct 2022 02:21:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998511; cv=none; d=google.com; s=arc-20160816; b=VTIz0TGp9Ya9RQ3vO85KxhR6NAlAzdz/Dz/iK+yJYKn2zPgNPHEq0Pi+4ATBVpdcLC MykAe2hGg3CYdPYbV5IDm5hiHe645oAkKe/ir3sGe6lHtZzSek5np9K8EId9qIRZgEeJ HaGWbOL3eYRkEOIVoWptk1YfTjJFejXaxaPJuugAPY2M0HVLmMQBd4uC1OebNMwiDNAx usY3wXmB8tybQstBCxMedHSMkV/Fm47VF0b5NbeL8C6hQdAiTWgWuJ3PxMWi32F7EuWf 4WrC0o61cMxZxjC8dudqrEGIZOIEaWXy5ylLWazthkMreucuIp1AYMlPz42qjuBAxdOz dNcA== 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=cBtBje6jwxU6FZyo8pZG+tr7pQu93ik7L6cy2pElzBc=; b=DssCN3kdshs+Xp9Wsg72qnfL0tbsU/74h7JNlyvJX5QXbXIIZszaxpSfERkB+1KVRy t5m+IK61T+dPdMt5FsWdw/x0DP5kvNqoNQ1Lsbhh52cJ3FcD6CMJhlOzO1is8j77RJ5g /tB7f24CHSvQ0OJGZx3tT3bMlXkBEDyz3nbPks/t1O/Q0obZ4J/flaFZ1XC64clMqm5G z+UsIOZ+r8guU1dIx6kXYGDWnsKuSFHq5iLMvxNyXBgXoH/bbrOxieF0fZJ/w+cfR8Du ijosLczmhtq0G8kMjVYTLj+HLorGEbZunyXXGE3bUCIm9RPtCPri/KLC3c8ZcI8lcm94 CIhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=UxnETf7M; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o5-20020a1709026b0500b00184c33ddeb8si10677703plk.23.2022.10.17.02.21.37; Mon, 17 Oct 2022 02:21:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=UxnETf7M; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231195AbiJQJPc (ORCPT + 99 others); Mon, 17 Oct 2022 05:15:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231165AbiJQJNO (ORCPT ); Mon, 17 Oct 2022 05:13:14 -0400 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7C5F4C638; Mon, 17 Oct 2022 02:12:52 -0700 (PDT) Received: by mail-pf1-x42d.google.com with SMTP id p14so10531578pfq.5; Mon, 17 Oct 2022 02:12:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=cBtBje6jwxU6FZyo8pZG+tr7pQu93ik7L6cy2pElzBc=; b=UxnETf7MYzw7P6abezqdTGQS5YZFycb+b52bdAKmN5xRNfjZs/l/cCgb1ivMwq2flM jjtf3GABSfMXd/Q2DM63NHfk9wwRbQ1jSQXXXZc+cQjcSVcJ8DO7jFc6pcNh2XEtcWKG UI+M4SMCGZp65QIKx4m5j3BmPF4+sWLlIrKXoNCdal20+8OadRHtnLTfcrchRgevZSHi HR4BQxVtR0xglRUwU9lkiS9ehGCeS90Dmvd4YYlt6EISU6GDjOAkYcRwGGjlqweiEcxU 66vL3RhKVK1kPpkmY6yoe1TA+VOUtahjX+6soXHZB1djuCJlsRsolV0OEZUpShaxdKv1 UowA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=cBtBje6jwxU6FZyo8pZG+tr7pQu93ik7L6cy2pElzBc=; b=UlMiFOkcEp6wiVJX7gWl7w//9YyxK/f6DcFq15FcKD84VZdbmH2W9CZnIENZ0wiOtw MyBtQpaOt2dRqW1TgqeGPZD9yhoyCOmratSB2t0GXVK77H5rP0VpzYXv131on1DHChdU Zz2IfI4dyaWlANbLbHnRGWOXT6t4ZkcAQLdnIpaZuNu42GyJc1yap1k7mAioi99UOs0w MdWSTHzUwQPzIj0llWGw/VwJk2Nm4GBhuy3x4z5/TTfTc4oN2EGHG4XHqoQsvf0uLuSa Rg0lnMOL+eh80QWYIS+ouS89QMnX5/SeDcXRzo2Z+5JVvlQZNH2PRYobuAX0X1NL7sy+ vZaw== X-Gm-Message-State: ACrzQf0CdwOI1gYJjFV0vSKp2CT5o2BT2yIhIQvZYZV7P28+a9KULM2p xnSIE0twdu5AmCGx76rVcQA= X-Received: by 2002:a63:187:0:b0:43b:cf3c:c64d with SMTP id 129-20020a630187000000b0043bcf3cc64dmr9895772pgb.359.1665997963702; Mon, 17 Oct 2022 02:12:43 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:43 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 11/26] mmc: sdhci-uhs2: add reset function and uhs2_mode function Date: Mon, 17 Oct 2022 17:11:38 +0800 Message-Id: <20221017091153.454873-12-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746926054411103347?= X-GMAIL-MSGID: =?utf-8?q?1746926054411103347?= Sdhci_uhs2_reset() does a UHS-II specific reset operation. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-pci-core.c | 1 + drivers/mmc/host/sdhci-pci-gli.c | 1 + drivers/mmc/host/sdhci-uhs2.c | 68 +++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 3 ++ drivers/mmc/host/sdhci.c | 3 +- drivers/mmc/host/sdhci.h | 14 +++++++ 6 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 622b7de96c7f..a187379ad204 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -1926,6 +1926,7 @@ static const struct sdhci_ops sdhci_pci_ops = { .reset = sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, .hw_reset = sdhci_pci_hw_reset, + .uhs2_reset = sdhci_uhs2_reset, }; /*****************************************************************************\ diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index 4d509f656188..607cf69f45d0 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -1097,6 +1097,7 @@ static const struct sdhci_ops sdhci_gl9755_ops = { .reset = sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, .voltage_switch = sdhci_gli_voltage_switch, + .uhs2_reset = sdhci_uhs2_reset, }; const struct sdhci_pci_fixes sdhci_gl9755 = { diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 08905ed081fb..0e82f98d1967 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -10,6 +10,7 @@ * Author: AKASHI Takahiro */ +#include #include #include "sdhci.h" @@ -49,6 +50,73 @@ 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) +{ + if ((host->mmc->caps2 & MMC_CAP2_SD_UHS2) && + (IS_ENABLED(CONFIG_MMC_SDHCI_UHS2) && + (host->version >= SDHCI_SPEC_400) && + (host->mmc->flags & MMC_UHS2_SUPPORT))) + return true; + else + return false; +} + +/** + * 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; + + if (!(sdhci_uhs2_mode(host))) { + /** + * u8 mask for legacy. + * u16 mask for uhs-2. + */ + u8 u8_mask; + + u8_mask = (mask & 0xFF); + sdhci_reset(host, u8_mask); + + return; + } + + sdhci_writew(host, mask, SDHCI_UHS2_SW_RESET); + + if (mask & SDHCI_UHS2_SW_RESET_FULL) { + host->clock = 0; + /* Reset-all turns off SD Bus Power */ + if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) + sdhci_runtime_pm_bus_off(host); + } + + /* Wait max 100 ms */ + timeout = 10000; + + /* 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 afdb05d6056b..31776dcca5cf 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -11,6 +11,7 @@ #define __SDHCI_UHS2_H #include +#include /* * UHS-II Controller registers @@ -210,5 +211,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 */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 4434838475bf..ab7ea55d9864 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -194,13 +194,14 @@ static void sdhci_runtime_pm_bus_on(struct sdhci_host *host) pm_runtime_get_noresume(mmc_dev(host->mmc)); } -static void sdhci_runtime_pm_bus_off(struct sdhci_host *host) +void sdhci_runtime_pm_bus_off(struct sdhci_host *host) { if (!host->bus_on) return; host->bus_on = false; pm_runtime_put_noidle(mmc_dev(host->mmc)); } +EXPORT_SYMBOL_GPL(sdhci_runtime_pm_bus_off); void sdhci_reset(struct sdhci_host *host, u8 mask) { diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 64c2d7e78e29..3787ffe61c78 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -717,6 +717,19 @@ struct sdhci_ops { u8 power_mode); unsigned int (*get_ro)(struct sdhci_host *host); void (*reset)(struct sdhci_host *host, u8 mask); + /** + * The sdhci_uhs2_reset callback is to implement for reset + * @host: SDHCI host + * @mask: Control mask + * + * Invoke reset, depending on a bit in @mask and wait for completion. + * SD mode UHS-II mode + * SDHCI_RESET_ALL SDHCI_UHS2_SW_RESET_FULL + * SDHCI_RESET_CMD SDHCI_RESET_CMD + * SDHCI_RESET_DATA SDHCI_UHS2_SW_RESET_SD + * + **/ + void (*uhs2_reset)(struct sdhci_host *host, u16 mask); int (*platform_execute_tuning)(struct sdhci_host *host, u32 opcode); void (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs); void (*hw_reset)(struct sdhci_host *host); @@ -839,6 +852,7 @@ static inline void sdhci_read_caps(struct sdhci_host *host) __sdhci_read_caps(host, NULL, NULL, NULL); } +void sdhci_runtime_pm_bus_off(struct sdhci_host *host); u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock, unsigned int *actual_clock); void sdhci_set_clock(struct sdhci_host *host, unsigned int clock); From patchwork Mon Oct 17 09:11:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3311 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347530wrs; Mon, 17 Oct 2022 02:17:48 -0700 (PDT) X-Google-Smtp-Source: AMsMyM63ncPBOqO+ndrQ2keDrFp50vrV/TxcrPZ6uYaTrU0u1ZnBbjFkUCJ0BG7Dc7mxuWoBxvVf X-Received: by 2002:a17:902:efd4:b0:180:fd88:1255 with SMTP id ja20-20020a170902efd400b00180fd881255mr11071560plb.111.1665998268326; Mon, 17 Oct 2022 02:17:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998268; cv=none; d=google.com; s=arc-20160816; b=FxbaE/WmJokojfJH1rocuNCuCWoj6ndZD4xggWLtgBrRppdVHaHCnxUj1Mff0Eag1L BAYsdqMTgooBKmtAOEDHM92xSKtGYhHYlslXhAr0sJyunDUy7ajRQ+F6/1tyjuj+qEIe zhEBYx7+SWE3aJBa6onLzzB6/vzYEQ8DoFAGOWHvC82svkt6A4D5ZJrRWa2h03zanpab BHlAM95B3jC4MRN79ake+9/c0aBYOFx1TxRed7S6Puv7DOphqt38xMaiVSOcoQXSFXni Us6h1GwXeNLJYHlr53eYRtnNiE/mNnCfbVpI1NgfzVVbwlCAT+lUfKMH36GKY8xkgoCD b7qQ== 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=BHBNIUW9z/2UVO1t1aTu9DuLmSyAkbTh3vVXoH3jAOk=; b=X5a+jYmG1/b5XNdQ4z8DSbhOQcRZi87BAb7386DiQtsTEB4qyfTUNSc1q/mc8ZRLow hDulvHKXWQmrPACQ0aTTCrA9ENaDOsWlyGQ/itWvOpeNsy0HMbYpn0ALBCxad0exiUck CnmszscCpf/QkqPgnJwVqcaLp7fD7OwpMYkTFYWibLl0acr96/1sUG9NdpYLwNo1XhrS be3MW6jrKu3XCMxGD9rdtE9xPDSp/DrKfr/g4fFZg6/4tw3PYAfql4ieJVx54a8GrMb+ k3s7RwuQo+dwhvwYSBeMTlbhOEKHFnYU8NpN30L+Qp+Pa/+sRpppldWZAvCQ19KnXQVl XBkg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=X31FtlvH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l12-20020a056a0016cc00b005281e5606b2si11752690pfc.32.2022.10.17.02.17.31; Mon, 17 Oct 2022 02:17:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=X31FtlvH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231214AbiJQJOH (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231217AbiJQJNY (ORCPT ); Mon, 17 Oct 2022 05:13:24 -0400 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1DD6220D7; Mon, 17 Oct 2022 02:12:58 -0700 (PDT) Received: by mail-pl1-x633.google.com with SMTP id i6so10174079pli.12; Mon, 17 Oct 2022 02:12:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=BHBNIUW9z/2UVO1t1aTu9DuLmSyAkbTh3vVXoH3jAOk=; b=X31FtlvHC4uad1WJglvo98c/eSXS3V8ftbi0zSAW857PhWnKigvNRvTD7TCDPsvS9n 0giKWF6ckBbrqczsrI3uCkj6WrOp+KDYYw7VoP1z8cBvM//y6N+d/QnK+WRmThhkRLf5 Ih73NlZf2sQiFxtBcEC2oZMjhd8sAbtkuuaTEI6PmTuxIZ8BymNDin4+kNHbeAOCdLRA JLQ85NQm06CwHubhg8N/X++KqMD23NEMI/7n8UgoPTLrXM8HhCdEosHYDtEAau9180HZ v4+0Ic+IhdEpIldJu+tii67IPwZppb831aL6kzX7qcVPj9u58IHK+JQv9KTtSCU92xeT U2EQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=BHBNIUW9z/2UVO1t1aTu9DuLmSyAkbTh3vVXoH3jAOk=; b=QZ/813o9fsNWJmYA694GTmnGshTxQhZfoTpq51Adgohkpr+/mka7z3cqrP16Ms6y9k RkgFaaxkzlbmL3Ko2ypTLmfOjj/Mr7UBl8TpDMfryXUlYHkK+dtY/Z8y5P9SerbTpuPn Td434zwI7IJDNaFVl5SwKnh78jV+xLL50b4WN0RQrxrdh8tUAZl3XmTeKCmrjcacVqs1 s/h7IUxSJzu3k8eke0FbKECmvffHS/c3eBr3HtvezjJk8RH3eIt5mvK/XnIcHTadJtyo XrSbM15WgND8Rm96DAVN3eSC1flmItvQdy2FmTSTHUL8kxnZlcL0Pr/yVMf0EHP8oUAI Lj0Q== X-Gm-Message-State: ACrzQf218cJnnAD3Z/8dGEhF+no10gKWRpRQ++u/RU4pSCdhWgmCYAzL pgZUfohqVDscHRgnXQF5Ub4= X-Received: by 2002:a17:902:7009:b0:178:b9c9:979f with SMTP id y9-20020a170902700900b00178b9c9979fmr10661453plk.39.1665997967011; Mon, 17 Oct 2022 02:12:47 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:46 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 12/26] mmc: sdhci-uhs2: add set_power() to support vdd2 Date: Mon, 17 Oct 2022 17:11:39 +0800 Message-Id: <20221017091153.454873-13-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925799795094614?= X-GMAIL-MSGID: =?utf-8?q?1746925799795094614?= This is a UHS-II version of sdhci's set_power operation. VDD2, as well as VDD, is handled here. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 79 +++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 2 + drivers/mmc/host/sdhci.c | 66 ++++++++++++++++------------- drivers/mmc/host/sdhci.h | 2 + 4 files changed, 120 insertions(+), 29 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 0e82f98d1967..896a1c8e55cf 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -117,6 +117,85 @@ void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask) } EXPORT_SYMBOL_GPL(sdhci_uhs2_reset); +void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, + unsigned short vdd) +{ + struct mmc_host *mmc = host->mmc; + u8 pwr; + + /* FIXME: check if flags & MMC_UHS2_SUPPORT? */ + if (!(sdhci_uhs2_mode(host))) { + sdhci_set_power(host, mode, vdd); + return; + } + + if (mode != MMC_POWER_OFF) { + pwr = sdhci_get_vdd_value(vdd); + if (!pwr) + WARN(1, "%s: Invalid vdd %#x\n", + mmc_hostname(host->mmc), vdd); + pwr |= SDHCI_VDD2_POWER_180; + } + + if (host->pwr == pwr) + return; + host->pwr = pwr; + + if (pwr == 0) { + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + + if (!IS_ERR(host->mmc->supply.vmmc)) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + if (!IS_ERR_OR_NULL(host->mmc->supply.vmmc2)) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc2, 0); + + if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) + sdhci_runtime_pm_bus_off(host); + } else { + if (!IS_ERR(host->mmc->supply.vmmc)) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); + if (!IS_ERR_OR_NULL(host->mmc->supply.vmmc2)) + /* support 1.8v only for now */ + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc2, + fls(MMC_VDD2_165_195) - 1); + + /* + * Spec says that we should clear the power reg before setting + * a new value. Some controllers don't seem to like this though. + */ + if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + + /* + * At least the Marvell CaFe chip gets confused if we set the + * voltage and set turn on power at the same time, so set the + * voltage first. + */ + if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); + + /* vdd first */ + pwr |= SDHCI_POWER_ON; + sdhci_writeb(host, pwr & 0xf, SDHCI_POWER_CONTROL); + mdelay(5); + + pwr |= SDHCI_VDD2_POWER_ON; + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); + mdelay(5); + + if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) + sdhci_runtime_pm_bus_on(host); + + /* + * Some controllers need an extra 10ms delay of 10ms before + * they can apply clock after applying power + */ + if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) + mdelay(10); + } +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_set_power); + /*****************************************************************************\ * * * Driver init/exit * diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index 31776dcca5cf..3179915f7f79 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -213,5 +213,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); +void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, + unsigned short vdd); #endif /* __SDHCI_UHS2_H */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ab7ea55d9864..509e34f46659 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -23,7 +23,7 @@ #include #include #include - +#include #include #include @@ -186,13 +186,14 @@ static void sdhci_disable_card_detection(struct sdhci_host *host) sdhci_set_card_detection(host, false); } -static void sdhci_runtime_pm_bus_on(struct sdhci_host *host) +void sdhci_runtime_pm_bus_on(struct sdhci_host *host) { if (host->bus_on) return; host->bus_on = true; pm_runtime_get_noresume(mmc_dev(host->mmc)); } +EXPORT_SYMBOL_GPL(sdhci_runtime_pm_bus_on); void sdhci_runtime_pm_bus_off(struct sdhci_host *host) { @@ -2036,41 +2037,48 @@ static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode, sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); } +unsigned short sdhci_get_vdd_value(unsigned short vdd) +{ + u8 pwr; + + switch (1 << vdd) { + case MMC_VDD_165_195: + /* + * Without a regulator, SDHCI does not support 2.0v + * so we only get here if the driver deliberately + * added the 2.0v range to ocr_avail. Map it to 1.8v + * for the purpose of turning on the power. + */ + case MMC_VDD_20_21: + pwr = SDHCI_POWER_180; + break; + case MMC_VDD_29_30: + case MMC_VDD_30_31: + pwr = SDHCI_POWER_300; + break; + case MMC_VDD_32_33: + case MMC_VDD_33_34: + pwr = SDHCI_POWER_330; + break; + default: + pwr = 0; + break; + } + + return pwr; +} +EXPORT_SYMBOL_GPL(sdhci_get_vdd_value); + void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode, unsigned short vdd) { u8 pwr = 0; if (mode != MMC_POWER_OFF) { - switch (1 << vdd) { - case MMC_VDD_165_195: - /* - * Without a regulator, SDHCI does not support 2.0v - * so we only get here if the driver deliberately - * added the 2.0v range to ocr_avail. Map it to 1.8v - * for the purpose of turning on the power. - */ - case MMC_VDD_20_21: - pwr = SDHCI_POWER_180; - break; - case MMC_VDD_29_30: - case MMC_VDD_30_31: - pwr = SDHCI_POWER_300; - break; - case MMC_VDD_32_33: - case MMC_VDD_33_34: - /* - * 3.4 ~ 3.6V are valid only for those platforms where it's - * known that the voltage range is supported by hardware. - */ - case MMC_VDD_34_35: - case MMC_VDD_35_36: - pwr = SDHCI_POWER_330; - break; - default: + pwr = sdhci_get_vdd_value(vdd); + if (!pwr) { WARN(1, "%s: Invalid vdd %#x\n", mmc_hostname(host->mmc), vdd); - break; } } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 3787ffe61c78..0d34ff4dca4e 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -852,6 +852,7 @@ static inline void sdhci_read_caps(struct sdhci_host *host) __sdhci_read_caps(host, NULL, NULL, NULL); } +void sdhci_runtime_pm_bus_on(struct sdhci_host *host); void sdhci_runtime_pm_bus_off(struct sdhci_host *host); u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock, unsigned int *actual_clock); @@ -862,6 +863,7 @@ void sdhci_set_power(struct sdhci_host *host, unsigned char mode, void sdhci_set_power_and_bus_voltage(struct sdhci_host *host, unsigned char mode, unsigned short vdd); +unsigned short sdhci_get_vdd_value(unsigned short vdd); void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode, unsigned short vdd); int sdhci_get_cd_nogpio(struct mmc_host *mmc); From patchwork Mon Oct 17 09:11:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3308 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347521wrs; Mon, 17 Oct 2022 02:17:47 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5WG98dmBFLsKaAs+Tu1SSI6ovxR9x+cbck5hV6wHz1SKgZG7xS4p7vHAG9NnZ75W126t3A X-Received: by 2002:a17:90a:5915:b0:20a:d6d5:31bd with SMTP id k21-20020a17090a591500b0020ad6d531bdmr12558043pji.15.1665998267608; Mon, 17 Oct 2022 02:17:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998267; cv=none; d=google.com; s=arc-20160816; b=WvaVMfvU+NUFIEQbjTDpGB+4pXs/56c21qg1yJE379GueILY7CT0cXPPmCgW8+c2dB DNKnK0g+duvBnLuxMUzrtoaHOBG63Hc3She0G+nZppRYZggAVpOpruCxWUe5mxg/wi8e L+WQmzp2upY1PgVGTRoHDXyL7fImIUtXZ5so3+5ZlSuswPSEF7Mzfjrzuq1/dEULnT/c aDDV8nShJgtS8uXf3PtXAn5U9mVhEq+TU3MbI/4+cn1z1dOB3t6ED9ITwRXE04nndR4y byKekO9XABAUeeHKgpNVY2g7B7D0Tmu9iWfxDGYiLshn9EaWM48q0CsWXRIQkBk4azJU grpQ== 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=1FsmUpiAlASHehR9dRBEnfUXc1GjY31312bVgt+7nS4=; b=KI4S0CnL5j563Te635js1jZOTKr+eweLo2Z91z/R+PDJoy4z98mEaWtKXAH3L3BVlr 8CpyfXKeCTV9IPFNNVwjhMibeunuVzqSRN8aaQzoZeLlT0xf3Q1ZEugCqxhDB+nozqXE puNMuwfm/Veh7ZGS12NzITK9joPmRnoEBgDlQ8xRk50XZL+yJQ9X+GCipd5ixJgJGqeu GjZ4+xuJmXr2VZZYwB3CQjJF/SOFomEsykymkxD+22wcNA/Z57sp+MNx5cY0bCgiUEhK SZwTHqc0xlF0bvVJnX26fBCVfUv+KRfCK0GW6tGa5rg3fSvsTsQQ4boGCqCm8z2uG8MO kGZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=iZcgqmIw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c24-20020a637258000000b0042c6044840dsi10514177pgn.425.2022.10.17.02.17.28; Mon, 17 Oct 2022 02:17:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=iZcgqmIw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230385AbiJQJOB (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231206AbiJQJNY (ORCPT ); Mon, 17 Oct 2022 05:13:24 -0400 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18F1D24F2D; Mon, 17 Oct 2022 02:13:01 -0700 (PDT) Received: by mail-pj1-x102d.google.com with SMTP id a5-20020a17090aa50500b002008eeb040eso12359492pjq.1; Mon, 17 Oct 2022 02:13:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=1FsmUpiAlASHehR9dRBEnfUXc1GjY31312bVgt+7nS4=; b=iZcgqmIw+hJ38Xc0pJ6p3DX+9pAxYaI6mMC7VvV0Mrj22TGnB5MX9+/dAMz9wseDHK xCvtZFsC296jva3Ge174oRs0AZ91o2L1jU1m2pIR9CBZy0vYvJN6QdJKiEPd5OvsYYax GLCSmlAt/rRjt9A2J1XpKSEP6XTI65QRPfapin1tnHqhkuZ1VY0VwJynU78yl3+ksspw JVACtTAXbbUC0K7N07AY0me7yCsTNMDPjJBrc4KtZGfuRYYOIEaQWtDzsWS1bztzXkC/ wK/5zuZLPRtIvQ2v7iHu7uX29Mq0XEBT5ND4hd/Bc2Q3SN0Yo3n0gcA4uuqjXCm5XVGO cRuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=1FsmUpiAlASHehR9dRBEnfUXc1GjY31312bVgt+7nS4=; b=uDeBCNCzBpmtAwfbblF5fjslpxMNGyQ3ahscAvHPrcLTYjN6Z74yoa/4PcYErFRfE2 Ya/tfXxS/x160ZczPQD2DLTqhS2hUlgqYKTmI5OrYWY7S+Um7xStqsBpyx9KYJfN9ULs wDYFZfnGByBFUXCMgUwH/h3Mu/6YO2pTEoNTTp6yo6KgjsItCCAMqQlTYtDwkVz63agF KqyTl+ySwFtD1ElJdqm0frvWfiej7MlRdXFrb9WbZJW1YagnlKM7W3yu8UagNlMK0k46 KYZ7u6cXFnG83Ued2o88kTlXxK04kmjk4G2ySwsOJl0zPiKwZnpBXjzJsFdhEXIDo/x5 DxFA== X-Gm-Message-State: ACrzQf1fN6H6dnJ96ZWXAR0FAN/qUBJNx3Bt7hWH6SlCQ2WQUAZz5rEK iQXVSIAUAeY/EOLApyDjujQ= X-Received: by 2002:a17:902:d48d:b0:183:1d43:fd34 with SMTP id c13-20020a170902d48d00b001831d43fd34mr11272746plg.46.1665997969769; Mon, 17 Oct 2022 02:12:49 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:49 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 13/26] mmc: sdhci-uhs2: skip signal_voltage_switch() Date: Mon, 17 Oct 2022 17:11:40 +0800 Message-Id: <20221017091153.454873-14-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925799377723008?= X-GMAIL-MSGID: =?utf-8?q?1746925799377723008?= For UHS2, the signal voltage is supplied by vdd2 which is already 1.8v, so no voltage switch required. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 896a1c8e55cf..4dc3e904d7d2 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -196,6 +196,27 @@ void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, } EXPORT_SYMBOL_GPL(sdhci_uhs2_set_power); +/*****************************************************************************\ + * * + * MMC callbacks * + * * +\*****************************************************************************/ + +static int sdhci_uhs2_start_signal_voltage_switch(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + + /* + * For UHS2, the signal voltage is supplied by vdd2 which is + * already 1.8v so no voltage switch required. + */ + if (sdhci_uhs2_mode(host)) + return 0; + + return sdhci_start_signal_voltage_switch(mmc, ios); +} + /*****************************************************************************\ * * * Driver init/exit * @@ -204,6 +225,9 @@ EXPORT_SYMBOL_GPL(sdhci_uhs2_set_power); static int sdhci_uhs2_host_ops_init(struct sdhci_host *host) { + host->mmc_host_ops.start_signal_voltage_switch = + sdhci_uhs2_start_signal_voltage_switch; + return 0; } From patchwork Mon Oct 17 09:11:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3313 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347761wrs; Mon, 17 Oct 2022 02:18:22 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4xLz3zxYEpZjuIHCyOfoO0FImtGJzF2GQZtOzrW+pktq+uoZEhbGIrTEC6JajXXov2q0BL X-Received: by 2002:a63:ea58:0:b0:45f:ffa9:60a0 with SMTP id l24-20020a63ea58000000b0045fffa960a0mr9916455pgk.433.1665998302321; Mon, 17 Oct 2022 02:18:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998302; cv=none; d=google.com; s=arc-20160816; b=OZdSpf8HJ9Zi5o2D3XEvxowLLuPCincJgZli9hASj3jVuzo400tSGTycC9y0CFPRgl ve9JKXlGGjjhs6Q61TZZVpKL0i81NWeurBb01ZI5TcvnZZ//gRRKwYaQyWZsDk5HGhQ2 OHHUdS5VP/Ujaa22L1cC2dvosyz4KW0vHJwe9mRioTGryigegeiHvRxtgoUgp+cU1pSG TdiBSJftGXyS4rHfTZzXcdKvlvJwJ4dAAsPmyDgA7yzxr2xYG8hR4dF0Vpao5KJ54lAP /jg5CtOtoo+buJtHpb5w/hbr3VCoGiSKBEu2d0BgK2QOeNb9dBkmL3EX7PEAMDf4dR3v 0xlA== 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=h5ky6yRKLirOgAuzcb87q4FCsZ9Aux469YNihh1WRPk=; b=IDq+hi56zw7Z1HF/cs6nDxVbvqNTR63Z2i1Bt/d3DnOTUwRlZrowjsAk04r2Il+OJg SZ2tHYNJOBMY3q9rQgoT1mO0qEpU/rxSONwyMQnUHOb+yleHOYdv3z7vUBHwDSTPRuYL Dcy2urIJAYR1Vz+gpHX0GiBBtQGxB+AK0lVWJ9yvy3el4TnJxeL3OKg8rM3BLKU3SKd6 x/0HM++JbZpIP0/ZnXBT6X+7p2cpC6AXOEB9eJbUTZzf06Y12rFqwi5JFdVGWWLn55nB 3mfwSrRKv5l+fpyPd7c66mtafi828iNUOJZWe7acaMcxUPrx/I3ygA47ThggU8RhgENP Hrww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=LCiAMVeH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e14-20020a63d94e000000b0043cae020a12si11361493pgj.378.2022.10.17.02.17.59; Mon, 17 Oct 2022 02:18:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=LCiAMVeH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231235AbiJQJOQ (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231222AbiJQJN2 (ORCPT ); Mon, 17 Oct 2022 05:13:28 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6FF154BA7C; Mon, 17 Oct 2022 02:13:03 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id i3so10489860pfc.11; Mon, 17 Oct 2022 02:13:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=h5ky6yRKLirOgAuzcb87q4FCsZ9Aux469YNihh1WRPk=; b=LCiAMVeHcYmVLz4j7kDEOEuc3K3J56MBIcWcSg/55nGw3o5dt07to9W3GYhLBtvnBK gqAbTLQE2Do0Qz67tSNodhslopkR/o6IXMOkqJI3shyEqSGtFCnuY2K/Zmm9aHZnMhnG 4Hld5EvhzYbc/4b8X9kvruYzB2AXa5WuvGM1pBBejv6G3K0cZtKd6wAy0+KWXFvDD23k gs8p6piRlgavlttmKitqcivw3WJgoF/XS1t902Kl/QqZGIM4sW/1GtdQSearuiAnw8Ks jwkyVgsWOd7pm31iC03BTUN+W5V1e1f9Z1fPXgsM/VugSrMcS+atMLM3M1NFM4wszJ1s D+XA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=h5ky6yRKLirOgAuzcb87q4FCsZ9Aux469YNihh1WRPk=; b=ZGu4lFv241Un0oVO/s+HZ1NPEtOojfZdsI7RLKBLcToQ7SGFoSp2krZ3ONdZFe/C+X Q74FiY3ZqNGQyzZ/J4KYpf4JbJzJjTPo4CiafHVe7CuZqWf3U03oDX3reUAuX1xQ4nQF /PdkSTikUvKw/es99u840UGVAxKONLtQteRZp5iT/P/zd5z/4ozrorqGcbHEPgiw4TNo TxFvZhHg3GqW0R5OkbMYd27LMpVqj7NnHVg4DKitxrc4ZgufJ/uptNGzUHfW+TCzhHqa ntyOOSgI9Tfz3qVgNMj2DAoaQHOmSAv2U93YiAwoBNqI8hC7u/uOv8qz7DzkrDrAybzl UUlQ== X-Gm-Message-State: ACrzQf0SZ06T5rFxCDVIM18bwHN38HbYA6TBUpgApLU/zgRHmlQ8fC7g uR+tMhKdTO/IZrcN4GJIbwQ= X-Received: by 2002:a05:6a00:4214:b0:562:67d0:77e7 with SMTP id cd20-20020a056a00421400b0056267d077e7mr11973951pfb.62.1665997972815; Mon, 17 Oct 2022 02:12:52 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:52 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 14/26] mmc: sdhci-uhs2: add set_timeout() Date: Mon, 17 Oct 2022 17:11:41 +0800 Message-Id: <20221017091153.454873-15-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925836030037169?= X-GMAIL-MSGID: =?utf-8?q?1746925836030037169?= From: AKASHI Takahiro This is a UHS-II version of sdhci's set_timeout() operation. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro --- drivers/mmc/host/sdhci-uhs2.c | 85 +++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 1 + 2 files changed, 86 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 4dc3e904d7d2..2b90e5308764 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -196,6 +196,91 @@ void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, } EXPORT_SYMBOL_GPL(sdhci_uhs2_set_power); +static u8 sdhci_calc_timeout_uhs2(struct sdhci_host *host, u8 *cmd_res, + u8 *dead_lock) +{ + u8 count; + unsigned int cmd_res_timeout, dead_lock_timeout, current_timeout; + + /* + * If the host controller provides us with an incorrect timeout + * value, just skip the check and use 0xE. The hardware may take + * longer to time out, but that's much better than having a too-short + * timeout value. + */ + if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) { + *cmd_res = 0xE; + *dead_lock = 0xE; + return 0xE; + } + + /* timeout in us */ + cmd_res_timeout = 5 * 1000; + dead_lock_timeout = 1 * 1000 * 1000; + + /* + * Figure out needed cycles. + * We do this in steps in order to fit inside a 32 bit int. + * The first step is the minimum timeout, which will have a + * minimum resolution of 6 bits: + * (1) 2^13*1000 > 2^22, + * (2) host->timeout_clk < 2^16 + * => + * (1) / (2) > 2^6 + */ + count = 0; + current_timeout = (1 << 13) * 1000 / host->timeout_clk; + while (current_timeout < cmd_res_timeout) { + count++; + current_timeout <<= 1; + if (count >= 0xF) + break; + } + + if (count >= 0xF) { + DBG("%s: Too large timeout 0x%x requested for CMD_RES!\n", + mmc_hostname(host->mmc), count); + count = 0xE; + } + *cmd_res = count; + + count = 0; + current_timeout = (1 << 13) * 1000 / host->timeout_clk; + while (current_timeout < dead_lock_timeout) { + count++; + current_timeout <<= 1; + if (count >= 0xF) + break; + } + + if (count >= 0xF) { + DBG("%s: Too large timeout 0x%x requested for DEADLOCK!\n", + mmc_hostname(host->mmc), count); + count = 0xE; + } + *dead_lock = count; + + return count; +} + +static void __sdhci_uhs2_set_timeout(struct sdhci_host *host) +{ + u8 cmd_res, dead_lock; + + sdhci_calc_timeout_uhs2(host, &cmd_res, &dead_lock); + cmd_res |= dead_lock << SDHCI_UHS2_TIMER_CTRL_DEADLOCK_SHIFT; + sdhci_writeb(host, cmd_res, SDHCI_UHS2_TIMER_CTRL); +} + +void sdhci_uhs2_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) +{ + __sdhci_set_timeout(host, cmd); + + if (host->mmc->flags & MMC_UHS2_SUPPORT) + __sdhci_uhs2_set_timeout(host); +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_set_timeout); + /*****************************************************************************\ * * * MMC callbacks * diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index 3179915f7f79..5ea235b14108 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -215,5 +215,6 @@ bool sdhci_uhs2_mode(struct sdhci_host *host); void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask); void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd); +void sdhci_uhs2_set_timeout(struct sdhci_host *host, struct mmc_command *cmd); #endif /* __SDHCI_UHS2_H */ From patchwork Mon Oct 17 09:11:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3320 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348192wrs; Mon, 17 Oct 2022 02:19:35 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5u8XIfVl7tSdaZkFg4DhRK5KpkOEEd0n9snHgFhfe27AesyC/8n5mDuEEZLGGOjjCtSRk/ X-Received: by 2002:a05:6a00:3202:b0:565:c863:78a1 with SMTP id bm2-20020a056a00320200b00565c86378a1mr11702068pfb.7.1665998374932; Mon, 17 Oct 2022 02:19:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998374; cv=none; d=google.com; s=arc-20160816; b=CtXThJRv5F99x5+x7mg+7/6+EGDxR7EJQbDBwBf+jSqURMq/6G1RkCLhDCtjn+mjuP r2vHnxsKJICo/ci908irqRPPab/pXkm3EhpBcKO8D3ssBDXXR0X42xDVZC9V0yuwmShV zTJN1Fod3RvPDMiU8eCSP1dRuj5oojkVb19tpg0ywYBtAXRENF/3s2AzdV0lSl4l9srE y1qZAg01jpER4Vku6m9f/zYNQQgYZHCX1TNFr+gX6Uf0EX9plIfZJEK2mbyge331LK7U pg8saTF0jjYohV5BxQstjIhKbDhMDl3MoaP0IXPMhTHvwoUQ4gVo9JL3E06kbLoS/Ms+ mY2w== 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=b0m5G6QwVeVB8SXs1aT9DhWk8khRrmdEfTTeLadnXfQ=; b=Bm/jMIH7PwBkqh3GSyIsGsgtVaVdDsBTxwnX+lGupJLTAxk/N0cWJRQlY2nsu5X9La gp9Gey1BGnkyn89/J9SM7RLXOGwIGKYEA42ccM+GPoM/tcU9BTgQUmuhU+RPfj88C2sP FHEmLSoJvqYTWXVYIaYd7agRa9QdVpJAvIj5Mk0MD4BiA9KyOp2SQUM1KfShN0JGWjak kFtzDk0/WI+tDkeVi8aCwwTV6c99xelL9EDZ+LQKLdeZYLzxuLqVpPfCBQQKG40iJMj6 kBQoKUfWOcPqQ5w7a3VJykrftU1etcS2daBqjhjnHe3dZuwD8OEFBfF+jv/+yE2QRyom 6VkQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=fFuBJvNS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n20-20020a170903405400b0016c058d72b2si9340488pla.238.2022.10.17.02.19.22; Mon, 17 Oct 2022 02:19:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=fFuBJvNS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231238AbiJQJOS (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230501AbiJQJN2 (ORCPT ); Mon, 17 Oct 2022 05:13:28 -0400 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 901254C005; Mon, 17 Oct 2022 02:13:06 -0700 (PDT) Received: by mail-pj1-x102d.google.com with SMTP id fw14so10418451pjb.3; Mon, 17 Oct 2022 02:13:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=b0m5G6QwVeVB8SXs1aT9DhWk8khRrmdEfTTeLadnXfQ=; b=fFuBJvNSYQ9dVuqDaW+lEohT0to5y/fcCD8kWw4Aax0ZfeJCfzyuPFYDDKhGlkNeel kpmAo2fbVtH1jHkeD5sDfriROtHsIzZGZmMntS+fUat9TXONcE2Cb4ehNqOzjCgpY2/p ZyutfybZyp8JGSrf7xNosbfAMelgWOk3z5iGwW4gP+SFr6NfowJ3WZo3yZ5kjlSZVgm8 MY20+kRVSrXt5nTlp6UMDGraknqZSlMvCe6Rmr8qvZy10bsvOx97WNey6sgXYIzvvto6 /8CqxoEKLDAyO2dDZaJ1HwG9jbs7CeYpgS9WMmOKmdgETMkxMCQ8c08ZjcwLyY57jnbi OctA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=b0m5G6QwVeVB8SXs1aT9DhWk8khRrmdEfTTeLadnXfQ=; b=JSNna2wed64q+4QlNr6/s4TRujEgdzI9WWPxVHfeUmaDgrL0UsvujvCIJi6uNRRGlt f/fv+tcjt3ozji7DG/ZU2Unh6cAyynRrNJIg1Cc1ebqskAg9P9f4mJC28f+g8m/NWFLT GaRWcu0NHHKsaf0xKJBRcvqdjevVbSp5jvo2WrKXF94oULfU5BnbHGdZ8pkdiDVkxRDD d7F+oMnd+7+hg5kSDJ0OXRNV4x1lRhdEGzNvpuTLFUIzoqPR8jYzF/m2g2pzj9bK4Kox P9uXzeI57k+iMRdlKOcbk/Yf6qLHIORpU00lilChFVU4aalmNz6/Qv656RNEYBmbIIqI o6Ww== X-Gm-Message-State: ACrzQf0taijChw1anudegOu0e5gSX/2F92r5CdJWly3/+SgO6JcwI8iz m1ajSEIYGOHWaDwW8+yI87w= X-Received: by 2002:a17:90b:3a8b:b0:20d:b254:e30e with SMTP id om11-20020a17090b3a8b00b0020db254e30emr12792159pjb.206.1665997975721; Mon, 17 Oct 2022 02:12:55 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:55 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 15/26] mmc: sdhci-uhs2: add set_ios() Date: Mon, 17 Oct 2022 17:11:42 +0800 Message-Id: <20221017091153.454873-16-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925912267285903?= X-GMAIL-MSGID: =?utf-8?q?1746925912267285903?= This is a sdhci version of mmc's set_ios operation. It covers both UHS-I and UHS-II. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 102 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 1 + drivers/mmc/host/sdhci.c | 40 ++++++++----- drivers/mmc/host/sdhci.h | 2 + 4 files changed, 130 insertions(+), 15 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 2b90e5308764..b535a47dc55a 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -281,6 +281,74 @@ void sdhci_uhs2_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) } EXPORT_SYMBOL_GPL(sdhci_uhs2_set_timeout); +/** + * sdhci_uhs2_clear_set_irqs - set Error Interrupt Status Enable register + * @host: SDHCI host + * @clear: bit-wise clear mask + * @set: bit-wise set mask + * + * Set/unset bits in UHS-II Error Interrupt Status Enable register + */ +void sdhci_uhs2_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set) +{ + u32 ier; + + ier = sdhci_readl(host, SDHCI_UHS2_ERR_INT_STATUS_EN); + ier &= ~clear; + ier |= set; + sdhci_writel(host, ier, SDHCI_UHS2_ERR_INT_STATUS_EN); + sdhci_writel(host, ier, SDHCI_UHS2_ERR_INT_SIG_EN); +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_clear_set_irqs); + +static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + u8 cmd_res, dead_lock; + u16 ctrl_2; + unsigned long flags; + + /* FIXME: why lock? */ + spin_lock_irqsave(&host->lock, flags); + + /* UHS2 Timeout Control */ + sdhci_calc_timeout_uhs2(host, &cmd_res, &dead_lock); + + /* change to use calculate value */ + cmd_res |= dead_lock << SDHCI_UHS2_TIMER_CTRL_DEADLOCK_SHIFT; + + sdhci_uhs2_clear_set_irqs(host, + SDHCI_UHS2_ERR_INT_STATUS_RES_TIMEOUT | + SDHCI_UHS2_ERR_INT_STATUS_DEADLOCK_TIMEOUT, + 0); + sdhci_writeb(host, cmd_res, SDHCI_UHS2_TIMER_CTRL); + sdhci_uhs2_clear_set_irqs(host, 0, + SDHCI_UHS2_ERR_INT_STATUS_RES_TIMEOUT | + SDHCI_UHS2_ERR_INT_STATUS_DEADLOCK_TIMEOUT); + + /* UHS2 timing */ + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (ios->timing == MMC_TIMING_SD_UHS2) + ctrl_2 |= SDHCI_CTRL_UHS_2 | SDHCI_CTRL_UHS2_INTERFACE_EN; + else + ctrl_2 &= ~(SDHCI_CTRL_UHS_2 | SDHCI_CTRL_UHS2_INTERFACE_EN); + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); + + if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) + sdhci_enable_preset_value(host, true); + + if (host->ops->set_power) + host->ops->set_power(host, ios->power_mode, ios->vdd); + else + sdhci_uhs2_set_power(host, ios->power_mode, ios->vdd); + udelay(100); + + host->timing = ios->timing; + sdhci_set_clock(host, host->clock); + + spin_unlock_irqrestore(&host->lock, flags); +} + /*****************************************************************************\ * * * MMC callbacks * @@ -302,6 +370,39 @@ static int sdhci_uhs2_start_signal_voltage_switch(struct mmc_host *mmc, return sdhci_start_signal_voltage_switch(mmc, ios); } +int sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + + if (!(host->version >= SDHCI_SPEC_400) || + !(host->mmc->flags & MMC_UHS2_SUPPORT && + host->mmc->caps2 & MMC_CAP2_SD_UHS2)) { + sdhci_set_ios(mmc, ios); + return 0; + } + + if (ios->power_mode == MMC_POWER_UNDEFINED) + return 1; + + if (host->flags & SDHCI_DEVICE_DEAD) { + if (!IS_ERR(mmc->supply.vmmc) && + ios->power_mode == MMC_POWER_OFF) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + if (!IS_ERR_OR_NULL(mmc->supply.vmmc2) && + ios->power_mode == MMC_POWER_OFF) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc2, 0); + return 1; + } + + /* FIXME: host->timing = ios->timing */ + + sdhci_set_ios_common(mmc, ios); + + __sdhci_uhs2_set_ios(mmc, ios); + + return 0; +} + /*****************************************************************************\ * * * Driver init/exit * @@ -312,6 +413,7 @@ static int sdhci_uhs2_host_ops_init(struct sdhci_host *host) { host->mmc_host_ops.start_signal_voltage_switch = sdhci_uhs2_start_signal_voltage_switch; + host->mmc_host_ops.uhs2_set_ios = sdhci_uhs2_set_ios; return 0; } diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index 5ea235b14108..23368448ccd4 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -216,5 +216,6 @@ void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask); void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd); void sdhci_uhs2_set_timeout(struct sdhci_host *host, struct mmc_command *cmd); +void sdhci_uhs2_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set); #endif /* __SDHCI_UHS2_H */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 509e34f46659..af4c7549f7c0 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -47,8 +47,6 @@ static unsigned int debug_quirks = 0; static unsigned int debug_quirks2; -static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); - static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd); void sdhci_dumpregs(struct sdhci_host *host) @@ -1853,6 +1851,9 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host) case MMC_TIMING_MMC_HS400: preset = sdhci_readw(host, SDHCI_PRESET_FOR_HS400); break; + case MMC_TIMING_SD_UHS2: + preset = sdhci_readw(host, SDHCI_PRESET_FOR_UHS2); + break; default: pr_warn("%s: Invalid UHS-I mode selected\n", mmc_hostname(host->mmc)); @@ -2270,20 +2271,9 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing) } EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling); -void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +void sdhci_set_ios_common(struct mmc_host *mmc, struct mmc_ios *ios) { struct sdhci_host *host = mmc_priv(mmc); - u8 ctrl; - - if (ios->power_mode == MMC_POWER_UNDEFINED) - return; - - if (host->flags & SDHCI_DEVICE_DEAD) { - if (!IS_ERR(mmc->supply.vmmc) && - ios->power_mode == MMC_POWER_OFF) - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); - return; - } /* * Reset the chip on each power off. @@ -2320,6 +2310,25 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->ops->set_power(host, ios->power_mode, ios->vdd); else sdhci_set_power(host, ios->power_mode, ios->vdd); +} +EXPORT_SYMBOL_GPL(sdhci_set_ios_common); + +void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + u8 ctrl; + + if (ios->power_mode == MMC_POWER_UNDEFINED) + return; + + if (host->flags & SDHCI_DEVICE_DEAD) { + if (!IS_ERR(mmc->supply.vmmc) && + ios->power_mode == MMC_POWER_OFF) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + return; + } + + sdhci_set_ios_common(mmc, ios); if (host->ops->platform_send_init_74_clocks) host->ops->platform_send_init_74_clocks(host, ios->power_mode); @@ -2909,7 +2918,7 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) } EXPORT_SYMBOL_GPL(sdhci_execute_tuning); -static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable) +void sdhci_enable_preset_value(struct sdhci_host *host, bool enable) { /* Host Controller v3.00 defines preset value registers */ if (host->version < SDHCI_SPEC_300) @@ -2937,6 +2946,7 @@ static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable) host->preset_enabled = enable; } } +EXPORT_SYMBOL_GPL(sdhci_enable_preset_value); static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq, int err) diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 0d34ff4dca4e..dca08aac076d 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -873,6 +873,8 @@ void sdhci_set_bus_width(struct sdhci_host *host, int width); void sdhci_reset(struct sdhci_host *host, u8 mask); void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing); int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); +void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); +void sdhci_set_ios_common(struct mmc_host *mmc, struct mmc_ios *ios); void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios); From patchwork Mon Oct 17 09:11:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3312 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347586wrs; Mon, 17 Oct 2022 02:17:56 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5y+yp347GlhaP//mFYu1ZaaqVHgRwnqN+mdulAkHf8trFK9WN2Iw0gio0qGiddekcbO4Ft X-Received: by 2002:a17:90a:ac11:b0:20b:10d2:e837 with SMTP id o17-20020a17090aac1100b0020b10d2e837mr12755221pjq.165.1665998276364; Mon, 17 Oct 2022 02:17:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998276; cv=none; d=google.com; s=arc-20160816; b=PMo27rpmSvL3EORY67vZAEIAPJQR9SX5Lh6WZcpJGiHDH6B+YvpMXURuwuUjOs4Ab7 dPkHYdqUN4W5PDTsLA8O1SQPHC1yNp8EQMzWKtsY/NG/TKSTRQ7iJukqXAMVVpnKxYnC r8YykZf6QqoP4UF7Wy+7h0rvuNZMuJK7RQ+3E8ahApF7BGmmXLZ6lCC4m59tqw8Lgl3e oF3r0oKeF76HMd3S8CI3hY0erLvka7CGx+iWdOdGDcKQXWNxUfwjIwWAZ4TKfe8IWudp bbJx8Nvl4atCCfjRz1CcPo6uDy3HxyL5StK3OU4PlKEgasZewfiTJtLT/XvzO99NstVI lZfg== 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=S0JaYjFQ+aDdA98wvr2uZtwG5pNvlC/TFpCGLaFw/7g=; b=nVVo+m51iRJpq7xmN9i1y14wTKjTDRUbwDlLneDl4UHY7bPE2lPvc9pCjvKPDrBj4i HzyfNu/gWz9ECz75Mm9FKFx9WWgHGqGms/dxcnF6ff4uLIJgNQIp0Kg/rAaDseCnBPYQ rZl3Upyf2xIbWwxbMjV+izlglH72r3GaWHgLPO1y9vK3TCWvXDGRwC7cB5CgXyo2AMeo 6vWw7GsmwDakLCFTiD6eI44niQLZyq3Xvjzr+A3DD7z+f9AtCp35BuhzvXysmqxpTQBZ UQUSGo/vIC8d1R2tJl7DPXsj0g+ajg45Rp8XzXsUBok7Y6Sfe+RxJjhHNoC85WPkef5Q udAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=WETiCRFu; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k19-20020a056a00169300b005637df79509si11125548pfc.197.2022.10.17.02.17.43; Mon, 17 Oct 2022 02:17:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=WETiCRFu; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231228AbiJQJOM (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34326 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230456AbiJQJNZ (ORCPT ); Mon, 17 Oct 2022 05:13:25 -0400 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 393D24C63F; Mon, 17 Oct 2022 02:13:06 -0700 (PDT) Received: by mail-pj1-x1035.google.com with SMTP id l1-20020a17090a72c100b0020a6949a66aso10405445pjk.1; Mon, 17 Oct 2022 02:13:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=S0JaYjFQ+aDdA98wvr2uZtwG5pNvlC/TFpCGLaFw/7g=; b=WETiCRFuvp6zEGwSY7lZvFrhm3OPpqCkBRMM5f6eiRGbK/k0CDnylzqo9Dqz1YWOq8 dYDhnYwp5TYH6pUMAo7PF7Fe8iqoDbx463549PAuH+/XqRAqg1Xy4vYUSyNc8Pa6gxHJ W7jYIS2QDZZpduYrfcnvbGm7Eeg1XwuYXnrXUNuUl+QpY8K/NDDasmJK51vWOIuTMqrs 8LiLt1mzlnVhL4aNC/7O2yAWi/MQsFm0S4cA5Y6CxqNaMu4PLX+STjUSCfsYhB/bs43Q NuFTjD54hRwqVxlfcXWDRE61Dw0KQAUI/g85kClXYwAvUYWWUH2XAs6ov7l1bBqhnrRz wAyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=S0JaYjFQ+aDdA98wvr2uZtwG5pNvlC/TFpCGLaFw/7g=; b=qg5BiZKjAC65NnvKhBPun78LB/SOiZlW3oYR5f2rFsIIHCNaDAJVkKEtDIQz8WajV6 HRKJwr+PlOm1xvyOqCP6lqHqBLoF6Rj5kCcjjXczh0bTi6Utdbd69pBdrYAm78Kymkqj a7xgFa/LqkBLnB38dRbPCPz9THqg3Rfywj4WYjnTgVtozcjpzEFhCXWg8vv1n0XZG/aJ Jg7jLTVyknv7+f7Tsk0Du1kyHpU6Jqu0GzzqMcUOQt4Nz/zYcLUEQOybmw8ala1kpCpM x+CCUyGR+Lp4td04mLPr6MG6xjO0bOU90Ki9s50xuFpbbDqfzwgOBKbAfFa5watR+qYe NXIQ== X-Gm-Message-State: ACrzQf1VFmcEFv9D7KsegbB0T3Fuioc05AAiuGaZVTHDuB1MoyjVN5aR 8PSUvdchnq1yiILIXr+FNy0= X-Received: by 2002:a17:90b:3908:b0:20d:4151:1b73 with SMTP id ob8-20020a17090b390800b0020d41511b73mr12828811pjb.45.1665997978582; Mon, 17 Oct 2022 02:12:58 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:12:58 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 16/26] mmc: sdhci-uhs2: add detect_init() to detect the interface Date: Mon, 17 Oct 2022 17:11:43 +0800 Message-Id: <20221017091153.454873-17-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925808594478424?= X-GMAIL-MSGID: =?utf-8?q?1746925808594478424?= Sdhci_uhs2_do_detect_init() is a sdhci version of mmc's uhs2_detect_init operation. After detected, the host's UHS-II capabilities will be set up here and interrupts will also be enabled. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 150 ++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index b535a47dc55a..145508918486 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -409,12 +409,162 @@ int sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * * \*****************************************************************************/ +static int sdhci_uhs2_interface_detect(struct sdhci_host *host) +{ + /* 100ms */ + int timeout = 100000; + u32 val; + + udelay(200); /* wait for 200us before check */ + + if (read_poll_timeout_atomic(sdhci_readl, val, (val & SDHCI_UHS2_IF_DETECT), + 100, timeout, true, host, SDHCI_PRESENT_STATE)) { + pr_warn("%s: not detect UHS2 interface in 200us.\n", mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + return -EIO; + } + + /* Enable UHS2 error interrupts */ + sdhci_uhs2_clear_set_irqs(host, SDHCI_INT_ALL_MASK, + SDHCI_UHS2_ERR_INT_STATUS_MASK); + + /* 150ms */ + timeout = 150000; + if (read_poll_timeout_atomic(sdhci_readl, val, (val & SDHCI_UHS2_LANE_SYNC), + 100, timeout, true, host, SDHCI_PRESENT_STATE)) { + pr_warn("%s: UHS2 Lane sync fail in 150ms.\n", mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + return -EIO; + } + + DBG("%s: UHS2 Lane synchronized in UHS2 mode, PHY is initialized.\n", + mmc_hostname(host->mmc)); + return 0; +} + +static int sdhci_uhs2_init(struct sdhci_host *host) +{ + u16 caps_ptr = 0; + u32 caps_gen = 0; + u32 caps_phy = 0; + u32 caps_tran[2] = {0, 0}; + struct mmc_host *mmc = host->mmc; + + /* + * TODO: may add corresponding members in sdhci_host to + * keep these caps. + */ + caps_ptr = sdhci_readw(host, SDHCI_UHS2_HOST_CAPS_PTR); + if (caps_ptr < 0x100 || caps_ptr > 0x1FF) { + pr_err("%s: SDHCI_UHS2_HOST_CAPS_PTR(%d) is wrong.\n", + mmc_hostname(mmc), caps_ptr); + return -ENODEV; + } + caps_gen = sdhci_readl(host, + caps_ptr + SDHCI_UHS2_HOST_CAPS_GEN_OFFSET); + caps_phy = sdhci_readl(host, + caps_ptr + SDHCI_UHS2_HOST_CAPS_PHY_OFFSET); + caps_tran[0] = sdhci_readl(host, + caps_ptr + SDHCI_UHS2_HOST_CAPS_TRAN_OFFSET); + caps_tran[1] = sdhci_readl(host, + caps_ptr + + SDHCI_UHS2_HOST_CAPS_TRAN_1_OFFSET); + + /* General Caps */ + mmc->uhs2_caps.dap = caps_gen & SDHCI_UHS2_HOST_CAPS_GEN_DAP_MASK; + mmc->uhs2_caps.gap = (caps_gen & SDHCI_UHS2_HOST_CAPS_GEN_GAP_MASK) >> + SDHCI_UHS2_HOST_CAPS_GEN_GAP_SHIFT; + mmc->uhs2_caps.n_lanes = (caps_gen & SDHCI_UHS2_HOST_CAPS_GEN_LANE_MASK) + >> SDHCI_UHS2_HOST_CAPS_GEN_LANE_SHIFT; + mmc->uhs2_caps.addr64 = + (caps_gen & SDHCI_UHS2_HOST_CAPS_GEN_ADDR_64) ? 1 : 0; + mmc->uhs2_caps.card_type = + (caps_gen & SDHCI_UHS2_HOST_CAPS_GEN_DEV_TYPE_MASK) >> + SDHCI_UHS2_HOST_CAPS_GEN_DEV_TYPE_SHIFT; + + /* PHY Caps */ + mmc->uhs2_caps.phy_rev = caps_phy & SDHCI_UHS2_HOST_CAPS_PHY_REV_MASK; + mmc->uhs2_caps.speed_range = + (caps_phy & SDHCI_UHS2_HOST_CAPS_PHY_RANGE_MASK) + >> SDHCI_UHS2_HOST_CAPS_PHY_RANGE_SHIFT; + mmc->uhs2_caps.n_lss_sync = + (caps_phy & SDHCI_UHS2_HOST_CAPS_PHY_N_LSS_SYN_MASK) + >> SDHCI_UHS2_HOST_CAPS_PHY_N_LSS_SYN_SHIFT; + mmc->uhs2_caps.n_lss_dir = + (caps_phy & SDHCI_UHS2_HOST_CAPS_PHY_N_LSS_DIR_MASK) + >> SDHCI_UHS2_HOST_CAPS_PHY_N_LSS_DIR_SHIFT; + if (mmc->uhs2_caps.n_lss_sync == 0) + mmc->uhs2_caps.n_lss_sync = 16 << 2; + else + mmc->uhs2_caps.n_lss_sync <<= 2; + if (mmc->uhs2_caps.n_lss_dir == 0) + mmc->uhs2_caps.n_lss_dir = 16 << 3; + else + mmc->uhs2_caps.n_lss_dir <<= 3; + + /* LINK/TRAN Caps */ + mmc->uhs2_caps.link_rev = + caps_tran[0] & SDHCI_UHS2_HOST_CAPS_TRAN_LINK_REV_MASK; + mmc->uhs2_caps.n_fcu = + (caps_tran[0] & SDHCI_UHS2_HOST_CAPS_TRAN_N_FCU_MASK) + >> SDHCI_UHS2_HOST_CAPS_TRAN_N_FCU_SHIFT; + if (mmc->uhs2_caps.n_fcu == 0) + mmc->uhs2_caps.n_fcu = 256; + mmc->uhs2_caps.host_type = + (caps_tran[0] & SDHCI_UHS2_HOST_CAPS_TRAN_HOST_TYPE_MASK) + >> SDHCI_UHS2_HOST_CAPS_TRAN_HOST_TYPE_SHIFT; + mmc->uhs2_caps.maxblk_len = + (caps_tran[0] & SDHCI_UHS2_HOST_CAPS_TRAN_BLK_LEN_MASK) + >> SDHCI_UHS2_HOST_CAPS_TRAN_BLK_LEN_SHIFT; + mmc->uhs2_caps.n_data_gap = + caps_tran[1] & SDHCI_UHS2_HOST_CAPS_TRAN_1_N_DATA_GAP_MASK; + + return 0; +} + +static int sdhci_uhs2_do_detect_init(struct mmc_host *mmc) +{ + struct sdhci_host *host = mmc_priv(mmc); + int ret = -EIO; + + DBG("%s: begin UHS2 init.\n", __func__); + + if (sdhci_uhs2_interface_detect(host)) { + pr_warn("%s: cannot detect UHS2 interface.\n", + mmc_hostname(host->mmc)); + goto out; + } + + if (sdhci_uhs2_init(host)) { + pr_warn("%s: UHS2 init fail.\n", mmc_hostname(host->mmc)); + goto out; + } + + /* Init complete, do soft reset and enable UHS2 error irqs. */ + host->ops->uhs2_reset(host, SDHCI_UHS2_SW_RESET_SD); + sdhci_uhs2_clear_set_irqs(host, SDHCI_INT_ALL_MASK, + SDHCI_UHS2_ERR_INT_STATUS_MASK); + /* + * !!! SDHCI_INT_ENABLE and SDHCI_SIGNAL_ENABLE was cleared + * by SDHCI_UHS2_SW_RESET_SD + */ + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); + + ret = 0; +out: + return ret; +} + static int sdhci_uhs2_host_ops_init(struct sdhci_host *host) { host->mmc_host_ops.start_signal_voltage_switch = sdhci_uhs2_start_signal_voltage_switch; host->mmc_host_ops.uhs2_set_ios = sdhci_uhs2_set_ios; + if (!host->mmc_host_ops.uhs2_detect_init) + host->mmc_host_ops.uhs2_detect_init = sdhci_uhs2_do_detect_init; + return 0; } From patchwork Mon Oct 17 09:11:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3315 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347826wrs; Mon, 17 Oct 2022 02:18:31 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6r3C48uGh1z3FXX6XopYcv4w86wBNlgcfulgPn2QXth20AjouZ2R3fJCHG6hP8Otgg+REs X-Received: by 2002:a17:902:be18:b0:178:b9c9:97b8 with SMTP id r24-20020a170902be1800b00178b9c997b8mr10685756pls.38.1665998311692; Mon, 17 Oct 2022 02:18:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998311; cv=none; d=google.com; s=arc-20160816; b=HZvLCGcRciWKoJ/2V4dU8NyQKWYwAIKPcipQZqWpiAT5e80ODaDYadTKWoL4yeWZ+0 TcNLW/wX++PaIAPC/jUG5guzMxRteUljp+VdNcR1yMBfqO5PyWcQWXqrf7zMe95a4JXj KdWE2TK0tTrSJygoEVL/uAPlgh1UcDtQtDSBIEbHVmH+Chy5HTneq6mkL1d0rRlIwAjc dWLN9G/Q+lGJcadTs+Tar5SriSkocYCJy4oTN4v6jSekao+ROYV+ydXC6M1yED/IhWqX lSLstTORasA7IaraCBLhmoGiUf8MqhG7Grab8ankDEOWJ/mecJyAa9L+ic+XBn7bD7Hv 8FMw== 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=tA2UmIKVuRoeoJ0BqAsA6/5RpJhUljcvAx2HKfeYlvY=; b=snuf3VOqh7lyYeZMYGLn+yLbL5Agf8M19UpdZBgq2nVoWwdEIrWaiJYIUWh6ciqDlt TzXGL3t8/+37FsM0H9HW6b3vXSjCzgYOf4VonXm1AXph1y5cAgRHqw53J5e5X3VYJY9l 4pIb0usqi33PVVMqZ9L5wT9UrKwa1zPB3gJ6N6PwgVkGqx0V3//mp16VYiXQpyCivNQ1 PqhKqWVoOoo+EHw888MeHczvzGf0SptRK2sBLcJkbNa7SnENA4SLLgS8cw6E4rP2kKBs a2FaTGUob/ufjz+6NsQcFx+RMj22aUMl+5G42gjzMMxRu74IimzlmuOW7IrMrSsumZkn tJaw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Sr4PYEf5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t18-20020a170902e85200b0017f77922b11si13584685plg.84.2022.10.17.02.18.18; Mon, 17 Oct 2022 02:18:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Sr4PYEf5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231241AbiJQJOW (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33134 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231134AbiJQJN2 (ORCPT ); Mon, 17 Oct 2022 05:13:28 -0400 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C6F14D4D2; Mon, 17 Oct 2022 02:13:09 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id gf8so10400047pjb.5; Mon, 17 Oct 2022 02:13:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=tA2UmIKVuRoeoJ0BqAsA6/5RpJhUljcvAx2HKfeYlvY=; b=Sr4PYEf5wQLycM2jIu7gAXfNqeWkBXd3bQDKSgDYmZdhEVQ8hffMW2O/3E9d4DDSIS iMX+EcW/+mPQqM1dVtavf9vl3PGl8J6qCMZvdIPlOsOChUj0dvxu0VB54pkhJ7WEPWU1 xfnMhX/zH2bU1haCFaJUxubX6NMIOfXB9EXMWkYRuhIaqyKan8QFMFPbYnEN37ll73oV KWYKcv3jgtBSQCisqgHkFhwVVkx0WF4odL3BBVmRk8szRD0fqCPn96Bz7MMaZONa5l2r P0snWRJ/vih/+ddPui3dVR7uHK/xis17kSaE8uENx5jS8XFh3qNZQ49rIeLQXYB5lOAZ oVfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=tA2UmIKVuRoeoJ0BqAsA6/5RpJhUljcvAx2HKfeYlvY=; b=fKFTr9866xPjb8VdM/kBQxsjqSsmB8GIlG8Vy3kD7YwZuFLChHd2c8IDPi+cQokdTd evjuxhWTFCoP/CXZHJHPpSA4gfiKJlU3E975YFN9ExiwopcDUY7aYZCrn7zHf3UER+8D v8NKmdTlDMpQtVy9Xowr6jTAz6GQ6bw0L2KHXGXtd9oR/cliEzOY2KZUGe/Tk32yqi21 +e825dVStsc6kUPXG/J0/VIiJJ4+Qcj4VY43UScFY1HJf/G+jehWQv3f1KCn1V0geWju VpWvJePcOc/Ve+HzaehD/NC7OxjpDBddsW2p06Px28KNvVA+JXjGVryyYtn0VahCB6W+ bxvw== X-Gm-Message-State: ACrzQf2HT4HErVoYFpOzTm+IoLsR8FTKegNcz4/y04i07Cvp+nbPJpKn UbpRxi6asc3ak8qioLc9SUI= X-Received: by 2002:a17:90b:17c7:b0:20b:7cb:9397 with SMTP id me7-20020a17090b17c700b0020b07cb9397mr26969871pjb.191.1665997981401; Mon, 17 Oct 2022 02:13:01 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.12.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:00 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 17/26] mmc: sdhci-uhs2: add clock operations Date: Mon, 17 Oct 2022 17:11:44 +0800 Message-Id: <20221017091153.454873-18-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925845504595931?= X-GMAIL-MSGID: =?utf-8?q?1746925845504595931?= This is a sdhci version of mmc's uhs2_[enable|disable]_clk operations. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 145508918486..3f3665d7990c 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -11,6 +11,7 @@ */ #include +#include #include #include "sdhci.h" @@ -403,6 +404,37 @@ int sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) return 0; } +static int sdhci_uhs2_disable_clk(struct mmc_host *mmc) +{ + struct sdhci_host *host = mmc_priv(mmc); + u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + + clk &= ~SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + + return 0; +} + +static int sdhci_uhs2_enable_clk(struct mmc_host *mmc) +{ + struct sdhci_host *host = mmc_priv(mmc); + u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + u32 val; + /* 20ms */ + int timeout_us = 20000; + + clk |= SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + + if (read_poll_timeout_atomic(sdhci_readw, val, (val & SDHCI_CLOCK_INT_STABLE), + 10, timeout_us, true, host, SDHCI_CLOCK_CONTROL)) { + pr_err("%s: Internal clock never stabilised.\n", mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + return 1; + } + return 0; +} + /*****************************************************************************\ * * * Driver init/exit * @@ -564,6 +596,10 @@ static int sdhci_uhs2_host_ops_init(struct sdhci_host *host) if (!host->mmc_host_ops.uhs2_detect_init) host->mmc_host_ops.uhs2_detect_init = sdhci_uhs2_do_detect_init; + if (!host->mmc_host_ops.uhs2_disable_clk) + host->mmc_host_ops.uhs2_disable_clk = sdhci_uhs2_disable_clk; + if (!host->mmc_host_ops.uhs2_enable_clk) + host->mmc_host_ops.uhs2_enable_clk = sdhci_uhs2_enable_clk; return 0; } From patchwork Mon Oct 17 09:11:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3317 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348118wrs; Mon, 17 Oct 2022 02:19:22 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6xLCc7y+PLNkzTIQfszFUYPAnqhS414F7uZhKAPVhsQv8WNqz4V2rWFd0FSGZU1ybuZoXe X-Received: by 2002:a17:90a:f2c3:b0:20b:b75f:2f9e with SMTP id gt3-20020a17090af2c300b0020bb75f2f9emr32620398pjb.43.1665998362542; Mon, 17 Oct 2022 02:19:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998362; cv=none; d=google.com; s=arc-20160816; b=U4tTVFKF/Fc+tG9wMWM1+Y4WZ3AN01LbNUD23E28zrNxqh9n4ZHNLtw5qgkyKXPG2p NLBelgDhTfoLbGwVQiscAf4C36T8a3+tLPC91dWFfhJZZRNgi+S8PMs2o9lNiOI+OFEK F1Ny7JwSH5xWefBGid2qFGg9n5758iLfzvyLTUWubc/b8YsWCl0p3JhSwvDmp1FXPZnw hy2cQHymW7vbf+qUK/5pnAXZy6lUuMJh53Pgw8UAvXxsdnWHcZy4W0lP6I0KUr0ns1H+ w3EnA2pGvZYLRWfF9FYoBtQxNhdtEYiijQe1rGHVBmNG145iaxCUrwye/xw0cGRm8KH7 r78w== 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=kUtXR1NdrKHcUH0qXdCpzNzpBEVeqH48oqp/hW6UgTQ=; b=JGr1/grPBmbHiRGniK2zq09nc7xiAMszJMc8Gg+JG9DsefuEwfYRO08/3MOlnk8MdJ WDTZags6G9kcVlzcVRitNbXzcRNypLXMW2+3nNMPwJACqKcjVK6O0TGhg2RPZ72rghn/ Tmg3A8EUyByJ2cMTQ6IA96oyrcQ85al02J6JFd36s/IMOnyTjZmOZIjWh9x8M/5f6z2i e3J+DkJQPZf8pWGctx5ChoQ9IK2cm9wAmz/B6Qhj4/vQth7WWANWyh0ZxVAyZbscYJo3 gaNquyJD37HO+HHhbVlWh5MPOcO3z3JCHUMrzyrHs/vbUETyfJcvXMjNEffYw7ERuqNq b06Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Wn3Q8CXv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w4-20020a656944000000b00460cb60836esi11926745pgq.659.2022.10.17.02.19.10; Mon, 17 Oct 2022 02:19:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Wn3Q8CXv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231258AbiJQJOi (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231261AbiJQJNi (ORCPT ); Mon, 17 Oct 2022 05:13:38 -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 0A8812C664; Mon, 17 Oct 2022 02:13:14 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id l1so10176034pld.13; Mon, 17 Oct 2022 02:13:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=kUtXR1NdrKHcUH0qXdCpzNzpBEVeqH48oqp/hW6UgTQ=; b=Wn3Q8CXvYg75gio63Y4dAHqHZjjXEYjhqGjG6N4H5RYlbZMQXueoBbYxR2wUNcGrjB 916MahvNqMy98LEL/Ho1Hi2nU3RSFUygj1hZr2t7I13zAsU7dELi0Qv7q/vMU99eiIr6 9B9gbAzRA2q/dASxSuaLPjEFCiVGXb5BkXQWlqiLmo8Wt5oeOIDcxM9gsDw/lXudxKOg K8DFmQ8y2wZL6q1G2v2FoyucmQM8h7mkfuNhuND8je0HLQEdoiVdtxFY0I8n/CLgwk1C ZddCJabYDT1fSjVKeTGSYPrCL9F6+BxPHCUKq5IUqs3R7ayjAKAHYEQ3iZB5R6lwFdl3 Bz1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=kUtXR1NdrKHcUH0qXdCpzNzpBEVeqH48oqp/hW6UgTQ=; b=hSchLdZB5C15zsKNsd8oelKKZSvQ1NKvSqWWWoSvLu5pjdcMLKPOHQ1F2qoa+lNX6Q hJ33eTcD8793elWoRNOXGKo9Q3RvLqYdzgEuD+lp+15YB7PLb/yPlZf+Ne0VEYdRgZ1D AGhgIbeXyY2BAQh8FgT2SVD0DNFRk+o6Y6aaXCvyuQrcOEIh7+4+YpQpQfMXAi35BYgy K8UxOtEgOUOXShbWyNFul6suuQ+qZQJQ9p5u9OOFKAW8QMrBYm99Jx3gzkLNAa1rngEM b8UFmbptEG8vtkF9L/tQoWXbz+1kKGnKN9WGC0/l6QyCi/SUOvTtWHhmhfyeiv5eVfP+ +bsQ== X-Gm-Message-State: ACrzQf3WEw0NpQspLK+AV9sPeJfbBnzE0b5z9qf5bq5sQ4thOCG0T+T8 G34TmkYs3J6FxV4NsPFtkKs= X-Received: by 2002:a17:903:11c8:b0:179:de93:bd7e with SMTP id q8-20020a17090311c800b00179de93bd7emr11052332plh.95.1665997984338; Mon, 17 Oct 2022 02:13:04 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:03 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 18/26] mmc: sdhci-uhs2: add uhs2_control() to initialise the interface Date: Mon, 17 Oct 2022 17:11:45 +0800 Message-Id: <20221017091153.454873-19-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925898875673838?= X-GMAIL-MSGID: =?utf-8?q?1746925898875673838?= This is a sdhci version of mmc's uhs2_set_reg operation. UHS-II interface (related registers) will be initialised here. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 115 ++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 3f3665d7990c..b0e6403ed31f 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -350,6 +350,65 @@ static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) spin_unlock_irqrestore(&host->lock, flags); } +/* TODO: move this function to sdhci.c */ +static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set) +{ + u32 ier; + + ier = sdhci_readl(host, SDHCI_INT_ENABLE); + ier &= ~clear; + ier |= set; + sdhci_writel(host, ier, SDHCI_INT_ENABLE); + sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE); +} + +static void sdhci_uhs2_set_config(struct sdhci_host *host) +{ + u32 value; + u16 sdhci_uhs2_set_ptr = sdhci_readw(host, SDHCI_UHS2_SET_PTR); + u16 sdhci_uhs2_gen_set_reg = (sdhci_uhs2_set_ptr + 0); + u16 sdhci_uhs2_phy_set_reg = (sdhci_uhs2_set_ptr + 4); + u16 sdhci_uhs2_tran_set_reg = (sdhci_uhs2_set_ptr + 8); + u16 sdhci_uhs2_tran_set_1_reg = (sdhci_uhs2_set_ptr + 12); + + /* Set Gen Settings */ + sdhci_writel(host, host->mmc->uhs2_caps.n_lanes_set << + SDHCI_UHS2_GEN_SET_N_LANES_POS, sdhci_uhs2_gen_set_reg); + + /* Set PHY Settings */ + value = (host->mmc->uhs2_caps.n_lss_dir_set << + SDHCI_UHS2_PHY_SET_N_LSS_DIR_POS) | + (host->mmc->uhs2_caps.n_lss_sync_set << + SDHCI_UHS2_PHY_SET_N_LSS_SYN_POS); + if (host->mmc->flags & MMC_UHS2_SPEED_B) + value |= 1 << SDHCI_UHS2_PHY_SET_SPEED_POS; + sdhci_writel(host, value, sdhci_uhs2_phy_set_reg); + + /* Set LINK-TRAN Settings */ + value = (host->mmc->uhs2_caps.max_retry_set << + SDHCI_UHS2_TRAN_SET_RETRY_CNT_POS) | + (host->mmc->uhs2_caps.n_fcu_set << + SDHCI_UHS2_TRAN_SET_N_FCU_POS); + sdhci_writel(host, value, sdhci_uhs2_tran_set_reg); + sdhci_writel(host, host->mmc->uhs2_caps.n_data_gap_set, + sdhci_uhs2_tran_set_1_reg); +} + +static int sdhci_uhs2_check_dormant(struct sdhci_host *host) +{ + u32 val; + /* 100ms */ + int timeout = 100000; + + if (read_poll_timeout_atomic(sdhci_readl, val, (val & SDHCI_UHS2_IN_DORMANT_STATE), + 100, timeout, true, host, SDHCI_PRESENT_STATE)) { + pr_warn("%s: UHS2 IN_DORMANT fail in 100ms.\n", mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + return -EIO; + } + return 0; +} + /*****************************************************************************\ * * * MMC callbacks * @@ -435,6 +494,61 @@ static int sdhci_uhs2_enable_clk(struct mmc_host *mmc) return 0; } +static int sdhci_uhs2_do_detect_init(struct mmc_host *mmc); + +static int sdhci_uhs2_control(struct mmc_host *mmc, enum sd_uhs2_operation op) +{ + struct sdhci_host *host = mmc_priv(mmc); + unsigned long flags; + int err = 0; + u16 sdhci_uhs2_set_ptr = sdhci_readw(host, SDHCI_UHS2_SET_PTR); + u16 sdhci_uhs2_phy_set_reg = (sdhci_uhs2_set_ptr + 4); + + DBG("Begin %s, act %d.\n", __func__, op); + + spin_lock_irqsave(&host->lock, flags); + + switch (op) { + case UHS2_PHY_INIT: + err = sdhci_uhs2_do_detect_init(mmc); + break; + case UHS2_SET_CONFIG: + sdhci_uhs2_set_config(host); + break; + case UHS2_ENABLE_INT: + sdhci_clear_set_irqs(host, 0, SDHCI_INT_CARD_INT); + break; + case UHS2_DISABLE_INT: + sdhci_clear_set_irqs(host, SDHCI_INT_CARD_INT, 0); + break; + case UHS2_SET_SPEED_B: + sdhci_writeb(host, 1 << SDHCI_UHS2_PHY_SET_SPEED_POS, + sdhci_uhs2_phy_set_reg); + break; + case UHS2_CHECK_DORMANT: + err = sdhci_uhs2_check_dormant(host); + break; + case UHS2_DISABLE_CLK: + err = sdhci_uhs2_disable_clk(mmc); + break; + case UHS2_ENABLE_CLK: + err = sdhci_uhs2_enable_clk(mmc); + break; + case UHS2_POST_ATTACH_SD: + host->ops->uhs2_post_attach_sd(host); + break; + default: + pr_err("%s: input sd uhs2 operation %d is wrong!\n", + mmc_hostname(host->mmc), op); + err = -EIO; + break; + } + + spin_unlock_irqrestore(&host->lock, flags); + + return err; +} + /*****************************************************************************\ * * * Driver init/exit * @@ -593,6 +707,7 @@ static int sdhci_uhs2_host_ops_init(struct sdhci_host *host) host->mmc_host_ops.start_signal_voltage_switch = sdhci_uhs2_start_signal_voltage_switch; host->mmc_host_ops.uhs2_set_ios = sdhci_uhs2_set_ios; + host->mmc_host_ops.uhs2_control = sdhci_uhs2_control; if (!host->mmc_host_ops.uhs2_detect_init) host->mmc_host_ops.uhs2_detect_init = sdhci_uhs2_do_detect_init; From patchwork Mon Oct 17 09:11:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3322 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348509wrs; Mon, 17 Oct 2022 02:20:44 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6fEn/+SaDh0srld6jfPsgpxVtQ+ngUkP8GWVVIScQ4CBZAltzaV4R1+yQ0Ifue5Mi2808L X-Received: by 2002:a17:90b:3891:b0:20d:59e3:1f4f with SMTP id mu17-20020a17090b389100b0020d59e31f4fmr12492466pjb.21.1665998444508; Mon, 17 Oct 2022 02:20:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998444; cv=none; d=google.com; s=arc-20160816; b=VJ7SDWNaUs2WSXxHt+R6gCttqRoet7sysFM8SKtkMxIQaCohvWI18zcvXF0xMhjYcE e8VqK/HR/Tb864WOMQOCsoLiaU645zzhxlkPxDxP8stxyCHTK13amucNBnqieFYzSUTT rzsZ1G9oBLeikJTgpSprYr7aO6oNDIz0lBJnuhP3mT0c7Il210w7FCEpWa7rrOtIMAh4 3aK0CR2CbubkMEq+1ol6SKJzhym3vMZ8Oeuo0kah6l2SqH/Z/0b7RcLOVzTeupgiNE6+ in/ZF3l2tML6EPO06eEpuJI9Sk2pbb0foOkelk5tx2xv1zDpIHPicwaihSGMina1ill1 pynQ== 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=k/GsVF8/ecL0LMiKZf7zN7aRzeHPZMb79CdA4rPpYMI=; b=FGHEzITvCcWmZhaSpFa7d9rQ9iQ5WBCwqAq9oGLKPlF7DzNIH01YanlSpsVBvrnH5e 1O1puXA77womVhBpDiml4IujCP9+ufnKzGcG4+YRlYFnCSCmQzLaPfUbymvEceZU9HFE efvrMFZFwNMlCYXrZz8qhlnOIKBLHJZCaC/hpNoDpw58val6xTTsogOn+MXHXPzpFH3j cO4wrGF9Op4YA4eb8cTb0fvMLfZC2nNJj+0AzgtL3JzJvgpxLGRbvKKZsl6F1P9zfiEE xvYEHemMQ/L9LRvvSwB5/j56bNfRCWMzdixOPSilhjCxSm/TaEe9rQd3wz6RR2TIgEHN Po4g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=kE7Ffrhz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id oj8-20020a17090b4d8800b00202dd7a4d3csi13123489pjb.113.2022.10.17.02.20.31; Mon, 17 Oct 2022 02:20:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=kE7Ffrhz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230181AbiJQJOy (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32772 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231135AbiJQJOA (ORCPT ); Mon, 17 Oct 2022 05:14:00 -0400 Received: from mail-qv1-xf2e.google.com (mail-qv1-xf2e.google.com [IPv6:2607:f8b0:4864:20::f2e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42B6B4F3B9; Mon, 17 Oct 2022 02:13:23 -0700 (PDT) Received: by mail-qv1-xf2e.google.com with SMTP id f14so7056597qvo.3; Mon, 17 Oct 2022 02:13:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=k/GsVF8/ecL0LMiKZf7zN7aRzeHPZMb79CdA4rPpYMI=; b=kE7FfrhzkeKKirR25O4/Jv6A3BKrOstRKaBBkDGG5mXlK9XV4XPkMphZlvt1elpn1d NK8HOlp1HM9bEul0y/jLWlm7OAyQiIj4xQsHbaPS0ZluVmVo8FhDnFj9azET2ZkvY4t3 z6xfPRLpVXofQIKm8XroSvCdBnEYsQA1dBmD7P9RFU4x6i/tvLtahq0Hc1SKw4fBnL64 TmRr90YEnmjCVRSVdC5VcKPJvpAxbVYU4a6Rf5qrysJa5mo1ztBGDZjKlBJZck0k5m+F DkFOc/EbDfQb7djB/He/mvaHiSL4JXZ05GHm+2x8HW1aYTGndj/si5LyiVuf+k4h/yIc jibA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=k/GsVF8/ecL0LMiKZf7zN7aRzeHPZMb79CdA4rPpYMI=; b=dR2CuwBxnzhsODvbcOnjP0zWwlJb7s1ai2wEKjrJF9R5VbU+I91LPYFJdPUpFFOWWE Nb75Bay8eY/Dvxt9lXkqsrWfCQVZCQfDR0aHK1vmbmsek4vT9Ny9DUJWe+wOGSiYP33A 6sTO1vK2j3Qu4Ios0WH3oQgY/Ao0F9zYHmK0N7ebk/T5tzp0k9ZFUO3wYFI5Dc8pD1r4 kHTXmvchXAOFVRZGWSoQUOUnzDFsnDiloEHsP+PkXausS8UPQwPNiTso/awjm03JBmPr K0iPi1c0iGqK9qGBzzC5etlgsPfOmrZD6y8jTk3yq47uiZ9rKZuOQpculSj311P2JsLw 5E8g== X-Gm-Message-State: ACrzQf3kLJ7MpErCMu3XzY4yerkOeNNKVR6nGfDzzzNpB7MYi+RbOspY I/cN9ELzhB1gXZi2FF4FApF+NpSedOo= X-Received: by 2002:a17:902:ed93:b0:185:4421:24b with SMTP id e19-20020a170902ed9300b001854421024bmr10852374plj.158.1665997987302; Mon, 17 Oct 2022 02:13:07 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:06 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 19/26] mmc: sdhci-uhs2: add request() and others Date: Mon, 17 Oct 2022 17:11:46 +0800 Message-Id: <20221017091153.454873-20-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925984588179964?= X-GMAIL-MSGID: =?utf-8?q?1746925984588179964?= This is a sdhci version of mmc's request operation. It covers both UHS-I and UHS-II. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 475 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c | 93 ++++--- drivers/mmc/host/sdhci.h | 17 ++ 3 files changed, 552 insertions(+), 33 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index b0e6403ed31f..b269593e9b08 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "sdhci.h" #include "sdhci-uhs2.h" @@ -549,6 +550,479 @@ static int sdhci_uhs2_control(struct mmc_host *mmc, enum sd_uhs2_operation op) return err; } +/*****************************************************************************\ + * * + * Core functions * + * * +\*****************************************************************************/ + +static void sdhci_uhs2_prepare_data(struct sdhci_host *host, + struct mmc_command *cmd) +{ + struct mmc_data *data = cmd->data; + + sdhci_initialize_data(host, data); + + sdhci_prepare_dma(host, data); + + sdhci_writew(host, data->blksz, SDHCI_UHS2_BLOCK_SIZE); + sdhci_writew(host, data->blocks, SDHCI_UHS2_BLOCK_COUNT); +} + +#if IS_ENABLED(CONFIG_MMC_SDHCI_EXTERNAL_DMA) +static void sdhci_uhs2_external_dma_prepare_data(struct sdhci_host *host, + struct mmc_command *cmd) +{ + if (!sdhci_external_dma_setup(host, cmd)) { + __sdhci_external_dma_prepare_data(host, cmd); + } else { + sdhci_external_dma_release(host); + pr_err("%s: Cannot use external DMA, switch to the DMA/PIO which standard SDHCI provides.\n", + mmc_hostname(host->mmc)); + sdhci_uhs2_prepare_data(host, cmd); + } +} +#else +static inline void sdhci_uhs2_external_dma_prepare_data(struct sdhci_host *host, + struct mmc_command *cmd) +{ + /* This should never happen */ + WARN_ON_ONCE(1); +} + +static inline void sdhci_external_dma_pre_transfer(struct sdhci_host *host, + struct mmc_command *cmd) +{ +} +#endif /* CONFIG_MMC_SDHCI_EXTERNAL_DMA */ + +static void sdhci_uhs2_finish_data(struct sdhci_host *host) +{ + struct mmc_data *data = host->data; + + __sdhci_finish_data_common(host); + + /* + * FIXME: Is this condition needed? + if (host->mmc->flags & MMC_UHS2_INITIALIZED) + */ + __sdhci_finish_mrq(host, data->mrq); +} + +static void sdhci_uhs2_set_transfer_mode(struct sdhci_host *host, + struct mmc_command *cmd) +{ + u16 mode; + struct mmc_data *data = cmd->data; + u16 arg; + + if (!data) { + /* clear Auto CMD settings for no data CMDs */ + arg = cmd->uhs2_cmd->arg; + if ((((arg & 0xF) << 8) | ((arg >> 8) & 0xFF)) == + UHS2_DEV_CMD_TRANS_ABORT) { + mode = 0; + } else { + mode = sdhci_readw(host, SDHCI_UHS2_TRANS_MODE); + if (cmd->opcode == MMC_STOP_TRANSMISSION || + cmd->opcode == MMC_ERASE) + mode |= SDHCI_UHS2_TRNS_WAIT_EBSY; + else + /* send status mode */ + if (cmd->opcode == MMC_SEND_STATUS) + mode = 0; + } + + if (IS_ENABLED(CONFIG_MMC_DEBUG)) + DBG("UHS2 no data trans mode is 0x%x.\n", mode); + + sdhci_writew(host, mode, SDHCI_UHS2_TRANS_MODE); + return; + } + + WARN_ON(!host->data); + + mode = SDHCI_UHS2_TRNS_BLK_CNT_EN | SDHCI_UHS2_TRNS_WAIT_EBSY; + if (data->flags & MMC_DATA_WRITE) + mode |= SDHCI_UHS2_TRNS_DATA_TRNS_WRT; + + if (data->blocks == 1 && + data->blksz != 512 && + cmd->opcode != MMC_READ_SINGLE_BLOCK && + cmd->opcode != MMC_WRITE_BLOCK) { + mode &= ~SDHCI_UHS2_TRNS_BLK_CNT_EN; + mode |= SDHCI_UHS2_TRNS_BLK_BYTE_MODE; + } + + if (host->flags & SDHCI_REQ_USE_DMA) + mode |= SDHCI_UHS2_TRNS_DMA; + + if ((host->mmc->uhs2_ios.is_2L_HD_mode) && !cmd->uhs2_tmode0_flag) + mode |= SDHCI_UHS2_TRNS_2L_HD; + + sdhci_writew(host, mode, SDHCI_UHS2_TRANS_MODE); + + if (IS_ENABLED(CONFIG_MMC_DEBUG)) + DBG("UHS2 trans mode is 0x%x.\n", mode); +} + +static void __sdhci_uhs2_send_command(struct sdhci_host *host, + struct mmc_command *cmd) +{ + int i, j; + int cmd_reg; + + if (host->mmc->flags & MMC_UHS2_INITIALIZED) { + if (!cmd->uhs2_cmd) { + pr_err("%s: fatal error, no uhs2_cmd!\n", + mmc_hostname(host->mmc)); + return; + } + } + + i = 0; + sdhci_writel(host, + ((u32)cmd->uhs2_cmd->arg << 16) | + (u32)cmd->uhs2_cmd->header, + SDHCI_UHS2_CMD_PACKET + i); + i += 4; + + /* + * Per spec, playload (config) should be MSB before sending out. + * But we don't need convert here because had set payload as + * MSB when preparing config read/write commands. + */ + for (j = 0; j < cmd->uhs2_cmd->payload_len / sizeof(u32); j++) { + sdhci_writel(host, *(cmd->uhs2_cmd->payload + j), + SDHCI_UHS2_CMD_PACKET + i); + i += 4; + } + + for ( ; i < SDHCI_UHS2_CMD_PACK_MAX_LEN; i += 4) + sdhci_writel(host, 0, SDHCI_UHS2_CMD_PACKET + i); + + if (IS_ENABLED(CONFIG_MMC_DEBUG)) { + DBG("UHS2 CMD packet_len = %d.\n", cmd->uhs2_cmd->packet_len); + for (i = 0; i < cmd->uhs2_cmd->packet_len; i++) + DBG("UHS2 CMD_PACKET[%d] = 0x%x.\n", i, + sdhci_readb(host, SDHCI_UHS2_CMD_PACKET + i)); + } + + cmd_reg = cmd->uhs2_cmd->packet_len << + SDHCI_UHS2_COMMAND_PACK_LEN_SHIFT; + if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) + cmd_reg |= SDHCI_UHS2_COMMAND_DATA; + if (cmd->opcode == MMC_STOP_TRANSMISSION) + cmd_reg |= SDHCI_UHS2_COMMAND_CMD12; + + /* UHS2 Native ABORT */ + if ((cmd->uhs2_cmd->header & UHS2_NATIVE_PACKET) && + ((((cmd->uhs2_cmd->arg & 0xF) << 8) | + ((cmd->uhs2_cmd->arg >> 8) & 0xFF)) == UHS2_DEV_CMD_TRANS_ABORT)) + cmd_reg |= SDHCI_UHS2_COMMAND_TRNS_ABORT; + + /* UHS2 Native DORMANT */ + if ((cmd->uhs2_cmd->header & UHS2_NATIVE_PACKET) && + ((((cmd->uhs2_cmd->arg & 0xF) << 8) | + ((cmd->uhs2_cmd->arg >> 8) & 0xFF)) == + UHS2_DEV_CMD_GO_DORMANT_STATE)) + cmd_reg |= SDHCI_UHS2_COMMAND_DORMANT; + + DBG("0x%x is set to UHS2 CMD register.\n", cmd_reg); + + sdhci_writew(host, cmd_reg, SDHCI_UHS2_COMMAND); +} + +static bool sdhci_uhs2_send_command(struct sdhci_host *host, + struct mmc_command *cmd) +{ + int flags; + u32 mask; + unsigned long timeout; + + WARN_ON(host->cmd); + + /* Initially, a command has no error */ + cmd->error = 0; + + if (!(host->mmc->flags & MMC_UHS2_SUPPORT)) + return sdhci_send_command(host, cmd); + + if (cmd->opcode == MMC_STOP_TRANSMISSION) + cmd->flags |= MMC_RSP_BUSY; + + mask = SDHCI_CMD_INHIBIT; + + if (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) + return false; + + host->cmd = cmd; + host->data_timeout = 0; + if (sdhci_data_line_cmd(cmd)) { + WARN_ON(host->data_cmd); + host->data_cmd = cmd; + __sdhci_uhs2_set_timeout(host); + } + + if (cmd->data) { + if (host->use_external_dma) + sdhci_uhs2_external_dma_prepare_data(host, cmd); + else + sdhci_uhs2_prepare_data(host, cmd); + } + + sdhci_uhs2_set_transfer_mode(host, cmd); + + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { + WARN_ONCE(1, "Unsupported response type!\n"); + /* + * This does not happen in practice because 136-bit response + * commands never have busy waiting, so rather than complicate + * the error path, just remove busy waiting and continue. + */ + cmd->flags &= ~MMC_RSP_BUSY; + } + + if (!(cmd->flags & MMC_RSP_PRESENT)) + flags = SDHCI_CMD_RESP_NONE; + else if (cmd->flags & MMC_RSP_136) + flags = SDHCI_CMD_RESP_LONG; + else if (cmd->flags & MMC_RSP_BUSY) + flags = SDHCI_CMD_RESP_SHORT_BUSY; + else + flags = SDHCI_CMD_RESP_SHORT; + + if (cmd->flags & MMC_RSP_CRC) + flags |= SDHCI_CMD_CRC; + if (cmd->flags & MMC_RSP_OPCODE) + flags |= SDHCI_CMD_INDEX; + + timeout = jiffies; + if (host->data_timeout) + timeout += nsecs_to_jiffies(host->data_timeout); + else if (!cmd->data && cmd->busy_timeout > 9000) + timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; + else + timeout += 10 * HZ; + sdhci_mod_timer(host, cmd->mrq, timeout); + + if (host->use_external_dma) + sdhci_external_dma_pre_transfer(host, cmd); + + __sdhci_uhs2_send_command(host, cmd); + + return true; +} + +static bool sdhci_uhs2_send_command_retry(struct sdhci_host *host, + struct mmc_command *cmd, + unsigned long flags) + __releases(host->lock) + __acquires(host->lock) +{ + struct mmc_command *deferred_cmd = host->deferred_cmd; + int timeout = 10; /* Approx. 10 ms */ + bool present; + + while (!sdhci_uhs2_send_command(host, cmd)) { + if (!timeout--) { + pr_err("%s: Controller never released inhibit bit(s).\n", + mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + cmd->error = -EIO; + return false; + } + + spin_unlock_irqrestore(&host->lock, flags); + + usleep_range(1000, 1250); + + present = host->mmc->ops->get_cd(host->mmc); + + spin_lock_irqsave(&host->lock, flags); + + /* A deferred command might disappear, handle that */ + if (cmd == deferred_cmd && cmd != host->deferred_cmd) + return true; + + if (sdhci_present_error(host, cmd, present)) + return false; + } + + if (cmd == host->deferred_cmd) + host->deferred_cmd = NULL; + + return true; +} + +static void __sdhci_uhs2_finish_command(struct sdhci_host *host) +{ + struct mmc_command *cmd = host->cmd; + u8 resp; + u8 ecode; + bool bReadA0 = 0; + int i; + + if (host->mmc->flags & MMC_UHS2_INITIALIZED) { + resp = sdhci_readb(host, SDHCI_UHS2_RESPONSE + 2); + if (resp & UHS2_RES_NACK_MASK) { + ecode = (resp >> UHS2_RES_ECODE_POS) & + UHS2_RES_ECODE_MASK; + pr_err("%s: NACK is got, ECODE=0x%x.\n", + mmc_hostname(host->mmc), ecode); + } + bReadA0 = 1; + } + + if (cmd->uhs2_resp && + cmd->uhs2_resp_len && cmd->uhs2_resp_len <= 20) { + /* Get whole response of some native CCMD, like + * DEVICE_INIT, ENUMERATE. + */ + for (i = 0; i < cmd->uhs2_resp_len; i++) + cmd->uhs2_resp[i] = + sdhci_readb(host, SDHCI_UHS2_RESPONSE + i); + } else { + /* Get SD CMD response and Payload for some read + * CCMD, like INQUIRY_CFG. + */ + /* Per spec (p136), payload field is divided into + * a unit of DWORD and transmission order within + * a DWORD is big endian. + */ + if (!bReadA0) + sdhci_readl(host, SDHCI_UHS2_RESPONSE); + for (i = 4; i < 20; i += 4) { + cmd->resp[i / 4 - 1] = + (sdhci_readb(host, + SDHCI_UHS2_RESPONSE + i) << 24) | + (sdhci_readb(host, + SDHCI_UHS2_RESPONSE + i + 1) + << 16) | + (sdhci_readb(host, + SDHCI_UHS2_RESPONSE + i + 2) + << 8) | + sdhci_readb(host, SDHCI_UHS2_RESPONSE + i + 3); + } + } +} + +static void sdhci_uhs2_finish_command(struct sdhci_host *host) +{ + struct mmc_command *cmd = host->cmd; + + /* FIXME: Is this check necessary? */ + if (!(host->mmc->flags & MMC_UHS2_SUPPORT)) { + sdhci_finish_command(host); + return; + } + + __sdhci_uhs2_finish_command(host); + + host->cmd = NULL; + + if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd) + mmc_command_done(host->mmc, cmd->mrq); + + /* + * The host can send and interrupt when the busy state has + * ended, allowing us to wait without wasting CPU cycles. + * The busy signal uses DAT0 so this is similar to waiting + * for data to complete. + * + * Note: The 1.0 specification is a bit ambiguous about this + * feature so there might be some problems with older + * controllers. + */ + if (cmd->flags & MMC_RSP_BUSY) { + if (cmd->data) { + DBG("Cannot wait for busy signal when also doing a data transfer"); + } else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) && + cmd == host->data_cmd) { + /* Command complete before busy is ended */ + return; + } + } + + /* Processed actual command. */ + if (host->data && host->data_early) + sdhci_uhs2_finish_data(host); + + if (!cmd->data) + __sdhci_finish_mrq(host, cmd->mrq); +} + +void sdhci_uhs2_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct sdhci_host *host = mmc_priv(mmc); + struct mmc_command *cmd; + unsigned long flags; + bool present; + + /* FIXME: check more flags? */ + if (!(sdhci_uhs2_mode(host))) { + sdhci_request(mmc, mrq); + return; + } + + /* Firstly check card presence */ + present = mmc->ops->get_cd(mmc); + + spin_lock_irqsave(&host->lock, flags); + + if (sdhci_present_error(host, mrq->cmd, present)) + goto out_finish; + + cmd = mrq->cmd; + + if (!sdhci_uhs2_send_command(host, cmd)) + goto out_finish; + + spin_unlock_irqrestore(&host->lock, flags); + + return; + +out_finish: + sdhci_finish_mrq(host, mrq); + spin_unlock_irqrestore(&host->lock, flags); +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_request); + +int sdhci_uhs2_request_atomic(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct sdhci_host *host = mmc_priv(mmc); + struct mmc_command *cmd; + unsigned long flags; + int ret = 0; + + if (!host->mmc->flags & MMC_UHS2_SUPPORT) + return sdhci_request_atomic(mmc, mrq); + + spin_lock_irqsave(&host->lock, flags); + + if (sdhci_present_error(host, mrq->cmd, true)) { + sdhci_finish_mrq(host, mrq); + goto out_finish; + } + + cmd = mrq->cmd; + + /* + * The HSQ may send a command in interrupt context without polling + * the busy signaling, which means we should return BUSY if controller + * has not released inhibit bits to allow HSQ trying to send request + * again in non-atomic context. So we should not finish this request + * here. + */ + if (!sdhci_uhs2_send_command(host, cmd)) + ret = -EBUSY; + +out_finish: + spin_unlock_irqrestore(&host->lock, flags); + return ret; +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_request_atomic); + /*****************************************************************************\ * * * Driver init/exit * @@ -708,6 +1182,7 @@ static int sdhci_uhs2_host_ops_init(struct sdhci_host *host) sdhci_uhs2_start_signal_voltage_switch; host->mmc_host_ops.uhs2_set_ios = sdhci_uhs2_set_ios; host->mmc_host_ops.uhs2_control = sdhci_uhs2_control; + host->mmc_host_ops.request = sdhci_uhs2_request; if (!host->mmc_host_ops.uhs2_detect_init) host->mmc_host_ops.uhs2_detect_init = sdhci_uhs2_do_detect_init; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index af4c7549f7c0..a8458b1f3899 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -47,8 +47,6 @@ static unsigned int debug_quirks = 0; static unsigned int debug_quirks2; -static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd); - void sdhci_dumpregs(struct sdhci_host *host) { SDHCI_DUMP("============ SDHCI REGISTER DUMP ===========\n"); @@ -147,10 +145,13 @@ void sdhci_enable_v4_mode(struct sdhci_host *host) } EXPORT_SYMBOL_GPL(sdhci_enable_v4_mode); -static inline bool sdhci_data_line_cmd(struct mmc_command *cmd) +bool sdhci_data_line_cmd(struct mmc_command *cmd) { return cmd->data || cmd->flags & MMC_RSP_BUSY; } +EXPORT_SYMBOL_GPL(sdhci_data_line_cmd); + +/* TODO: move this as an inline function to a header */ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) { @@ -363,7 +364,7 @@ static void sdhci_reinit(struct sdhci_host *host) mmc_detect_change(host->mmc, msecs_to_jiffies(200)); } -static void __sdhci_led_activate(struct sdhci_host *host) +void __sdhci_led_activate(struct sdhci_host *host) { u8 ctrl; @@ -374,8 +375,9 @@ static void __sdhci_led_activate(struct sdhci_host *host) ctrl |= SDHCI_CTRL_LED; sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } +EXPORT_SYMBOL_GPL(__sdhci_led_activate); -static void __sdhci_led_deactivate(struct sdhci_host *host) +void __sdhci_led_deactivate(struct sdhci_host *host) { u8 ctrl; @@ -386,6 +388,7 @@ static void __sdhci_led_deactivate(struct sdhci_host *host) ctrl &= ~SDHCI_CTRL_LED; sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } +EXPORT_SYMBOL_GPL(__sdhci_led_deactivate); #if IS_REACHABLE(CONFIG_LEDS_CLASS) static void sdhci_led_control(struct led_classdev *led, @@ -464,14 +467,15 @@ static inline void sdhci_led_deactivate(struct sdhci_host *host) #endif -static void sdhci_mod_timer(struct sdhci_host *host, struct mmc_request *mrq, - unsigned long timeout) +void sdhci_mod_timer(struct sdhci_host *host, struct mmc_request *mrq, + unsigned long timeout) { if (sdhci_data_line_cmd(mrq->cmd)) mod_timer(&host->data_timer, timeout); else mod_timer(&host->timer, timeout); } +EXPORT_SYMBOL_GPL(sdhci_mod_timer); static void sdhci_del_timer(struct sdhci_host *host, struct mmc_request *mrq) { @@ -1052,8 +1056,7 @@ static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) __sdhci_set_timeout(host, cmd); } -static void sdhci_initialize_data(struct sdhci_host *host, - struct mmc_data *data) +void sdhci_initialize_data(struct sdhci_host *host, struct mmc_data *data) { WARN_ON(host->data); @@ -1066,6 +1069,7 @@ static void sdhci_initialize_data(struct sdhci_host *host, host->data_early = 0; host->data->bytes_xfered = 0; } +EXPORT_SYMBOL_GPL(sdhci_initialize_data); static inline void sdhci_set_block_info(struct sdhci_host *host, struct mmc_data *data) @@ -1088,12 +1092,8 @@ static inline void sdhci_set_block_info(struct sdhci_host *host, } } -static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) +void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data) { - struct mmc_data *data = cmd->data; - - sdhci_initialize_data(host, data); - if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { struct scatterlist *sg; unsigned int length_mask, offset_mask; @@ -1178,6 +1178,16 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) } sdhci_set_transfer_irqs(host); +} +EXPORT_SYMBOL_GPL(sdhci_prepare_dma); + +static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) +{ + struct mmc_data *data = cmd->data; + + sdhci_initialize_data(host, data); + + sdhci_prepare_dma(host, data); sdhci_set_block_info(host, data); } @@ -1220,8 +1230,7 @@ static struct dma_chan *sdhci_external_dma_channel(struct sdhci_host *host, return data->flags & MMC_DATA_WRITE ? host->tx_chan : host->rx_chan; } -static int sdhci_external_dma_setup(struct sdhci_host *host, - struct mmc_command *cmd) +int sdhci_external_dma_setup(struct sdhci_host *host, struct mmc_command *cmd) { int ret, i; enum dma_transfer_direction dir; @@ -1274,8 +1283,9 @@ static int sdhci_external_dma_setup(struct sdhci_host *host, return ret; } +EXPORT_SYMBOL_GPL(sdhci_external_dma_setup); -static void sdhci_external_dma_release(struct sdhci_host *host) +void sdhci_external_dma_release(struct sdhci_host *host) { if (host->tx_chan) { dma_release_channel(host->tx_chan); @@ -1289,9 +1299,10 @@ static void sdhci_external_dma_release(struct sdhci_host *host) sdhci_switch_external_dma(host, false); } +EXPORT_SYMBOL_GPL(sdhci_external_dma_release); -static void __sdhci_external_dma_prepare_data(struct sdhci_host *host, - struct mmc_command *cmd) +void __sdhci_external_dma_prepare_data(struct sdhci_host *host, + struct mmc_command *cmd) { struct mmc_data *data = cmd->data; @@ -1302,6 +1313,7 @@ static void __sdhci_external_dma_prepare_data(struct sdhci_host *host, sdhci_set_block_info(host, data); } +EXPORT_SYMBOL(__sdhci_external_dma_prepare_data); static void sdhci_external_dma_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) @@ -1316,8 +1328,8 @@ static void sdhci_external_dma_prepare_data(struct sdhci_host *host, } } -static void sdhci_external_dma_pre_transfer(struct sdhci_host *host, - struct mmc_command *cmd) +void sdhci_external_dma_pre_transfer(struct sdhci_host *host, + struct mmc_command *cmd) { struct dma_chan *chan; @@ -1328,6 +1340,7 @@ static void sdhci_external_dma_pre_transfer(struct sdhci_host *host, if (chan) dma_async_issue_pending(chan); } +EXPORT_SYMBOL_GPL(sdhci_external_dma_pre_transfer); #else @@ -1379,11 +1392,11 @@ static inline bool sdhci_auto_cmd23(struct sdhci_host *host, return mrq->sbc && (host->flags & SDHCI_AUTO_CMD23); } -static inline bool sdhci_manual_cmd23(struct sdhci_host *host, - struct mmc_request *mrq) +bool sdhci_manual_cmd23(struct sdhci_host *host, struct mmc_request *mrq) { return mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23); } +EXPORT_SYMBOL_GPL(sdhci_manual_cmd23); static inline void sdhci_auto_cmd_select(struct sdhci_host *host, struct mmc_command *cmd, @@ -1495,7 +1508,7 @@ static void sdhci_set_mrq_done(struct sdhci_host *host, struct mmc_request *mrq) WARN_ON(i >= SDHCI_MAX_MRQS); } -static void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) +void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) { if (host->cmd && host->cmd->mrq == mrq) host->cmd = NULL; @@ -1519,15 +1532,17 @@ static void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) if (!sdhci_has_requests(host)) sdhci_led_deactivate(host); } +EXPORT_SYMBOL_GPL(__sdhci_finish_mrq); -static void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) +void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) { __sdhci_finish_mrq(host, mrq); queue_work(host->complete_wq, &host->complete_work); } +EXPORT_SYMBOL_GPL(sdhci_finish_mrq); -static void __sdhci_finish_data(struct sdhci_host *host, bool sw_data_timeout) +void __sdhci_finish_data_common(struct sdhci_host *host) { struct mmc_command *data_cmd = host->data_cmd; struct mmc_data *data = host->data; @@ -1560,6 +1575,14 @@ static void __sdhci_finish_data(struct sdhci_host *host, bool sw_data_timeout) data->bytes_xfered = 0; else data->bytes_xfered = data->blksz * data->blocks; +} +EXPORT_SYMBOL_GPL(__sdhci_finish_data_common); + +static void __sdhci_finish_data(struct sdhci_host *host, bool sw_data_timeout) +{ + struct mmc_data *data = host->data; + + __sdhci_finish_data_common(host); /* * Need to send CMD12 if - @@ -1598,12 +1621,13 @@ static void __sdhci_finish_data(struct sdhci_host *host, bool sw_data_timeout) } } -static void sdhci_finish_data(struct sdhci_host *host) +void sdhci_finish_data(struct sdhci_host *host) { __sdhci_finish_data(host, false); } +EXPORT_SYMBOL_GPL(sdhci_finish_data); -static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) +bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) { int flags; u32 mask; @@ -1645,8 +1669,6 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) sdhci_prepare_data(host, cmd); } - sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); - sdhci_set_transfer_mode(host, cmd); if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { @@ -1690,13 +1712,16 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) if (host->use_external_dma) sdhci_external_dma_pre_transfer(host, cmd); + sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); + sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); return true; } +EXPORT_SYMBOL_GPL(sdhci_send_command); -static bool sdhci_present_error(struct sdhci_host *host, - struct mmc_command *cmd, bool present) +bool sdhci_present_error(struct sdhci_host *host, + struct mmc_command *cmd, bool present) { if (!present || host->flags & SDHCI_DEVICE_DEAD) { cmd->error = -ENOMEDIUM; @@ -1705,6 +1730,7 @@ static bool sdhci_present_error(struct sdhci_host *host, return false; } +EXPORT_SYMBOL_GPL(sdhci_present_error); static bool sdhci_send_command_retry(struct sdhci_host *host, struct mmc_command *cmd, @@ -1768,7 +1794,7 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd) } } -static void sdhci_finish_command(struct sdhci_host *host) +void sdhci_finish_command(struct sdhci_host *host) { struct mmc_command *cmd = host->cmd; @@ -1821,6 +1847,7 @@ static void sdhci_finish_command(struct sdhci_host *host) __sdhci_finish_mrq(host, cmd->mrq); } } +EXPORT_SYMBOL_GPL(sdhci_finish_command); static u16 sdhci_get_preset_value(struct sdhci_host *host) { diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index dca08aac076d..99f88b0ff4f4 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -852,8 +852,25 @@ static inline void sdhci_read_caps(struct sdhci_host *host) __sdhci_read_caps(host, NULL, NULL, NULL); } +bool sdhci_data_line_cmd(struct mmc_command *cmd); void sdhci_runtime_pm_bus_on(struct sdhci_host *host); void sdhci_runtime_pm_bus_off(struct sdhci_host *host); +void sdhci_mod_timer(struct sdhci_host *host, struct mmc_request *mrq, unsigned long timeout); +void sdhci_initialize_data(struct sdhci_host *host, struct mmc_data *data); +void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data); +#if IS_ENABLED(CONFIG_MMC_SDHCI_EXTERNAL_DMA) +int sdhci_external_dma_setup(struct sdhci_host *host, struct mmc_command *cmd); +void sdhci_external_dma_release(struct sdhci_host *host); +void __sdhci_external_dma_prepare_data(struct sdhci_host *host, struct mmc_command *cmd); +void sdhci_external_dma_pre_transfer(struct sdhci_host *host, struct mmc_command *cmd); +#endif +bool sdhci_manual_cmd23(struct sdhci_host *host, struct mmc_request *mrq); +void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq); +void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq); +void __sdhci_finish_data_common(struct sdhci_host *host); +bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd); +void sdhci_finish_command(struct sdhci_host *host); +bool sdhci_present_error(struct sdhci_host *host, struct mmc_command *cmd, bool present); u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock, unsigned int *actual_clock); void sdhci_set_clock(struct sdhci_host *host, unsigned int clock); From patchwork Mon Oct 17 09:11:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3316 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1347868wrs; Mon, 17 Oct 2022 02:18:39 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7/qkH77/sZiloI5Hof7ZW6qPyT36/jmyVikk4XxToeYgCKg6T5fZwIstMMHKlG0ZfrsmkF X-Received: by 2002:a17:90a:c7cc:b0:20a:c595:16de with SMTP id gf12-20020a17090ac7cc00b0020ac59516demr12450048pjb.201.1665998319497; Mon, 17 Oct 2022 02:18:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998319; cv=none; d=google.com; s=arc-20160816; b=i9Q/EDmEgRQrmskQeRF+gw9Gfzi+8jY0z+FBXAcO4bE4zg8rXlPQphwAlyXHxRfqiG Me4mm07mjHzvSmRbCUMWlE4dtxvBT37plC2yB5tnB2/baE0DCd0QXLUx03isC2K2O692 p9h6RNWTVpx7Ji2X/hoTpqvHvBBsqEi5Z1HomuKXveOwp7CZcQxVJVj0uw3oWbzzmy5U Wy7xBwJ0qq2T/maDhBRwMCmgjg8W012Ow30+B52L/o48rVFxIG1V1DjRT6HnoGcg/tkr gCwyCB2N7aePya/J2tHaXFvC0fTmO3odZYAdi5ijncwokhXPPDVl61bKwGKCkYsbOnsn Ax1g== 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=UdG4MmSrSVXj2AOOOO/+ILrQ0BjQgwzE0+PHc9VPkME=; b=MGPhvbx7NhwWOhFvxbeCrUEsOLAXkraWKIH/+XoZb+meg/9l+wB0+Aslu00Gk8+9T2 LlFVM4DE/qAYeJvWUSCNHu+nxrzWp43drV1fJ7r5TGoJw6iBVkDP5Fg6vwi347WQrWMH YbOjy+H+5lbeAfSkdMu2PD3/B3iMYB2FIx4mM3/8AWRr2qkbt4ptzggj8GhCvqPR02QX OwywqK5xXZ0QvWSxbF0wfQ5eklGGtuRq5ec6yBgNDGxrsNhFeWQjCJ+z8OllaGLmAW1N R9jB7gRWmrAHl4+rJ7wPXBaHBAgTu9UENfTpP8U3tEQ4DnrJbp3d2uLK78tPqfWUxbIz kEBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=BEHvzNKB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ha15-20020a17090af3cf00b00205f49b70fdsi10284035pjb.127.2022.10.17.02.18.26; Mon, 17 Oct 2022 02:18:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=BEHvzNKB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229707AbiJQJOa (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231252AbiJQJNg (ORCPT ); Mon, 17 Oct 2022 05:13:36 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B14E4CA03; Mon, 17 Oct 2022 02:13:19 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id n7so10231874plp.1; Mon, 17 Oct 2022 02:13:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=UdG4MmSrSVXj2AOOOO/+ILrQ0BjQgwzE0+PHc9VPkME=; b=BEHvzNKBUyft5EriIOyv6W1U26wOr6eVAQ0iL9O8shFGcA+a4lj4jZG4PIxOPSSkNw 2NbgfP0U36hjK3PFH+iJaaqWdGBqZD/xdHzv8fnwyfKJAe2OlvRDuJB+0j51jf18h48u XxKvN41FENtGjFRL6+SJsAzRL+PyK1ETkOkJIILZ9Kg5j+TQg094HsYMG7l+yQ5vElZj B7SnOalmKRemFOshItN+JNAA8FlEQfiy1HT5Jio1M9aRmn6aN9duqvU8IHA3jr4NXm1n /KJ18D9bivZblrBhG/ZGV+MDqxYv5RAxivLQ5i5x+bqW3HxKZIDJfRs8951IS5JpExGO Go2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=UdG4MmSrSVXj2AOOOO/+ILrQ0BjQgwzE0+PHc9VPkME=; b=NtT/TbEPHEBnUnhw7yK0uO0xZs2t/ijm5mOM34c4MCO9JKXVCURSdbUCn+ZEvJ9wb7 rKnxcA196ewai0o77rK8Mrt6dHXVQBHcc0jytJJrX1RtPyqds0Ha/zCox9kidBmeAluL RsRoYP+gEXZOY21ipD5zYj1BhJU4OYEJ5hi7y0/ZvDZGGjgMdW8ZiJNSW5DlxHYoO4kW ZDzKsLahS0iBGTKwYBohnzUphU5UQuYUnumXfCv+xMwwMhFWNPDbtFodbhVd5thuomly 8lAW82PzDdp9nZ6uAt5lrlF/lAemWQpKy1IsEcpiSzXKORM2M8aSaIQ0+JhbbYY+bZQx zb3A== X-Gm-Message-State: ACrzQf0RYMmT7DApnkkfg0JeLollRHYEbwkqi7KSkNDl8tjs2PF4B8zs 0S24keCvT/TMGC6iYuzB5tU= X-Received: by 2002:a17:902:b717:b0:184:4a5c:c74a with SMTP id d23-20020a170902b71700b001844a5cc74amr11287446pls.0.1665997990382; Mon, 17 Oct 2022 02:13:10 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:09 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 20/26] mmc: sdhci-uhs2: add irq() and others Date: Mon, 17 Oct 2022 17:11:47 +0800 Message-Id: <20221017091153.454873-21-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925853878063528?= X-GMAIL-MSGID: =?utf-8?q?1746925853878063528?= This is a UHS-II version of sdhci's request() operation. It handles UHS-II related command interrupts and errors. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 246 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 3 + drivers/mmc/host/sdhci.c | 106 ++++++++------- drivers/mmc/host/sdhci.h | 5 + 4 files changed, 313 insertions(+), 47 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index b269593e9b08..452cd9165cdf 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -594,6 +595,12 @@ static inline void sdhci_external_dma_pre_transfer(struct sdhci_host *host, struct mmc_command *cmd) { } + +static inline struct dma_chan *sdhci_external_dma_channel(struct sdhci_host *host, + struct mmc_data *data) +{ + return NULL; +} #endif /* CONFIG_MMC_SDHCI_EXTERNAL_DMA */ static void sdhci_uhs2_finish_data(struct sdhci_host *host) @@ -952,6 +959,245 @@ static void sdhci_uhs2_finish_command(struct sdhci_host *host) __sdhci_finish_mrq(host, cmd->mrq); } +/*****************************************************************************\ + * * + * Request done * + * * +\*****************************************************************************/ + +static bool sdhci_uhs2_request_done(struct sdhci_host *host) +{ + unsigned long flags; + struct mmc_request *mrq; + int i; + + /* FIXME: UHS2_INITIALIZED, instead? */ + if (!(host->mmc->flags & MMC_UHS2_SUPPORT)) + return sdhci_request_done(host); + + spin_lock_irqsave(&host->lock, flags); + + for (i = 0; i < SDHCI_MAX_MRQS; i++) { + mrq = host->mrqs_done[i]; + if (mrq) + break; + } + + if (!mrq) { + spin_unlock_irqrestore(&host->lock, flags); + return true; + } + + /* + * Always unmap the data buffers if they were mapped by + * sdhci_prepare_data() whenever we finish with a request. + * This avoids leaking DMA mappings on error. + */ + if (host->flags & SDHCI_REQ_USE_DMA) { + struct mmc_data *data = mrq->data; + + if (host->use_external_dma && data && + (mrq->cmd->error || data->error)) { + struct dma_chan *chan = sdhci_external_dma_channel(host, data); + + host->mrqs_done[i] = NULL; + spin_unlock_irqrestore(&host->lock, flags); + dmaengine_terminate_sync(chan); + spin_lock_irqsave(&host->lock, flags); + sdhci_set_mrq_done(host, mrq); + } + + sdhci_request_done_dma(host, mrq); + } + + /* + * The controller needs a reset of internal state machines + * upon error conditions. + */ + if (sdhci_needs_reset(host, mrq)) { + /* + * Do not finish until command and data lines are available for + * reset. Note there can only be one other mrq, so it cannot + * also be in mrqs_done, otherwise host->cmd and host->data_cmd + * would both be null. + */ + if (host->cmd || host->data_cmd) { + spin_unlock_irqrestore(&host->lock, flags); + return true; + } + + /* Some controllers need this kick or reset won't work here */ + if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) + /* This is to force an update */ + host->ops->set_clock(host, host->clock); + + host->ops->uhs2_reset(host, SDHCI_UHS2_SW_RESET_SD); + host->pending_reset = false; + } + + host->mrqs_done[i] = NULL; + + spin_unlock_irqrestore(&host->lock, flags); + + if (host->ops->request_done) + host->ops->request_done(host, mrq); + else + mmc_request_done(host->mmc, mrq); + + return false; +} + +static void sdhci_uhs2_complete_work(struct work_struct *work) +{ + struct sdhci_host *host = container_of(work, struct sdhci_host, + complete_work); + + while (!sdhci_uhs2_request_done(host)) + ; +} + +/*****************************************************************************\ + * * + * Interrupt handling * + * * +\*****************************************************************************/ + +static void __sdhci_uhs2_irq(struct sdhci_host *host, u32 uhs2mask) +{ + struct mmc_command *cmd = host->cmd; + + DBG("*** %s got UHS2 error interrupt: 0x%08x\n", + mmc_hostname(host->mmc), uhs2mask); + + if (uhs2mask & SDHCI_UHS2_ERR_INT_STATUS_CMD_MASK) { + if (!host->cmd) { + pr_err("%s: Got cmd interrupt 0x%08x but no cmd.\n", + mmc_hostname(host->mmc), + (unsigned int)uhs2mask); + sdhci_dumpregs(host); + return; + } + host->cmd->error = -EILSEQ; + if (uhs2mask & SDHCI_UHS2_ERR_INT_STATUS_RES_TIMEOUT) + host->cmd->error = -ETIMEDOUT; + } + + if (uhs2mask & SDHCI_UHS2_ERR_INT_STATUS_DATA_MASK) { + if (!host->data) { + pr_err("%s: Got data interrupt 0x%08x but no data.\n", + mmc_hostname(host->mmc), + (unsigned int)uhs2mask); + sdhci_dumpregs(host); + return; + } + + if (uhs2mask & SDHCI_UHS2_ERR_INT_STATUS_DEADLOCK_TIMEOUT) { + pr_err("%s: Got deadlock timeout interrupt 0x%08x\n", + mmc_hostname(host->mmc), + (unsigned int)uhs2mask); + host->data->error = -ETIMEDOUT; + } else if (uhs2mask & SDHCI_UHS2_ERR_INT_STATUS_ADMA) { + pr_err("%s: ADMA error = 0x %x\n", + mmc_hostname(host->mmc), + sdhci_readb(host, SDHCI_ADMA_ERROR)); + host->data->error = -EIO; + } else { + host->data->error = -EILSEQ; + } + } + + if (host->data && host->data->error) + sdhci_uhs2_finish_data(host); + else + sdhci_finish_mrq(host, cmd->mrq); +} + +u32 sdhci_uhs2_irq(struct sdhci_host *host, u32 intmask) +{ + u32 mask = intmask, uhs2mask; + + if (!(host->mmc->flags & MMC_UHS2_SUPPORT)) + goto out; + + /* + * TODO: We should mask Normal Error Interrupt Status Register + * in UHS-2 mode so that we don't have to care SD mode errors. + */ + if (intmask & SDHCI_INT_ERROR) { + uhs2mask = sdhci_readl(host, SDHCI_UHS2_ERR_INT_STATUS); + if (!(uhs2mask & SDHCI_UHS2_ERR_INT_STATUS_MASK)) + goto cmd_irq; + + /* Clear error interrupts */ + sdhci_writel(host, uhs2mask & SDHCI_UHS2_ERR_INT_STATUS_MASK, + SDHCI_UHS2_ERR_INT_STATUS); + + /* Handle error interrupts */ + __sdhci_uhs2_irq(host, uhs2mask); + + /* Caller, shdci_irq(), doesn't have to care UHS-2 errors */ + intmask &= ~SDHCI_INT_ERROR; + mask &= SDHCI_INT_ERROR; + } + +cmd_irq: + /* + * TODO: Cleanup + * INT_RESPONSE is enough instead of INT_CMD_MASK, assuming that + * INT_ERROR and INT_CMD_MASK won't happen at the same time. + */ + if (intmask & SDHCI_INT_CMD_MASK) { + /* Clear command interrupt */ + sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK, SDHCI_INT_STATUS); + + /* Handle command interrupt */ + if (intmask & SDHCI_INT_RESPONSE) + sdhci_uhs2_finish_command(host); + + /* Caller, shdci_irq(), doesn't have to care UHS-2 command */ + intmask &= ~SDHCI_INT_CMD_MASK; + mask &= SDHCI_INT_CMD_MASK; + } + + /* Clear already-handled interrupts. */ + sdhci_writel(host, mask, SDHCI_INT_STATUS); + +out: + return intmask; +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_irq); + +static irqreturn_t sdhci_uhs2_thread_irq(int irq, void *dev_id) +{ + struct sdhci_host *host = dev_id; + struct mmc_command *cmd; + unsigned long flags; + u32 isr; + + while (!sdhci_uhs2_request_done(host)) + ; + + spin_lock_irqsave(&host->lock, flags); + + isr = host->thread_isr; + host->thread_isr = 0; + + cmd = host->deferred_cmd; + if (cmd && !sdhci_uhs2_send_command_retry(host, cmd, flags)) + sdhci_finish_mrq(host, cmd->mrq); + + spin_unlock_irqrestore(&host->lock, flags); + + if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { + struct mmc_host *mmc = host->mmc; + + mmc->ops->card_event(mmc); + mmc_detect_change(mmc, msecs_to_jiffies(200)); + } + + return IRQ_HANDLED; +} + void sdhci_uhs2_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct sdhci_host *host = mmc_priv(mmc); diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index 23368448ccd4..d32a8602d045 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -217,5 +217,8 @@ void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd); void sdhci_uhs2_set_timeout(struct sdhci_host *host, struct mmc_command *cmd); void sdhci_uhs2_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set); +void sdhci_uhs2_request(struct mmc_host *mmc, struct mmc_request *mrq); +int sdhci_uhs2_request_atomic(struct mmc_host *mmc, struct mmc_request *mrq); +u32 sdhci_uhs2_irq(struct sdhci_host *host, u32 intmask); #endif /* __SDHCI_UHS2_H */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a8458b1f3899..e1288c9b6a93 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1224,11 +1224,12 @@ static int sdhci_external_dma_init(struct sdhci_host *host) return ret; } -static struct dma_chan *sdhci_external_dma_channel(struct sdhci_host *host, - struct mmc_data *data) +struct dma_chan *sdhci_external_dma_channel(struct sdhci_host *host, + struct mmc_data *data) { return data->flags & MMC_DATA_WRITE ? host->tx_chan : host->rx_chan; } +EXPORT_SYMBOL_GPL(sdhci_external_dma_channel); int sdhci_external_dma_setup(struct sdhci_host *host, struct mmc_command *cmd) { @@ -1478,7 +1479,7 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, sdhci_writew(host, mode, SDHCI_TRANSFER_MODE); } -static bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq) +bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq) { return (!(host->flags & SDHCI_DEVICE_DEAD) && ((mrq->cmd && mrq->cmd->error) || @@ -1486,8 +1487,9 @@ static bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq) (mrq->data && mrq->data->stop && mrq->data->stop->error) || (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))); } +EXPORT_SYMBOL_GPL(sdhci_needs_reset); -static void sdhci_set_mrq_done(struct sdhci_host *host, struct mmc_request *mrq) +void sdhci_set_mrq_done(struct sdhci_host *host, struct mmc_request *mrq) { int i; @@ -1507,6 +1509,7 @@ static void sdhci_set_mrq_done(struct sdhci_host *host, struct mmc_request *mrq) WARN_ON(i >= SDHCI_MAX_MRQS); } +EXPORT_SYMBOL_GPL(sdhci_set_mrq_done); void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) { @@ -3068,7 +3071,56 @@ static const struct mmc_host_ops sdhci_ops = { * * \*****************************************************************************/ -static bool sdhci_request_done(struct sdhci_host *host) +void sdhci_request_done_dma(struct sdhci_host *host, struct mmc_request *mrq) +{ + struct mmc_data *data = mrq->data; + + if (data && data->host_cookie == COOKIE_MAPPED) { + if (host->bounce_buffer) { + /* + * On reads, copy the bounced data into the + * sglist + */ + if (mmc_get_dma_dir(data) == DMA_FROM_DEVICE) { + unsigned int length = data->bytes_xfered; + + if (length > host->bounce_buffer_size) { + pr_err("%s: bounce buffer is %u bytes but DMA claims to have transferred %u bytes\n", + mmc_hostname(host->mmc), + host->bounce_buffer_size, + data->bytes_xfered); + /* Cap it down and continue */ + length = host->bounce_buffer_size; + } + dma_sync_single_for_cpu( + host->mmc->parent, + host->bounce_addr, + host->bounce_buffer_size, + DMA_FROM_DEVICE); + sg_copy_from_buffer(data->sg, + data->sg_len, + host->bounce_buffer, + length); + } else { + /* No copying, just switch ownership */ + dma_sync_single_for_cpu( + host->mmc->parent, + host->bounce_addr, + host->bounce_buffer_size, + mmc_get_dma_dir(data)); + } + } else { + /* Unmap the raw data */ + dma_unmap_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, + mmc_get_dma_dir(data)); + } + data->host_cookie = COOKIE_UNMAPPED; + } +} +EXPORT_SYMBOL_GPL(sdhci_request_done_dma); + +bool sdhci_request_done(struct sdhci_host *host) { unsigned long flags; struct mmc_request *mrq; @@ -3137,48 +3189,7 @@ static bool sdhci_request_done(struct sdhci_host *host) sdhci_set_mrq_done(host, mrq); } - if (data && data->host_cookie == COOKIE_MAPPED) { - if (host->bounce_buffer) { - /* - * On reads, copy the bounced data into the - * sglist - */ - if (mmc_get_dma_dir(data) == DMA_FROM_DEVICE) { - unsigned int length = data->bytes_xfered; - - if (length > host->bounce_buffer_size) { - pr_err("%s: bounce buffer is %u bytes but DMA claims to have transferred %u bytes\n", - mmc_hostname(host->mmc), - host->bounce_buffer_size, - data->bytes_xfered); - /* Cap it down and continue */ - length = host->bounce_buffer_size; - } - dma_sync_single_for_cpu( - mmc_dev(host->mmc), - host->bounce_addr, - host->bounce_buffer_size, - DMA_FROM_DEVICE); - sg_copy_from_buffer(data->sg, - data->sg_len, - host->bounce_buffer, - length); - } else { - /* No copying, just switch ownership */ - dma_sync_single_for_cpu( - mmc_dev(host->mmc), - host->bounce_addr, - host->bounce_buffer_size, - mmc_get_dma_dir(data)); - } - } else { - /* Unmap the raw data */ - dma_unmap_sg(mmc_dev(host->mmc), data->sg, - data->sg_len, - mmc_get_dma_dir(data)); - } - data->host_cookie = COOKIE_UNMAPPED; - } + sdhci_request_done_dma(host, mrq); } host->mrqs_done[i] = NULL; @@ -3192,6 +3203,7 @@ static bool sdhci_request_done(struct sdhci_host *host) return false; } +EXPORT_SYMBOL_GPL(sdhci_request_done); static void sdhci_complete_work(struct work_struct *work) { diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 99f88b0ff4f4..4a7d31a54e2e 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -863,8 +863,11 @@ int sdhci_external_dma_setup(struct sdhci_host *host, struct mmc_command *cmd); void sdhci_external_dma_release(struct sdhci_host *host); void __sdhci_external_dma_prepare_data(struct sdhci_host *host, struct mmc_command *cmd); void sdhci_external_dma_pre_transfer(struct sdhci_host *host, struct mmc_command *cmd); +struct dma_chan *sdhci_external_dma_channel(struct sdhci_host *host, struct mmc_data *data); #endif bool sdhci_manual_cmd23(struct sdhci_host *host, struct mmc_request *mrq); +bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq); +void sdhci_set_mrq_done(struct sdhci_host *host, struct mmc_request *mrq); void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq); void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq); void __sdhci_finish_data_common(struct sdhci_host *host); @@ -896,6 +899,8 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios); void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable); +void sdhci_request_done_dma(struct sdhci_host *host, struct mmc_request *mrq); +bool sdhci_request_done(struct sdhci_host *host); void sdhci_adma_write_desc(struct sdhci_host *host, void **desc, dma_addr_t addr, int len, unsigned int cmd); From patchwork Mon Oct 17 09:11:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3318 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348115wrs; Mon, 17 Oct 2022 02:19:22 -0700 (PDT) X-Google-Smtp-Source: AMsMyM58aqNTcPujFGcKLfDmy5Rq/dQuvIgQ+vGzWVQBbwIMTTsW2/LtClUCAPF4MF/1W699X8ZT X-Received: by 2002:aa7:864a:0:b0:53f:dcdf:4614 with SMTP id a10-20020aa7864a000000b0053fdcdf4614mr11733969pfo.38.1665998362248; Mon, 17 Oct 2022 02:19:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998362; cv=none; d=google.com; s=arc-20160816; b=TaWpniS8sTWMuQWGKWGG7jFLVUAtKSGdvQuq4v7YpQDpXg/TUlSRtZQ5U4JQwZRs0A jgVIX6T5DjD7njziCtZrgF9u88uJhlaAxggQMsTjvcDBVQ8lfHd4WsBKpx0RZLe7hS+s WYnmztsWY8UWByT7Ms+YYH3wSO/IrYC7feLHd0cX+cqALUKygmVfLO0o52jJovOMVuZe tP1p3Gl4GZFLaZuKeevOKgq9s6OvQqZ0BijugEpldN5Q1nwrJzHF2rI2NsGYYVQX7B06 jCbckzTGLzVvITWX6mKMZfmz7e6kkhXSVmW3O6ERjvnzTrtIhkKgzmcb5ewrUjL3cOUq F/MQ== 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=ClIUEwsCp8thdfE8NBnZGuFhY59OfJYJmXyU5NOqP9o=; b=j4mqhpsOhrTYJwHKG/9dvvsztujrg/KwR37PEmYj2gcqoHnencSEHlxwCduktPR61L QzBsAvwSMSGwMrK6i0EmzBcW1LNLBHlT08AU04LbPDlLhhur/link9fUBcsujvw0SLPL NCm+j1stHDRSNnTstErrEvsifBpG7O3mibLHb6NYOMXvSmgIThdApOdtVBSyIbaFalT3 GCpp6Dg1zaJ1jgfInO3+wt/abpyn80t+Yhs/BVmN2wQdXniM9N7YZGLOORutZxItL70X Hu8S1UFkHDIdAY+ym8Pm2FKY99sGXCLEWg5CRRhQcsJQK8mnLK/+/n5P9bm7LbOlKgoO HMAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=eklPvOAV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j191-20020a6380c8000000b0046b454af0d6si1149905pgd.520.2022.10.17.02.19.08; Mon, 17 Oct 2022 02:19:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=eklPvOAV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229800AbiJQJOe (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231258AbiJQJNh (ORCPT ); Mon, 17 Oct 2022 05:13:37 -0400 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4350833401; Mon, 17 Oct 2022 02:13:20 -0700 (PDT) Received: by mail-pj1-x102a.google.com with SMTP id q10-20020a17090a304a00b0020b1d5f6975so10435332pjl.0; Mon, 17 Oct 2022 02:13:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=ClIUEwsCp8thdfE8NBnZGuFhY59OfJYJmXyU5NOqP9o=; b=eklPvOAVG6upB8585c2CM0Q5hlkVVY/yYTYfskkd0J6HU5u8s3k70hu8aTmoNKTxNk fzZIMlluz0V4jYnz4pdMC4eoOXf6wbHPTd4TedGlB8VjfIWTnkTgLTYxK89XLkqvgOZu gbLrKekEYHpyKTIlbkH00GSBxWPJ9SQxZ3nX/Aao9H5fGsxvtZg0HsgOc9ycrepUplT6 c/mz6ZK0kx3mwGCEsAZbs8n0OJzZwa4Sw5lgQMsyphLv4ODPnd+DyF+HpjvMa8/VKZEU E6GLzlUKktH3yhlUypA2ZT/puOSIrQf+n1Rn4spc+SLiRFoE+jx2ZyiXpNntTg7eDNxF dGlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=ClIUEwsCp8thdfE8NBnZGuFhY59OfJYJmXyU5NOqP9o=; b=NJQ+X4au4451VKuBoPhF/SiMsjnaCPWrHMSi86jpG6OOup2+l3g8+EqeoPBpWkgMKE 00TronPFQ1imKWHTXcjfir56UEOC9ottS6xCdZ7ulHO3jxXNxFt72BGoVnXYlCUeGr7/ tg7DVNTBIYzwqMei4XkBQANpEXJeyCneygFkWfv77wozCdq1KjPErFKXVXyla1xkrbDI mtvF2Rb/HJsDY4axKSNr8A7mzYIlpM6xWpCTliGpfBVjf+iRoqBbgATtVaGhpFDr+4vI i5chfltyusIirJmbnJ5RnXbCY7l1ZRd1PAKR8kH8R6hRBFVJKk+xCbd5flUah97SL2Fh Co2g== X-Gm-Message-State: ACrzQf2w4HEfPBQKevTRVr1JknxgitrTIvxp1oLwcaEXEm+80zb9S1Pe w0dxSgwhmo7ha3crI4YYB/k= X-Received: by 2002:a17:90b:38c4:b0:20d:9dfa:4339 with SMTP id nn4-20020a17090b38c400b0020d9dfa4339mr27838805pjb.74.1665997993898; Mon, 17 Oct 2022 02:13:13 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:13 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 21/26] mmc: sdhci-uhs2: add add_host() and others to set up the driver Date: Mon, 17 Oct 2022 17:11:48 +0800 Message-Id: <20221017091153.454873-22-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925899055682264?= X-GMAIL-MSGID: =?utf-8?q?1746925899055682264?= This is a UHS-II version of sdhci's add_host/remove_host operation. Any sdhci drivers which are capable of handling UHS-II cards must call those functions instead of the corresponding sdhci's. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 175 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 2 + drivers/mmc/host/sdhci.c | 24 +++-- drivers/mmc/host/sdhci.h | 10 ++ 4 files changed, 203 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 452cd9165cdf..8e547b672574 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "sdhci.h" #include "sdhci-uhs2.h" @@ -1198,6 +1199,180 @@ static irqreturn_t sdhci_uhs2_thread_irq(int irq, void *dev_id) return IRQ_HANDLED; } +/*****************************************************************************\ + * + * Device allocation/registration * + * * +\*****************************************************************************/ + +static int __sdhci_uhs2_add_host_v4(struct sdhci_host *host, u32 caps1) +{ + struct mmc_host *mmc; + u32 max_current_caps2; + + if (host->version < SDHCI_SPEC_400) + return 0; + + mmc = host->mmc; + + /* Support UHS2 */ + if (caps1 & SDHCI_SUPPORT_UHS2) + mmc->caps2 |= MMC_CAP2_SD_UHS2; + + max_current_caps2 = sdhci_readl(host, SDHCI_MAX_CURRENT_1); + + if ((caps1 & SDHCI_SUPPORT_VDD2_180) && + !max_current_caps2 && + !IS_ERR(mmc->supply.vmmc2)) { + /* UHS2 - VDD2 */ + int curr = regulator_get_current_limit(mmc->supply.vmmc2); + + if (curr > 0) { + /* convert to SDHCI_MAX_CURRENT format */ + curr = curr / 1000; /* convert to mA */ + curr = curr / SDHCI_MAX_CURRENT_MULTIPLIER; + curr = min_t(u32, curr, SDHCI_MAX_CURRENT_LIMIT); + max_current_caps2 = curr; + } + } + + if (caps1 & SDHCI_SUPPORT_VDD2_180) { + mmc->ocr_avail_uhs2 |= MMC_VDD2_165_195; + /* + * UHS2 doesn't require this. Only UHS-I bus needs to set + * max current. + */ + mmc->max_current_180_vdd2 = (max_current_caps2 & + SDHCI_MAX_CURRENT_VDD2_180_MASK) * + SDHCI_MAX_CURRENT_MULTIPLIER; + } else { + mmc->caps2 &= ~MMC_CAP2_SD_UHS2; + } + + return 0; +} + +static int sdhci_uhs2_host_ops_init(struct sdhci_host *host); + +static int __sdhci_uhs2_add_host(struct sdhci_host *host) +{ + unsigned int flags = WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_HIGHPRI; + struct mmc_host *mmc = host->mmc; + int ret; + + if ((mmc->caps2 & MMC_CAP2_CQE) && + (host->quirks & SDHCI_QUIRK_BROKEN_CQE)) { + mmc->caps2 &= ~MMC_CAP2_CQE; + mmc->cqe_ops = NULL; + } + + /* overwrite ops */ + if (mmc->caps2 & MMC_CAP2_SD_UHS2) + sdhci_uhs2_host_ops_init(host); + + host->complete_wq = alloc_workqueue("sdhci", flags, 0); + if (!host->complete_wq) + return -ENOMEM; + + INIT_WORK(&host->complete_work, sdhci_uhs2_complete_work); + + timer_setup(&host->timer, sdhci_timeout_timer, 0); + timer_setup(&host->data_timer, sdhci_timeout_data_timer, 0); + + init_waitqueue_head(&host->buf_ready_int); + + sdhci_init(host, 0); + + ret = request_threaded_irq(host->irq, sdhci_irq, + sdhci_uhs2_thread_irq, + IRQF_SHARED, mmc_hostname(mmc), host); + if (ret) { + pr_err("%s: Failed to request IRQ %d: %d\n", + mmc_hostname(mmc), host->irq, ret); + goto unwq; + } + + ret = mmc_add_host(mmc); + if (ret) + return 1; + + pr_info("%s: SDHCI controller on %s [%s] using %s\n", + mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), + host->use_external_dma ? "External DMA" : + (host->flags & SDHCI_USE_ADMA) ? + (host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" : + (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); + + sdhci_enable_card_detection(host); + + return 0; + +unwq: + destroy_workqueue(host->complete_wq); + + return ret; +} + +static void __sdhci_uhs2_remove_host(struct sdhci_host *host, int dead) +{ + if (!(host->mmc) || !(host->mmc->flags & MMC_UHS2_SUPPORT)) + return; + + if (!dead) + host->ops->uhs2_reset(host, SDHCI_UHS2_SW_RESET_FULL); + + sdhci_writel(host, 0, SDHCI_UHS2_ERR_INT_STATUS_EN); + sdhci_writel(host, 0, SDHCI_UHS2_ERR_INT_SIG_EN); + host->mmc->flags &= ~MMC_UHS2_INITIALIZED; +} + +int sdhci_uhs2_add_host(struct sdhci_host *host) +{ + struct mmc_host *mmc = host->mmc; + int ret; + + ret = sdhci_setup_host(host); + if (ret) + return ret; + + if (host->version >= SDHCI_SPEC_400) { + ret = __sdhci_uhs2_add_host_v4(host, host->caps1); + if (ret) + goto cleanup; + } + + if ((mmc->caps2 & MMC_CAP2_SD_UHS2) && !host->v4_mode) + /* host doesn't want to enable UHS2 support */ + /* FIXME: Do we have to do some cleanup here? */ + mmc->caps2 &= ~MMC_CAP2_SD_UHS2; + + ret = __sdhci_uhs2_add_host(host); + if (ret) + goto cleanup2; + + return 0; + +cleanup2: + /* + * TODO: Is this a right cleanup? + */ + if (host->version >= SDHCI_SPEC_400) + __sdhci_uhs2_remove_host(host, 0); +cleanup: + sdhci_cleanup_host(host); + + return ret; +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_add_host); + +void sdhci_uhs2_remove_host(struct sdhci_host *host, int dead) +{ + __sdhci_uhs2_remove_host(host, dead); + + sdhci_remove_host(host, dead); +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_remove_host); + void sdhci_uhs2_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct sdhci_host *host = mmc_priv(mmc); diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index d32a8602d045..54241a7adfca 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -220,5 +220,7 @@ void sdhci_uhs2_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set); void sdhci_uhs2_request(struct mmc_host *mmc, struct mmc_request *mrq); int sdhci_uhs2_request_atomic(struct mmc_host *mmc, struct mmc_request *mrq); u32 sdhci_uhs2_irq(struct sdhci_host *host, u32 intmask); +int sdhci_uhs2_add_host(struct sdhci_host *host); +void sdhci_uhs2_remove_host(struct sdhci_host *host, int dead); #endif /* __SDHCI_UHS2_H */ diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e1288c9b6a93..56637b40fc66 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -175,10 +175,11 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); } -static void sdhci_enable_card_detection(struct sdhci_host *host) +void sdhci_enable_card_detection(struct sdhci_host *host) { sdhci_set_card_detection(host, true); } +EXPORT_SYMBOL_GPL(sdhci_enable_card_detection); static void sdhci_disable_card_detection(struct sdhci_host *host) { @@ -237,7 +238,7 @@ void sdhci_reset(struct sdhci_host *host, u8 mask) } EXPORT_SYMBOL_GPL(sdhci_reset); -static void sdhci_do_reset(struct sdhci_host *host, u8 mask) +void sdhci_do_reset(struct sdhci_host *host, u8 mask) { if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { struct mmc_host *mmc = host->mmc; @@ -258,6 +259,7 @@ static void sdhci_do_reset(struct sdhci_host *host, u8 mask) host->preset_enabled = false; } } +EXPORT_SYMBOL_GPL(sdhci_do_reset); static void sdhci_set_default_irqs(struct sdhci_host *host) { @@ -321,7 +323,7 @@ static void sdhci_config_dma(struct sdhci_host *host) sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } -static void sdhci_init(struct sdhci_host *host, int soft) +void sdhci_init(struct sdhci_host *host, int soft) { struct mmc_host *mmc = host->mmc; unsigned long flags; @@ -346,6 +348,7 @@ static void sdhci_init(struct sdhci_host *host, int soft) mmc->ops->set_ios(mmc, &mmc->ios); } } +EXPORT_SYMBOL_GPL(sdhci_init); static void sdhci_reinit(struct sdhci_host *host) { @@ -410,7 +413,7 @@ static void sdhci_led_control(struct led_classdev *led, spin_unlock_irqrestore(&host->lock, flags); } -static int sdhci_led_register(struct sdhci_host *host) +int sdhci_led_register(struct sdhci_host *host) { struct mmc_host *mmc = host->mmc; @@ -427,14 +430,16 @@ static int sdhci_led_register(struct sdhci_host *host) return led_classdev_register(mmc_dev(mmc), &host->led); } +EXPORT_SYMBOL_GPL(sdhci_led_register); -static void sdhci_led_unregister(struct sdhci_host *host) +void sdhci_led_unregister(struct sdhci_host *host) { if (host->quirks & SDHCI_QUIRK_NO_LED) return; led_classdev_unregister(&host->led); } +EXPORT_SYMBOL_GPL(sdhci_led_unregister); static inline void sdhci_led_activate(struct sdhci_host *host) { @@ -3214,7 +3219,7 @@ static void sdhci_complete_work(struct work_struct *work) ; } -static void sdhci_timeout_timer(struct timer_list *t) +void sdhci_timeout_timer(struct timer_list *t) { struct sdhci_host *host; unsigned long flags; @@ -3235,8 +3240,9 @@ static void sdhci_timeout_timer(struct timer_list *t) spin_unlock_irqrestore(&host->lock, flags); } +EXPORT_SYMBOL_GPL(sdhci_timeout_timer); -static void sdhci_timeout_data_timer(struct timer_list *t) +void sdhci_timeout_data_timer(struct timer_list *t) { struct sdhci_host *host; unsigned long flags; @@ -3267,6 +3273,7 @@ static void sdhci_timeout_data_timer(struct timer_list *t) spin_unlock_irqrestore(&host->lock, flags); } +EXPORT_SYMBOL_GPL(sdhci_timeout_data_timer); /*****************************************************************************\ * * @@ -3530,7 +3537,7 @@ static inline bool sdhci_defer_done(struct sdhci_host *host, data->host_cookie == COOKIE_MAPPED); } -static irqreturn_t sdhci_irq(int irq, void *dev_id) +irqreturn_t sdhci_irq(int irq, void *dev_id) { struct mmc_request *mrqs_done[SDHCI_MAX_MRQS] = {0}; irqreturn_t result = IRQ_NONE; @@ -3671,6 +3678,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) return result; } +EXPORT_SYMBOL_GPL(sdhci_irq); static irqreturn_t sdhci_thread_irq(int irq, void *dev_id) { diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 4a7d31a54e2e..bc4be80bf0af 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -853,8 +853,15 @@ static inline void sdhci_read_caps(struct sdhci_host *host) } bool sdhci_data_line_cmd(struct mmc_command *cmd); +void sdhci_enable_card_detection(struct sdhci_host *host); void sdhci_runtime_pm_bus_on(struct sdhci_host *host); void sdhci_runtime_pm_bus_off(struct sdhci_host *host); +void sdhci_do_reset(struct sdhci_host *host, u8 mask); +void sdhci_init(struct sdhci_host *host, int soft); +#if IS_REACHABLE(CONFIG_LEDS_CLASS) +int sdhci_led_register(struct sdhci_host *host); +void sdhci_led_unregister(struct sdhci_host *host); +#endif void sdhci_mod_timer(struct sdhci_host *host, struct mmc_request *mrq, unsigned long timeout); void sdhci_initialize_data(struct sdhci_host *host, struct mmc_data *data); void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data); @@ -901,6 +908,9 @@ int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable); void sdhci_request_done_dma(struct sdhci_host *host, struct mmc_request *mrq); bool sdhci_request_done(struct sdhci_host *host); +void sdhci_timeout_timer(struct timer_list *t); +void sdhci_timeout_data_timer(struct timer_list *t); +irqreturn_t sdhci_irq(int irq, void *dev_id); void sdhci_adma_write_desc(struct sdhci_host *host, void **desc, dma_addr_t addr, int len, unsigned int cmd); From patchwork Mon Oct 17 09:11:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3321 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348493wrs; Mon, 17 Oct 2022 02:20:41 -0700 (PDT) X-Google-Smtp-Source: AMsMyM40Hy5lNEVEs4yKAREpi1/KTMdf9Xwd2fh9XMiwcHzWLukMtAzdM954Zlxw2FSOfoep15qA X-Received: by 2002:a17:903:3113:b0:17f:6846:6266 with SMTP id w19-20020a170903311300b0017f68466266mr10947073plc.150.1665998441089; Mon, 17 Oct 2022 02:20:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998441; cv=none; d=google.com; s=arc-20160816; b=EZYMh9OJ/WEpCIcEIPNxKbFRo+JMRJYf0VoPsS5mXdXHSt+WFa5XasOR0QZfVjWjTd ve/CEZd1D7piw0/icuzCaa4tumpRJeXaS6eCDXkF739BXVlBvK3/EVpDsY/v2PC/bC/2 aCPyYoA8x4mwSfAhBZLgZxj0TdmWdYb3T+5qrR5wyh9BEqoqKSOfV9GlHx9Rf9HnHbNA z7bHIG77XXc9VTsMrtYm8vvrE+vPlqVMubRujmNDpp17gaVvt3GjCg0sGQXnlZ1cY9sq dq+8kmxKuXCppIsfM1yiF552X3TCasupi1cqfMHhcg0SR+UEVJ8ng/hW18jiB1XLZDjr 1yYQ== 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=FlEORPHGXzxv44xyQoYwE+VyJB+0P99hwxAci/rfmuQ=; b=R94p4FRKOgHRQYmPlVepTLko2jNRemi5IOH/tWtoeEuwG0OV5cC0CN+XBNx7k/bncN RKn0e+HGSdQ6LLr2NYSdUB8vB9hiJuHAZHLEycK2IOWDUKnY4uXcUN1JBL+vGi52xjR2 bOevaepmI4pw+IFUlYXWz+TiT84HHdRQdcOvgFvsb0EaYNNXVRRt9Cr0S0OQ9uutW2aV wUsga86toSXZAu2xUO11XeXYlYIoPNH3sJIWjnKxJsxb1XhoolOyZXlC2DbmS5k8suOf YVTeTPklXZUSj0WYik1c8AvCB4XtF2JN30QUxi5+Ap/pD6JpY82bSbvp5l/B48AuNkcR yApQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=JJa3+An1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 2-20020a630d42000000b0045a8a6b75fesi11312148pgn.499.2022.10.17.02.20.27; Mon, 17 Oct 2022 02:20:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=JJa3+An1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230195AbiJQJO5 (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231163AbiJQJOB (ORCPT ); Mon, 17 Oct 2022 05:14:01 -0400 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E5694F184; Mon, 17 Oct 2022 02:13:23 -0700 (PDT) Received: by mail-pl1-x62e.google.com with SMTP id c24so10197389pls.9; Mon, 17 Oct 2022 02:13:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=FlEORPHGXzxv44xyQoYwE+VyJB+0P99hwxAci/rfmuQ=; b=JJa3+An1YKZPwvgwqCBMpwHnO+29pqTfXC3Q83G+n/93npi6xwJKQsAygzOeAfpLbJ 8HXUuBTP3StBXAd7XvRwGCd+5OIdmgTgYt71d8nhwANHSf65RF4WMPm/Ue4FK6N6QXeu etsOcZDK/H54PSjYf67HT0iWKBGVuPyw81xzhat5qNGOUWN5FxIvRdn9yumw5rpzSWan gIztkEA6NxvKc4xA7OslS32zMmshnN+FVbX/G3c9CIK15hD1Hf1a/wg0bWmY5FovJ/hP c/ARbFfGtHkiz3aDUbDbJdcPo9h0tXQKwe/pCrAp17kkM7Kc35VKac8592CRMLFahomq Kkqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=FlEORPHGXzxv44xyQoYwE+VyJB+0P99hwxAci/rfmuQ=; b=L/oS1r8eO6UQpQ0BxuR1c017UNqacdKDsaxS3SY4bRHQ6MVbRHHm19NVmhJqU0hTF6 /EGoW0vefsiLC5Q92smLjWLo/0n46Ie+G1G2/4to7froZfvXpUftRl0r/HUWIY7FdngA 4GE5XIcbnSXAIVcB2xMvtckR9J3n3gC+vzsAbgZTZjETFK43yS4JntzwLLgq9S2mUarl oyqn2YW4T1AU4OQzDPJbNk5qLiWWPfNrnePZIK7fQ1WkJHXaPtmJZ+5gbLBC5qi9ZWRl VeATDYIuuBsZTKAeisPNCELLe7LuVBYFbl5wuzAY9bp/m9RGIUhpns+osr/4uN7bJuyT CNGA== X-Gm-Message-State: ACrzQf2H6oxA4EADk3pcs8Y4lgiCLZuT+Hondy6WrOS/zBzE/u6y0Js+ +hhH/uIrL7kNcwXwhmHJwdM= X-Received: by 2002:a17:90a:1785:b0:20a:6162:2b6a with SMTP id q5-20020a17090a178500b0020a61622b6amr12469731pja.180.1665997998126; Mon, 17 Oct 2022 02:13:18 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:17 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 22/26] mmc: sdhci-uhs2: add pre-detect_init hook Date: Mon, 17 Oct 2022 17:11:49 +0800 Message-Id: <20221017091153.454873-23-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925981409572969?= X-GMAIL-MSGID: =?utf-8?q?1746925981409572969?= From: Victor Shih This "pre" hook for detect_init(), uhs2_pre_detect_init, will be required to enable UHS-II support, at least, on GL9755. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 3 +++ drivers/mmc/host/sdhci.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 8e547b672574..88decfba1880 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -1570,6 +1570,9 @@ static int sdhci_uhs2_do_detect_init(struct mmc_host *mmc) DBG("%s: begin UHS2 init.\n", __func__); + if (host->ops && host->ops->uhs2_pre_detect_init) + host->ops->uhs2_pre_detect_init(host); + if (sdhci_uhs2_interface_detect(host)) { pr_warn("%s: cannot detect UHS2 interface.\n", mmc_hostname(host->mmc)); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index bc4be80bf0af..943701aef22a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -745,6 +745,7 @@ struct sdhci_ops { struct mmc_request *mrq); void (*dump_vendor_regs)(struct sdhci_host *host); void (*dump_uhs2_regs)(struct sdhci_host *host); + void (*uhs2_pre_detect_init)(struct sdhci_host *host); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS From patchwork Mon Oct 17 09:11:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3319 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348128wrs; Mon, 17 Oct 2022 02:19:25 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6Fhmd1yZ67qM5/H25A1ypNQT+lBV81qbQ8WPktL+nshX3QiAwK58av+VjjhT3Ml2z4UBNS X-Received: by 2002:a17:90b:1b47:b0:20d:cdf2:c02e with SMTP id nv7-20020a17090b1b4700b0020dcdf2c02emr10551835pjb.233.1665998365106; Mon, 17 Oct 2022 02:19:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998365; cv=none; d=google.com; s=arc-20160816; b=seOYkwV0QPH7WHTU4kWCK0bx8KZDzoRi7ODqEYHXiD+NjVJVkS9KJJC9xC1/gyJOru IlD6T3IXw+HYPIQnSeXbdzc95rb3BuXUdvkcdL7movb117Tf3yeE+ZyhOPC+kpw95CLV Z0wicWC37DOmj7p9wEeqttjASrQapQ79amHqjZbeDmRJLyh+XudPcnKJ+C5h+tGwYJre x7thx4vKC5SuscDSOV5tpe4cTaqBBeGL1tDmTIg2vrk5/5l3FJLJQovNtqZjyh4m5uDz KmBszN+IPTyvQaUsl9I0i0JibsFekxxQdKDHb6HGTehP19yaMXlEOOITY7gbxQtA7FtB x3HQ== 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=NnqdZrpjB39egxtL+QCzwuA4NRAaJFbgBz0XDUCs42M=; b=n0EHCGpfFQYCG2qltTjp7U5pQgzQfo+Q9FQWbmDY6GtOBISgPbodM69Ftq3rqH16Xa bLuGD0xwzZHPH3ma01Bfp+E2bw5234crYwgFCVGZe6AfPVtZF3hY013eaMxeinXIF8NT dypinAsLkMTxPxAFyLaAfqxy/91mqXFlI/o89F4YbMTTv+C8Gd3actd+wFgxGghGspfg 7fwqxAEyOMLbdPcAWxa2JFUuFMEc+VjKPPVsxoiMUKWm3+KYKDnjm/MiJszYQ+4uBbaD 3kENbm0qQxpbh5a+XnpcoY9MPR34tSc1yF5hJedOs6xxJqez0gji5tP1L9UkaP8S0l0T Wn0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=nd36XPAf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id oo3-20020a17090b1c8300b0020087bc6415si19626710pjb.16.2022.10.17.02.19.12; Mon, 17 Oct 2022 02:19:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=nd36XPAf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231289AbiJQJOt (ORCPT + 99 others); Mon, 17 Oct 2022 05:14:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34078 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229887AbiJQJN4 (ORCPT ); Mon, 17 Oct 2022 05:13:56 -0400 Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0FD3020F6C; Mon, 17 Oct 2022 02:13:25 -0700 (PDT) Received: by mail-pf1-x429.google.com with SMTP id d10so10522780pfh.6; Mon, 17 Oct 2022 02:13:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=NnqdZrpjB39egxtL+QCzwuA4NRAaJFbgBz0XDUCs42M=; b=nd36XPAfDfSTx/DgtkL1HGUbatdbwalbwITd1kDXsmYT72i/kdQsKBSlysBh01WhYs 9XVXJFLT67zS8zBm7Jf5d1kL2y/14fdKa73I/qUwJEKf/YcgDAueUic7cVNmoCCEzT1h I/ZWCpa6X49lPwVZ9cm1wQp5WjM27MglqkICXUcJZc3wGV/k4ZY8PSBz45VO3HkEVCnb VK9J7qdByc7nlweGQ5LuX1yZFxcHOvUa/aQN+cM68KN2ldp8Q7qtmOcfKdiUWq8QXHRq 7X6oBZsibeyPw2BG0wZtmfvW6FnDa1PbxQsJBCgUJyq3OwJEmCxwRzAzPodO5Sduq7ZX Miqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=NnqdZrpjB39egxtL+QCzwuA4NRAaJFbgBz0XDUCs42M=; b=WKj/JrbWNNGpiyvgpHaUchSH9YS1VZtkJgRiVrHcqn/j5BQEVXC2WfSOn/eOYdmjT4 fqiIvUHQF0tTYRgf3yURcalQWN777Mjg55A2cY/VVLE8nYlWRWXUggV7lr5CTZWmcbXB HgmeFpKTu7nnCaRaz7T4dtQ+R5qutgA0ay6JLJPfx9AJ8uRwTnWdRsZBY4XZchUu6C3h nFbZgxwY8Xb7Pc9C6rhKj/rGX/6/M1ASTFSJDJ+5z6Nwqb0vUKdvaR/qvDrRnhlXQAbL EkGmHNvQgoJsgQNIBzmpUpEF7VJiwumuBw4cwjdjnKrkJ2bwQEn3TtuHCJognXXGD2+c jPbQ== X-Gm-Message-State: ACrzQf30+PB5YbYv7JgaWb65F9MqKfKN1Qo5zFEr/pawgxfRTC7U+7zq g7IPHMXrzbVT1mn1cvzmuoMJ5UhtDKQ= X-Received: by 2002:aa7:8a15:0:b0:566:1817:6fcf with SMTP id m21-20020aa78a15000000b0056618176fcfmr11620969pfa.85.1665998001583; Mon, 17 Oct 2022 02:13:21 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:21 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 23/26] mmc: core: add post-mmc_attach_sd hook Date: Mon, 17 Oct 2022 17:11:50 +0800 Message-Id: <20221017091153.454873-24-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746925901696993273?= X-GMAIL-MSGID: =?utf-8?q?1746925901696993273?= From: AKASHI Takahiro This "post" hook for mmc_attach_sd() will be required to enable UHS-II support, at least, on GL9755. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro --- drivers/mmc/core/sd.c | 6 ++++++ include/linux/mmc/host.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index cab4725209c1..975987fb02a1 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1855,6 +1855,12 @@ int mmc_attach_sd(struct mmc_host *host) goto remove_card; mmc_claim_host(host); + + /* TODO: Is this the right place? */ + if ((host->flags & MMC_UHS2_INITIALIZED) && + host->ops->uhs2_post_attach_sd) + host->ops->uhs2_post_attach_sd(host); + return 0; remove_card: diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index cf5adf26b6e4..e58be4ccb308 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -279,6 +279,7 @@ struct mmc_host_ops { int (*uhs2_set_reg)(struct mmc_host *host, enum sd_uhs2_operation act); int (*uhs2_disable_clk)(struct mmc_host *host); int (*uhs2_enable_clk)(struct mmc_host *host); + void (*uhs2_post_attach_sd)(struct mmc_host *host); /* * The uhs2_control callback is used to execute SD UHS-II specific From patchwork Mon Oct 17 09:11:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3323 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348606wrs; Mon, 17 Oct 2022 02:21:08 -0700 (PDT) X-Google-Smtp-Source: AMsMyM70Ifx6ewN9OpiEVi5j5c1/REHtS9UugSe4R8seishq9Sz4ixvOo24qLs8cUc1oCY0BshEl X-Received: by 2002:a17:90a:c7d3:b0:20a:68a1:85cb with SMTP id gf19-20020a17090ac7d300b0020a68a185cbmr32654076pjb.138.1665998468123; Mon, 17 Oct 2022 02:21:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998468; cv=none; d=google.com; s=arc-20160816; b=cJWswMJWMwSgYSLmfmJHNuaRfx8h93KONY2nlifhSI08pifg1eLS+q3EoRWMG1ySlD GEvd+4z2vpNlQNbhR1EULiDFD2uAjIjGpTQ0AfqS/Bg8MxgLRIACDwCksKn+9LCPr1sK cQaviBuULOWikVBaX7vLNFKv9W1qRZHegGk+5tF2nBjRnCsPAetdTFouBy5q1SKeFXZW tCjM0W3S7W7p1V2/wjNQ7xUHoR1yHNLwUGflR0rFa3f5+r1V6aLLAkh1DMiCxv/Oisp4 IvCzV5kgoCiFX6XtL8c1HxJFs2mF5f9xoTvK4XFr2c56lLnFMunpn/k4lv7aBWA9VFmq a+1w== 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=MJyxTTeGNHxq9RsExK67ky3HBRhQX3BCNFgWjcG3gFE=; b=EdDJdLoqZ2m/cp7a9x8vz9r7KdAX4lAuf3wEVcb6xJWkuZm9hzQIL8MtzWLbDoNPHr wtjG0SoZAFWW+4VSCUeXpHlBIlQSK5x/ZvuKf5ncwZCTF6LZuNdSXEMBY33Y7XRpDNZz xEjAKIRSfGuScZyHg4nc8A+mZ1ElWpWovzrKaNOybksjHWGlRIn82tmtE4uYmqSEpNhd dWBJd2xJfF2kRWukuhrB4ctRSi9zPID+6bAGp7alF4oMeZar/9gwqTn2prgFvds4je3b 9rXWrXhZmFrQRAusShTA6YvTeuR9h9Na8LHn62959Q/sA7Nf21PgJft7Q5ZbqEgH4/30 wzRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=UUQskCnT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t18-20020a170902e85200b0017f77922b11si13584685plg.84.2022.10.17.02.20.55; Mon, 17 Oct 2022 02:21:08 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=UUQskCnT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230476AbiJQJPI (ORCPT + 99 others); Mon, 17 Oct 2022 05:15:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60566 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231200AbiJQJOD (ORCPT ); Mon, 17 Oct 2022 05:14:03 -0400 Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B4893FED5; Mon, 17 Oct 2022 02:13:27 -0700 (PDT) Received: by mail-pg1-x530.google.com with SMTP id 129so9920136pgc.5; Mon, 17 Oct 2022 02:13:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=MJyxTTeGNHxq9RsExK67ky3HBRhQX3BCNFgWjcG3gFE=; b=UUQskCnTbYHvB1seZphzDZF7q3qA9B2Svw78Jq2hwRG/epyeH6a8SoYf887239wUYW dDbYGV7y9+ghmGzE2hfWXzRawvAOzoqWDeA9ZYw08g+l7ZMD3UtlV8AfyTQRgXp698ii nSPGWOJHb5M76FeajPQIIJG+vXRLyrmMhksLffsE5XX2VleI1KGVdnCdqt3K06tPdJyG ybl0e91jtKDTJilArAcHHjsnuflt9Mg2ZY60J+w/L3Ctr4xW7VsGo2MnQzTNkIJJ2rbO W4htSKbOJ6CbjGXeGJmOjNRwDZ9rhS8Lw5PRc4OoVYJwiEIaFQRVICCnhgsRIR7diuSi lppQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=MJyxTTeGNHxq9RsExK67ky3HBRhQX3BCNFgWjcG3gFE=; b=3qgqVgEm0ZKUYdwX+3QQ2HHd44jz8tQhtCc2FdLOgs9IvHETxqRmNm6BiZ9z3tMheX IhR9poDtguZjZICsUMlzxYUb/KwdvywW8ao042Mc3/z2mK22D/43wn56oxHXizGIJedA eJOslEm5lktFyUHhMxpcRQvDyhh41ujBnzLq17ekMNa7oh5f8TMPkJle4J7tuAisfAWX DWzH2syZ0VFIVHg2yT1aKcl3P1BFRtxX1GFIBMgi6hhz0ex3S8zKHdHkIio//cbcXYqT SJS/G3ME3B+iRP0OSUJihjnTHooCoDKtjMO1lm2Thhy4449eZ9ymy8V+Zfy2NWF/zc8M lKvw== X-Gm-Message-State: ACrzQf0sc1gT6G0r80KRrtw0F8jjBry4y+5JMwKGrv8FyJrfv9e9Yp9E n78/BOL4yzgrI+OrDQHIEps= X-Received: by 2002:a05:6a00:1ca4:b0:562:daf9:6162 with SMTP id y36-20020a056a001ca400b00562daf96162mr11578722pfw.40.1665998005104; Mon, 17 Oct 2022 02:13:25 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:24 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 24/26] mmc: sdhci-uhs2: add post-mmc_attach_sd hook Date: Mon, 17 Oct 2022 17:11:51 +0800 Message-Id: <20221017091153.454873-25-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746926009712773486?= X-GMAIL-MSGID: =?utf-8?q?1746926009712773486?= From: Ben Chuang This "post" hook for mmc_attach_sd(), uhs2_post_attach_sd, will be required to enable UHS-II support, at least, on GL9755. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro --- drivers/mmc/host/sdhci.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 943701aef22a..e81de556cf78 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -746,6 +746,7 @@ struct sdhci_ops { void (*dump_vendor_regs)(struct sdhci_host *host); void (*dump_uhs2_regs)(struct sdhci_host *host); void (*uhs2_pre_detect_init)(struct sdhci_host *host); + void (*uhs2_post_attach_sd)(struct sdhci_host *host); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS From patchwork Mon Oct 17 09:11:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3326 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348852wrs; Mon, 17 Oct 2022 02:22:03 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6otfWD8+VlCW4FRMVUaWXR51dUufZEFTbGhTQ68DpVL0DK25tPrHP4mTwYE7oLR3tX3tST X-Received: by 2002:a17:902:7101:b0:180:202c:ad77 with SMTP id a1-20020a170902710100b00180202cad77mr11446475pll.47.1665998523601; Mon, 17 Oct 2022 02:22:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998523; cv=none; d=google.com; s=arc-20160816; b=oTtckKKV9JqnmUYDMQ+3urHiSzceObm8sze94X/74eQUqiz8bEmhPjGZfnu1iv2WzZ ByH3afyyffuAJny5SxpjrZBFLgGL6rRYX5uUg20UeEtnpwQjK2GNlI05rcfee05G/TjQ FeOYNUL7uBbRh+TXOM/GTAXCqb+G9hN9j8qghsT7/r9jcpl/z2ldQgmyrKZQb4BBA8ZA AU1D/Q+6AtZciW1hzXyfHRKOmJyTkzmkCBo2thxmVe+TGySWQxwSPUNDatQvoRusvzu2 AUddIKZ2wDDqv7goA/9IZ72PDXMuiVllhk1sbfjkjwLuLVLyM7RomVn3GmEQ3Hq+MNC0 qpMA== 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=+HwnNcHzfM/xxQ8Jc+59AjKb99BR1HhaEozFHr56zf4=; b=09aZ6LBu/fXe2PkHtP9Rby4wlfSzdS1ZJyBgaxKo+xM0y0TAvqPopBaJIbX5VICPUp NhexyO1RCQeVayRySJsyRo9SoI98cTNOQswDtD3wDUg2U26Kmg4vHNsFP5LnBDPO1APE tioh7kMlb6HB96qrleEqf3fC/J+Lci9oDIJsQm6rbWJfpufUApKGTMK/Od9VZ1O6G/MO 4igxhsuab6C5hQLyP1/MlP5m1iiPxfmLi1QLDnaNT6JA7MTm90AaTayIpS6M6UAeIosj +KS+MEtUj9bUAair6VIdMRR+XrNJDKToRscMdAaC96wpSgLsyGuH7JgPw7DTiJF/KaR+ TfcA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=WRQVBXWv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x189-20020a6331c6000000b0043a348b6198si10708901pgx.109.2022.10.17.02.21.50; Mon, 17 Oct 2022 02:22:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=WRQVBXWv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231193AbiJQJPE (ORCPT + 99 others); Mon, 17 Oct 2022 05:15:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231194AbiJQJOC (ORCPT ); Mon, 17 Oct 2022 05:14:02 -0400 Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 710D84CA22; Mon, 17 Oct 2022 02:13:30 -0700 (PDT) Received: by mail-pf1-x42f.google.com with SMTP id m6so10565737pfb.0; Mon, 17 Oct 2022 02:13:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=+HwnNcHzfM/xxQ8Jc+59AjKb99BR1HhaEozFHr56zf4=; b=WRQVBXWvrvje4YgapPZ5rFGu547dh0vShqh1cJHzvQnVeGnVBx2pl0eABvMwDbCgJ7 wY4FMJChxEYorx7OrayveMV7RdUSdyphctaSDyYKoAl/Q4J3GhEvHdsRZngUDHFaOKH7 S0EwsWdyBYxML2eixdO9BUf8/iZlO9RLIppuYH4FTT4W7J8aG9QzJxTJxgAZ69IzpI6T 1pzU8whP4kf9hHTF1wZgpp5VaOCwmhVUp9WET6k1zUxSnD8orOB4JtFOWtBz60ejhaWd 3V3EQ0sCdFw6ss1wJDcHdQXTZD10uI1mcaN4CdDCve6g0eKWonI4d+kkcHeh0fh88AsR 50sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=+HwnNcHzfM/xxQ8Jc+59AjKb99BR1HhaEozFHr56zf4=; b=E+RItTn6eCjLiPoWaQ2sTXkZJ2iaMSOC8TSMPKjTpulKu0ONwKw9fy2scGI2Cu5GKs 2RI/un+IkpS5R9IeqcvQtFpgga1yeE3UaD7sd5ZPOYG1MNWL2kXfBjsabJFFVTU+PqCZ tHnVm/B1mBIVLMTliKFWL2mc9qGzX9r+GqAo2ciyskibFOjzGxP3Av3IPlk/jOuj8WTi bl8U6/OIo16pXzP7EzKuTNbv8lt90CkCtYe5pNSxBxybVtwHC5dcT/4ozxCK/MBNtsu/ VwW2Dv8jK6scJAhjNKm6f1chKRvjLzPb5yG0iWWfbW0Yn9OLKF107IECfx1rzhSXTCea uFlg== X-Gm-Message-State: ACrzQf0nBfo23OTdhR11IVHWYz8s4/6RwXWn9o2YGz1OibFfFGEjRneR UcX9bht7y1uXA2BnThQNBY4= X-Received: by 2002:a62:1684:0:b0:554:cade:6970 with SMTP id 126-20020a621684000000b00554cade6970mr11673547pfw.11.1665998008627; Mon, 17 Oct 2022 02:13:28 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:28 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 25/26] mmc: sdhci-pci: add UHS-II support framework Date: Mon, 17 Oct 2022 17:11:52 +0800 Message-Id: <20221017091153.454873-26-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746926067830857796?= X-GMAIL-MSGID: =?utf-8?q?1746926067830857796?= From: AKASHI Takahiro This patch prepares for adding UHS-II support at a specific UHS-II capable sdhci-pci controller, GL9755 for now. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro --- drivers/mmc/host/sdhci-pci-core.c | 16 +++++++++++++++- drivers/mmc/host/sdhci-pci.h | 3 +++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index a187379ad204..bf6d579aa992 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -39,6 +39,7 @@ #include "sdhci.h" #include "sdhci-pci.h" +#include "sdhci-uhs2.h" static void sdhci_pci_hw_reset(struct sdhci_host *host); @@ -2130,7 +2131,10 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) if (scratch == (u32)-1) dead = 1; - sdhci_remove_host(slot->host, dead); + if (slot->chip->fixes && slot->chip->fixes->remove_host) + slot->chip->fixes->remove_host(slot, dead); + else + sdhci_remove_host(slot->host, dead); if (slot->chip->fixes && slot->chip->fixes->remove_slot) slot->chip->fixes->remove_slot(slot, dead); @@ -2138,6 +2142,16 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) sdhci_free_host(slot->host); } +int sdhci_pci_uhs2_add_host(struct sdhci_pci_slot *slot) +{ + return sdhci_uhs2_add_host(slot->host); +} + +void sdhci_pci_uhs2_remove_host(struct sdhci_pci_slot *slot, int dead) +{ + sdhci_uhs2_remove_host(slot->host, dead); +} + static void sdhci_pci_runtime_pm_allow(struct device *dev) { pm_suspend_ignore_children(dev, 1); diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index 3661a224fb04..7f4a981c0e63 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h @@ -140,6 +140,7 @@ struct sdhci_pci_fixes { int (*probe_slot) (struct sdhci_pci_slot *); int (*add_host) (struct sdhci_pci_slot *); void (*remove_slot) (struct sdhci_pci_slot *, int); + void (*remove_host) (struct sdhci_pci_slot *, int); #ifdef CONFIG_PM_SLEEP int (*suspend) (struct sdhci_pci_chip *); @@ -184,6 +185,8 @@ static inline void *sdhci_pci_priv(struct sdhci_pci_slot *slot) return (void *)slot->private; } +int sdhci_pci_uhs2_add_host(struct sdhci_pci_slot *slot); +void sdhci_pci_uhs2_remove_host(struct sdhci_pci_slot *slot, int dead); #ifdef CONFIG_PM_SLEEP int sdhci_pci_resume_host(struct sdhci_pci_chip *chip); #endif From patchwork Mon Oct 17 09:11:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 3324 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1348704wrs; Mon, 17 Oct 2022 02:21:26 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4gGkrsI0rmPerbzCZFkw1SEoLSBdzwZMyW0Q4/ZLn9VtBJ4f8ptyJHxrCdAaW6XLnIc8R9 X-Received: by 2002:a05:6a00:1947:b0:565:c337:c53b with SMTP id s7-20020a056a00194700b00565c337c53bmr11657538pfk.10.1665998486453; Mon, 17 Oct 2022 02:21:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665998486; cv=none; d=google.com; s=arc-20160816; b=YT2j/R6AVXhPtg0gPNYPqeWj7pECpgbMHtOGVWjJfYjnGLHsaTwJl47l3VIlQjMR/1 AxfeXbkTGu3Uo6hkNQSu69gqQ8qpEiZ9KZ59exK4znD9PPyHB5s5QqLuHP3anEzugTsq GvtCi4N4SxYNF0IrTLrxMduDyTqd31q5mDlCQ5Fo5my0mw1tNW+wpkELC/Z8ACZpXqEc EkC0kt9osVTcvimwzUAc1+/odw5A+gtDUc26U+MNYyyv/D+yzQUXa1Kj0rQfJqdgr+BZ 3oTIGAi3g9MqekbPQ+Q6RHgtJeb5nb9vleozuzsLXBkXbLEWy+OB51oXU6VCHtBkL1px PbXQ== 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=E/q4nAxZOfBpMqDh+qb417qs/nmp+Iu7KHmv0brlGdc=; b=I2ds93LjyntnXl7laPZ/2ROj1C+L7D3fcRy/vbQH18Pvc96TvoVpdtG1xH/W6nDNgU 0TKxTgtzq4Vz2tUWtVeFBr2zguPWu7XQOkaytecn8CtShoIJlDaOdD3Fd+43x0w2/9QO hL7HH6XfaBeDL5MZc3alCzRZPPa28D9zaE3vIRaFTveOBljbgy/bAP+auDePDN8jDFU5 OJVjzsRbnCqnSok7beuJXCTsC+S6INA/qpCzL8aVdIgn7StZ0WfcLysLV1P3D55pqzDD 2QSYV1vS8nwhGEE8RCvKFK9AJicOetSZ6qoFWVMC7X/TdHHoaJeD1Wn9MDKsHLAQZiLY VikQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="aq84b/6u"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k19-20020a056a00169300b005637df79509si11125548pfc.197.2022.10.17.02.21.14; Mon, 17 Oct 2022 02:21:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="aq84b/6u"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231314AbiJQJPW (ORCPT + 99 others); Mon, 17 Oct 2022 05:15:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231270AbiJQJOM (ORCPT ); Mon, 17 Oct 2022 05:14:12 -0400 Received: from mail-vs1-xe35.google.com (mail-vs1-xe35.google.com [IPv6:2607:f8b0:4864:20::e35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B9D8C4E60F; Mon, 17 Oct 2022 02:13:47 -0700 (PDT) Received: by mail-vs1-xe35.google.com with SMTP id 126so10784753vsi.10; Mon, 17 Oct 2022 02:13:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=E/q4nAxZOfBpMqDh+qb417qs/nmp+Iu7KHmv0brlGdc=; b=aq84b/6uPYCvIwAYR+FY/d5yQMNuqAABpRFBpnl3SRPKNzQgkRl3ND1XZSgCskDn77 54LEGCpu5tLdDLrL7jeSMT+SiQ/QifcW7j17Gb0fqkaZwLojLNA1XA9H/wwxbXgHE9Eb 8h2ZGahSyg8o7c4Lq78NGNnxOxEc6X8MoT7lnRXdl9rtwTzkUzTbt5/mWqtKcBIUCno3 M7WO3nTT9ZnBD3GAkG7U1JF57JwRnyLLk28tZHkCVjXHQ7/L+OVyrJZmLfpHEmQ6vvea CWAlZOpuqK4pwlbfNu1U6ABZz4rErUBIYOudAWrPGs0v7TuxjdTMBQXvLUewwKMjxBYO bJ5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=E/q4nAxZOfBpMqDh+qb417qs/nmp+Iu7KHmv0brlGdc=; b=VaNTqaEa4yb+m6lz0XZkes2OP5TF83a7Z7A/4HRn6AZyNp4eiPOrzDzzNGda3/rHCf YKg/QOjOxdK6Eu5UPMQfgn5kGRxqjQQzM3awD+eH1VFO2Qxo8rD3TnhnucpgYC/V87uS mqSGZ6DWcaKpxRN5g00PSNZFoQVguuVj83owmiM7XD8/YR0PjOx81abxC3Ju3ZKIktVJ eKkPEgMPF2wW88aqeo5YyrEa+TvfB2gTV52n34Xd/llLKvf7moABHSilMZCWGxkEW+lN uIUqDbmNE006dlp/OyBlbNFGmoZSYnbIdaCei+8LWjs0vi+nqZmkaaHM14OeDxSdGPEZ oE8Q== X-Gm-Message-State: ACrzQf08XtrO00BeCkQRm3yjDgwDsLBDn6u7gvjEPvOIqK8MfgG6xp9W arkB5HHvk3x/sOAazX5aimiUNBCd5Xc= X-Received: by 2002:a05:6a00:1ac8:b0:563:7d18:7a15 with SMTP id f8-20020a056a001ac800b005637d187a15mr11332203pfv.59.1665998012202; Mon, 17 Oct 2022 02:13:32 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e258-8c34-4ca3-4989-34c1-7890.emome-ip6.hinet.net. [2001:b400:e258:8c34:4ca3:4989:34c1:7890]) by smtp.gmail.com with ESMTPSA id t22-20020a170902b21600b0017f75bc7a61sm6091996plr.166.2022.10.17.02.13.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Oct 2022 02:13:31 -0700 (PDT) From: Victor Shih X-Google-Original-From: Victor Shih 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 , Ben Chuang Subject: [PATCH V5 26/26] mmc: sdhci-pci-gli: enable UHS-II mode for GL9755 Date: Mon, 17 Oct 2022 17:11:53 +0800 Message-Id: <20221017091153.454873-27-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> References: <20221017091153.454873-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746926028920783101?= X-GMAIL-MSGID: =?utf-8?q?1746926028920783101?= Changes are: * Disable GL9755 overcurrent interrupt when power on/off on UHS-II. * Enable the internal clock when do reset on UHS-II mode. * Set ZC to 0x0 for Sandisk cards and set ZC to 0xB for others. * Increase timeout value before detecting UHS-II interface. * Add vendor settings fro UHS-II mode. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-pci-gli.c | 309 ++++++++++++++++++++++++++++++- 2 files changed, 309 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index d89e7bf91c35..28a686610607 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -102,6 +102,7 @@ config MMC_SDHCI_PCI tristate "SDHCI support on PCI bus" depends on MMC_SDHCI && PCI select MMC_CQHCI + select MMC_SDHCI_UHS2 select IOSF_MBI if X86 select MMC_SDHCI_IO_ACCESSORS help diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index 607cf69f45d0..334715b62cb3 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -17,6 +17,7 @@ #include "sdhci.h" #include "sdhci-pci.h" #include "cqhci.h" +#include "sdhci-uhs2.h" /* Genesys Logic extra registers */ #define SDHCI_GLI_9750_WT 0x800 @@ -138,9 +139,36 @@ #define PCI_GLI_9755_PLLSSC 0x68 #define PCI_GLI_9755_PLLSSC_PPM GENMASK(15, 0) +#define PCI_GLI_9755_PLLSSC_RTL BIT(24) +#define GLI_9755_PLLSSC_RTL_VALUE 0x1 +#define PCI_GLI_9755_PLLSSC_TRANS_PASS BIT(27) +#define GLI_9755_PLLSSC_TRANS_PASS_VALUE 0x1 +#define PCI_GLI_9755_PLLSSC_RECV GENMASK(29, 28) +#define GLI_9755_PLLSSC_RECV_VALUE 0x3 +#define PCI_GLI_9755_PLLSSC_TRAN GENMASK(31, 30) +#define GLI_9755_PLLSSC_TRAN_VALUE 0x3 + +#define PCI_GLI_9755_UHS2_PLL 0x6C +#define PCI_GLI_9755_UHS2_PLL_SSC GENMASK(9, 8) +#define GLI_9755_UHS2_PLL_SSC_VALUE 0x0 +#define PCI_GLI_9755_UHS2_PLL_DELAY BIT(18) +#define GLI_9755_UHS2_PLL_DELAY_VALUE 0x1 +#define PCI_GLI_9755_UHS2_PLL_PDRST BIT(27) +#define GLI_9755_UHS2_PLL_PDRST_VALUE 0x1 #define PCI_GLI_9755_SerDes 0x70 +#define PCI_GLI_9755_UHS2_SERDES_INTR GENMASK(2, 0) +#define GLI_9755_UHS2_SERDES_INTR_VALUE 0x3 +#define PCI_GLI_9755_UHS2_SERDES_ZC1 BIT(3) +#define GLI_9755_UHS2_SERDES_ZC1_VALUE 0x0 +#define PCI_GLI_9755_UHS2_SERDES_ZC2 GENMASK(7, 4) +#define GLI_9755_UHS2_SERDES_ZC2_DEFAULT 0xB +#define GLI_9755_UHS2_SERDES_ZC2_SANDISK 0x0 #define PCI_GLI_9755_SCP_DIS BIT(19) +#define PCI_GLI_9755_UHS2_SERDES_TRAN GENMASK(27, 24) +#define GLI_9755_UHS2_SERDES_TRAN_VALUE 0xC +#define PCI_GLI_9755_UHS2_SERDES_RECV GENMASK(31, 28) +#define GLI_9755_UHS2_SERDES_RECV_VALUE 0xF #define PCI_GLI_9755_MISC 0x78 #define PCI_GLI_9755_MISC_SSC_OFF BIT(26) @@ -692,6 +720,276 @@ static void gl9755_hw_setting(struct sdhci_pci_slot *slot) gl9755_wt_off(pdev); } +static void gl9755_vendor_init(struct sdhci_host *host) +{ + struct sdhci_pci_slot *slot = sdhci_priv(host); + struct pci_dev *pdev = slot->chip->pdev; + u32 serdes; + u32 pllssc; + u32 uhs2_pll; + + gl9755_wt_on(pdev); + + pci_read_config_dword(pdev, PCI_GLI_9755_SerDes, &serdes); + serdes &= ~PCI_GLI_9755_UHS2_SERDES_TRAN; + serdes |= FIELD_PREP(PCI_GLI_9755_UHS2_SERDES_TRAN, + GLI_9755_UHS2_SERDES_TRAN_VALUE); + serdes &= ~PCI_GLI_9755_UHS2_SERDES_RECV; + serdes |= FIELD_PREP(PCI_GLI_9755_UHS2_SERDES_RECV, + GLI_9755_UHS2_SERDES_RECV_VALUE); + serdes &= ~PCI_GLI_9755_UHS2_SERDES_INTR; + serdes |= FIELD_PREP(PCI_GLI_9755_UHS2_SERDES_INTR, + GLI_9755_UHS2_SERDES_INTR_VALUE); + serdes &= ~PCI_GLI_9755_UHS2_SERDES_ZC1; + serdes |= FIELD_PREP(PCI_GLI_9755_UHS2_SERDES_ZC1, + GLI_9755_UHS2_SERDES_ZC1_VALUE); + serdes &= ~PCI_GLI_9755_UHS2_SERDES_ZC2; + serdes |= FIELD_PREP(PCI_GLI_9755_UHS2_SERDES_ZC2, + GLI_9755_UHS2_SERDES_ZC2_DEFAULT); + pci_write_config_dword(pdev, PCI_GLI_9755_SerDes, serdes); + + pci_read_config_dword(pdev, PCI_GLI_9755_UHS2_PLL, &uhs2_pll); + uhs2_pll &= ~PCI_GLI_9755_UHS2_PLL_SSC; + uhs2_pll |= FIELD_PREP(PCI_GLI_9755_UHS2_PLL_SSC, + GLI_9755_UHS2_PLL_SSC_VALUE); + uhs2_pll &= ~PCI_GLI_9755_UHS2_PLL_DELAY; + uhs2_pll |= FIELD_PREP(PCI_GLI_9755_UHS2_PLL_DELAY, + GLI_9755_UHS2_PLL_DELAY_VALUE); + uhs2_pll &= ~PCI_GLI_9755_UHS2_PLL_PDRST; + uhs2_pll |= FIELD_PREP(PCI_GLI_9755_UHS2_PLL_PDRST, + GLI_9755_UHS2_PLL_PDRST_VALUE); + pci_write_config_dword(pdev, PCI_GLI_9755_UHS2_PLL, uhs2_pll); + + pci_read_config_dword(pdev, PCI_GLI_9755_PLLSSC, &pllssc); + pllssc &= ~PCI_GLI_9755_PLLSSC_RTL; + pllssc |= FIELD_PREP(PCI_GLI_9755_PLLSSC_RTL, + GLI_9755_PLLSSC_RTL_VALUE); + pllssc &= ~PCI_GLI_9755_PLLSSC_TRANS_PASS; + pllssc |= FIELD_PREP(PCI_GLI_9755_PLLSSC_TRANS_PASS, + GLI_9755_PLLSSC_TRANS_PASS_VALUE); + pllssc &= ~PCI_GLI_9755_PLLSSC_RECV; + pllssc |= FIELD_PREP(PCI_GLI_9755_PLLSSC_RECV, + GLI_9755_PLLSSC_RECV_VALUE); + pllssc &= ~PCI_GLI_9755_PLLSSC_TRAN; + pllssc |= FIELD_PREP(PCI_GLI_9755_PLLSSC_TRAN, + GLI_9755_PLLSSC_TRAN_VALUE); + pci_write_config_dword(pdev, PCI_GLI_9755_PLLSSC, pllssc); + + gl9755_wt_off(pdev); +} + +static void gl9755_pre_detect_init(struct sdhci_host *host) +{ + /* GL9755 need more time on UHS2 detect flow */ + sdhci_writeb(host, 0xA7, SDHCI_UHS2_TIMER_CTRL); +} + +static void gl9755_post_attach_sd(struct sdhci_host *host) +{ + struct pci_dev *pdev; + struct sdhci_pci_chip *chip; + struct sdhci_pci_slot *slot; + u32 serdes; + + slot = sdhci_priv(host); + chip = slot->chip; + pdev = chip->pdev; + + gl9755_wt_on(pdev); + + pci_read_config_dword(pdev, PCI_GLI_9755_SerDes, &serdes); + serdes &= ~PCI_GLI_9755_UHS2_SERDES_ZC1; + serdes &= ~PCI_GLI_9755_UHS2_SERDES_ZC2; + serdes |= FIELD_PREP(PCI_GLI_9755_UHS2_SERDES_ZC1, + GLI_9755_UHS2_SERDES_ZC1_VALUE); + + /* the manfid of sandisk card is 0x3 */ + if (host->mmc->card->cid.manfid == 0x3) + serdes |= FIELD_PREP(PCI_GLI_9755_UHS2_SERDES_ZC2, + GLI_9755_UHS2_SERDES_ZC2_SANDISK); + else + serdes |= FIELD_PREP(PCI_GLI_9755_UHS2_SERDES_ZC2, + GLI_9755_UHS2_SERDES_ZC2_DEFAULT); + + pci_write_config_dword(pdev, PCI_GLI_9755_SerDes, serdes); + + gl9755_wt_off(pdev); +} + +static void gl9755_overcurrent_event_enable(struct sdhci_host *host, + bool enable) +{ + u32 mask; + + mask = sdhci_readl(host, SDHCI_SIGNAL_ENABLE); + if (enable) + mask |= SDHCI_INT_BUS_POWER; + else + mask &= ~SDHCI_INT_BUS_POWER; + + sdhci_writel(host, mask, SDHCI_SIGNAL_ENABLE); + + mask = sdhci_readl(host, SDHCI_INT_ENABLE); + if (enable) + mask |= SDHCI_INT_BUS_POWER; + else + mask &= ~SDHCI_INT_BUS_POWER; + + sdhci_writel(host, mask, SDHCI_INT_ENABLE); +} + +static void gl9755_set_power(struct sdhci_host *host, unsigned char mode, + unsigned short vdd) +{ + u8 pwr = 0; + + if (mode != MMC_POWER_OFF) { + switch (1 << vdd) { + case MMC_VDD_165_195: + /* + * Without a regulator, SDHCI does not support 2.0v + * so we only get here if the driver deliberately + * added the 2.0v range to ocr_avail. Map it to 1.8v + * for the purpose of turning on the power. + */ + case MMC_VDD_20_21: + pwr = SDHCI_POWER_180; + break; + case MMC_VDD_29_30: + case MMC_VDD_30_31: + pwr = SDHCI_POWER_300; + break; + case MMC_VDD_32_33: + case MMC_VDD_33_34: + pwr = SDHCI_POWER_330; + break; + default: + WARN(1, "%s: Invalid vdd %#x\n", + mmc_hostname(host->mmc), vdd); + break; + } + + pwr |= SDHCI_VDD2_POWER_180; + } + + if (host->pwr == pwr) + return; + + host->pwr = pwr; + + if (pwr == 0) { + gl9755_overcurrent_event_enable(host, false); + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + } else { + gl9755_overcurrent_event_enable(host, false); + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + + pwr |= (SDHCI_POWER_ON | SDHCI_VDD2_POWER_ON); + + sdhci_writeb(host, pwr & 0xf, SDHCI_POWER_CONTROL); + /* wait stable */ + mdelay(5); + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); + /* wait stable */ + mdelay(5); + gl9755_overcurrent_event_enable(host, true); + } +} + +static bool sdhci_wait_clock_stable(struct sdhci_host *host) +{ + u16 clk = 0; + ktime_t timeout; + + /* Wait max 20 ms */ + timeout = ktime_add_ms(ktime_get(), 20); + while (1) { + bool timedout = ktime_after(ktime_get(), timeout); + + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + if (clk & SDHCI_CLOCK_INT_STABLE) + break; + if (timedout) { + pr_err("%s: Internal clock never stabilised.\n", + mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + return false; + } + udelay(10); + } + return true; +} + +static void gl9755_uhs2_reset_sd_tran(struct sdhci_host *host) +{ + /* do this on UHS2 mode */ + if (host->mmc->flags & MMC_UHS2_INITIALIZED) { + sdhci_uhs2_reset(host, SDHCI_UHS2_SW_RESET_SD); + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); + sdhci_uhs2_clear_set_irqs(host, + SDHCI_INT_ALL_MASK, + SDHCI_UHS2_ERR_INT_STATUS_MASK); + } +} + +static void sdhci_gl9755_reset(struct sdhci_host *host, u8 mask) +{ + ktime_t timeout; + u16 ctrl2; + u16 clk_ctrl; + + /* need internal clock */ + if (mask & SDHCI_RESET_ALL) { + ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); + clk_ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + + if ((ctrl2 & SDHCI_CTRL_V4_MODE) && + (ctrl2 & SDHCI_CTRL_UHS2_INTERFACE_EN)) { + sdhci_writew(host, + SDHCI_CLOCK_INT_EN, + SDHCI_CLOCK_CONTROL); + } else { + sdhci_writew(host, + SDHCI_CLOCK_INT_EN, + SDHCI_CLOCK_CONTROL); + sdhci_wait_clock_stable(host); + sdhci_writew(host, + SDHCI_CTRL_V4_MODE, + SDHCI_HOST_CONTROL2); + } + } + + sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); + + /* reset sd-tran on UHS2 mode if need to reset cmd/data */ + if ((mask & SDHCI_RESET_CMD) | (mask & SDHCI_RESET_DATA)) + gl9755_uhs2_reset_sd_tran(host); + + if (mask & SDHCI_RESET_ALL) + host->clock = 0; + + /* Wait max 100 ms */ + timeout = ktime_add_ms(ktime_get(), 100); + + /* hw clears the bit when it's done */ + while (1) { + bool timedout = ktime_after(ktime_get(), timeout); + + if (!(sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask)) + break; + if (timedout) { + pr_err("%s: Reset 0x%x never completed.\n", + mmc_hostname(host->mmc), (int)mask); + sdhci_dumpregs(host); + /* manual clear */ + sdhci_writeb(host, 0, SDHCI_SOFTWARE_RESET); + return; + } + udelay(10); + } +} + static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot) { struct sdhci_host *host = slot->host; @@ -700,6 +998,7 @@ static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot) gli_pcie_enable_msi(slot); slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; sdhci_enable_v4_mode(host); + gl9755_vendor_init(host); return 0; } @@ -1092,18 +1391,26 @@ static const struct sdhci_ops sdhci_gl9755_ops = { .read_w = sdhci_gli_readw, .read_b = sdhci_gli_readb, .set_clock = sdhci_gl9755_set_clock, + .set_power = gl9755_set_power, .enable_dma = sdhci_pci_enable_dma, .set_bus_width = sdhci_set_bus_width, - .reset = sdhci_reset, + .reset = sdhci_gl9755_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, .voltage_switch = sdhci_gli_voltage_switch, .uhs2_reset = sdhci_uhs2_reset, + .dump_uhs2_regs = sdhci_uhs2_dump_regs, + .set_timeout = sdhci_uhs2_set_timeout, + .irq = sdhci_uhs2_irq, + .uhs2_pre_detect_init = gl9755_pre_detect_init, + .uhs2_post_attach_sd = gl9755_post_attach_sd, }; const struct sdhci_pci_fixes sdhci_gl9755 = { .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50, .probe_slot = gli_probe_slot_gl9755, + .add_host = sdhci_pci_uhs2_add_host, + .remove_host = sdhci_pci_uhs2_remove_host, .ops = &sdhci_gl9755_ops, #ifdef CONFIG_PM_SLEEP .resume = sdhci_pci_gli_resume,