From patchwork Fri Mar 31 10:55:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77720 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp471597vqo; Fri, 31 Mar 2023 03:58:04 -0700 (PDT) X-Google-Smtp-Source: AKy350ZotFcE2eu3E+IV/pePX+Erj9VRbVmNtmqOJA20uA4R/s7XKKn0TekV2WhzhpEM+c7GvwJ9 X-Received: by 2002:a17:903:1109:b0:1a2:38a3:7958 with SMTP id n9-20020a170903110900b001a238a37958mr28353411plh.1.1680260284518; Fri, 31 Mar 2023 03:58:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260284; cv=none; d=google.com; s=arc-20160816; b=CcictDV4XuDZrrIDezkE9eWKTq1ZO92arbQQVCCsxV5EAKqXEFcLFwigEP9NnmnYXv 6rRNX+1Cp2LHyDCCOBxkWopDLO30t5nbmbiSr1iTileRngA8tmR2Jl9pRmvRkvJuSbBa vapu0li+bw+IEBaphDUCkPngkKzZyffGQetbfI2ho/iJUc4WtU9EiQ23kNRuiuaeNQmU jUcsQidEoeXLrrxvZzr7HfWcUnvmb1ubnNdt3W7hP3xU4yLsOz2aZGOs3PCf5LjYn7xv NdkjOlDh0gYNcoEe1XJ7WqgeEomGEffjZltoy7ZCb216uOD65fNsT5tL5S949w8lxY56 4gig== 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=4CnmHFKdPQEHTvZNRYXNIZZMHyo/3bfUyI7H1X7Tf+A=; b=nfCJi3QqA9apDfhcCviMgxN8sUBu9FKrbk5b8meaqqarweqI+jlCRCF3srMKhy6IcY AwEcjp3GgB9L3U9+ov7JjSo0ew7zDJH5QghxyU/jV2tY/oMv+IPbwwT0hF8vTl6FRK5k W2B5T8PrVNWB2BoJ9tG9mGRzWad/RDNiW62Kgy5oTovAHB5W80dmRn2zdexXUM95YXlk yP4l/6UAyqxA2rxhz1fP4eJZ/8mHfR9dqZbriMn3gHkuP+kd/QbqnpVNb1pHk2852nMl +OvJXmfAVKg6eSBxo6nkzoRVGaoTclGvLvrHexmPznj6V5vB+WWxUBGT6bDe3QkLSQjz yvog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Me10YJcx; 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 b7-20020a170902d50700b001a1aa5d3ba4si1969847plg.416.2023.03.31.03.57.52; Fri, 31 Mar 2023 03:58: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=Me10YJcx; 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 S231771AbjCaK4n (ORCPT + 99 others); Fri, 31 Mar 2023 06:56:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230403AbjCaK4Z (ORCPT ); Fri, 31 Mar 2023 06:56:25 -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 528BF1E730; Fri, 31 Mar 2023 03:56:10 -0700 (PDT) Received: by mail-pl1-x633.google.com with SMTP id o2so20872968plg.4; Fri, 31 Mar 2023 03:56:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260170; 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=4CnmHFKdPQEHTvZNRYXNIZZMHyo/3bfUyI7H1X7Tf+A=; b=Me10YJcxdjrStL7uupP5YkyqYD8CoNBSTlFDEE7Xl91kSw8zfTYRgPJ8UxAbp+axGj J7W55RSOeijXPtv3rvhjMps5juGdF7jhvX4XgY+XMqQVLFaBXb7ftygmKHZw8q8KITwP T7EfUuXrMBr5Sh6Ff8ILiUsWYclFc5YIc4b9KuLLDpMMsSWhSR1V320OnQGFK1ul2A5X /5jX6+l99D+yEyI517c4mW8e7MQLBFc79v2u1VPxh6vORcIqg/wsm9K2q8kZkfudvgTV zrSYmffHG71xV++LBMOmiooro/XSQCZNKQnxxPjaphRbpeY0TacIfxbkTROXxJku0OKH Fqew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260170; 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=4CnmHFKdPQEHTvZNRYXNIZZMHyo/3bfUyI7H1X7Tf+A=; b=AMSu637zqeEDJuKjSh+ry2c6cAT7zZBU7SsTkd7i1TiDHMKgqeD6+ymPLyj18Uahdb VZzD2pz1wCT4mttgeZhitopvEacl9hCc0Ixh8cnEIqOPy+OiAsQO2p+azgi+PwRW7irX yA5+USVxdKVOWe+vDzHpsYsRB5daXpbjeEICkHlPH9BXp+TWW/hrrWIz4IELJcFhWfAm 6CYcHOkDgDFoG+po+/XwPwyTo1XUiGluMNdSjA75cT6yanhss1x26tEFlHTEL/d5Df0A SUhXf8UeQ832w+OPHoWL823uWtlXFsg9UuMAj3xtvhh8oLMUU7+im9crdy1EdCLSmMV4 Ywtg== X-Gm-Message-State: AAQBX9dTSuWZukD8QAdX4B7OvPookqZsseq6djrZlsi4/7YVPkgjBiLV Fj8NjE5umbASVZ07aoh/sfM= X-Received: by 2002:a17:903:247:b0:1a0:4859:19ea with SMTP id j7-20020a170903024700b001a0485919eamr29574732plh.39.1680260169748; Fri, 31 Mar 2023 03:56:09 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56: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 Subject: [PATCH V7 01/23] mmc: core: Cleanup printing of speed mode at card insertion Date: Fri, 31 Mar 2023 18:55:24 +0800 Message-Id: <20230331105546.13607-2-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761880607998175492?= X-GMAIL-MSGID: =?utf-8?q?1761880607998175492?= 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 Signed-off-by: Victor Shih --- 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 2c3074a605fc..cf32cf135781 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); - } mmc_add_card_debugfs(card); card->dev.of_node = mmc_of_find_child_device(card->host, 0); From patchwork Fri Mar 31 10:55:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77734 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp478870vqo; Fri, 31 Mar 2023 04:09:19 -0700 (PDT) X-Google-Smtp-Source: AKy350ZpShdGxIArGtdN72utj/at63i/LcrZ8TAdA3w1ZQtUXk8QiVfuCiPUbteUdC8ksSDB5XtM X-Received: by 2002:a62:604:0:b0:627:f1f1:a97d with SMTP id 4-20020a620604000000b00627f1f1a97dmr24287846pfg.24.1680260959690; Fri, 31 Mar 2023 04:09:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260959; cv=none; d=google.com; s=arc-20160816; b=I0ZyAcv+w+HLgT5HpzP1lESgRPR8asIQ3Fxi2NLPqxBbEqPmoP5oHNsqOgWG9cUHei oyOF5ynWvrZitOkxDXAy+1qlGkiEHF+5RiEkH0uI0X+tnrr2QEULftsZjCGl3iVc1ZKn vQ7bRL2oReX7seeWExkZxD+OFOQZ//Jnx3ry+PamRpb+TXUyaD0V0GvAQC296+q/A7DV KwkzABjMJ7XnjU5SgsS+llVHvdomITTHS0Tzo1jtKNHtKDUQaxOXQOqk+EjZYq8niwrd dFYLaYETEZ9g0VDy4jj9ai/Zq7hB///pHpIlvgxT/588l53WwstQQr+lKhgFdqrllemq b58A== 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=+1xJwSpjEKOHbKZqqJfmu0w8WM49C7u79zqodXUILdA=; b=qf/uczqZanBYUH/ygySHpxRXx0KW7SjyqZadM9kXtH+tSL4mkqQIV+YbD9tklalO1Q OWqcWMgBFGt2z2Il4zD+2/d853SRrvR6zkg5aZxZbJdFWNVW4zSMwiSzb2I9cp8EvtVv QYISJpsSNBNyCEqMLcizUFFV3HAAmFSNS3IIq8GhJhxfb/RpZEO/c9+tmtxz1j7bTl81 gXJy2q0mF0hZDtLoD12m0rZafZ+lhUt3/Y8CfLA4unGLaG8eItMWRXCXJEdu3qbhaVqB CqJiUUXAtxI3A96hHqq58uUcm2/FpIOxVBd+U2wpUc75Uh+gt9QPgpFayNvaMIdxGLep FG7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=pmEirXVA; 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 i12-20020a655b8c000000b0050bfc20c788si2159932pgr.282.2023.03.31.04.09.07; Fri, 31 Mar 2023 04:09:19 -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=pmEirXVA; 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 S231723AbjCaK4p (ORCPT + 99 others); Fri, 31 Mar 2023 06:56:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59610 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231626AbjCaK4Z (ORCPT ); Fri, 31 Mar 2023 06:56:25 -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 C4AF41DF84; Fri, 31 Mar 2023 03:56:12 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id f22so16745827plr.0; Fri, 31 Mar 2023 03:56:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260172; 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=+1xJwSpjEKOHbKZqqJfmu0w8WM49C7u79zqodXUILdA=; b=pmEirXVAemm+fiw1873TgPH96za+ovBiy70AZNY+cmQjsSi76Grhf+iHJKDVj+yOnq FklxlB5O6BwhvLVM37H4WS4I9dRj37uQ9/0S6/h/5RKbeBqwUENfGMxkEH+b/NTX5lS/ RSTCwWGDrZYm6nkrZWksRLxNlejqTwABQOVNF8PWmXK1KXJemdkaY1IlEfDg7limGsfY Kdf4U3DtnNw+NgFhWd6Hm7lg/WFrA8/ysYuyrQ8zIgmaIiol4v/PE4pBoC8yztR1em1/ RwwhPfgMLS6NtQOxWOrVShz/ddaOJw2RA/Wkwuu30QabsOPwxi81l/YY/gne48OiC2GC l1cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260172; 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=+1xJwSpjEKOHbKZqqJfmu0w8WM49C7u79zqodXUILdA=; b=tmBkdu4eAlpVLnhtBuacyEGGk/A6VY+xz/S/7RpZ3YtYddzfOfXuf0ktsgPR9o6c6r bwbsHHE3K7+YBdwPRfieKxCmqZgdNjBgP6cMfLHU+7sRw9oupBNs+yg+6FK5yTk9IYP/ h8MaifIY2o6F6c1cGDlOAN0tCrbDAXSm6ucA44/RlqVkk+cOtNHveyRgukTuKMStDiwH 9bJwOfd73eBWHuaKkBp5Ryjpc6zkQwhz0dAojByHg0ZNDWK0zPSPAJBBfbEiyb/jjbsg zAjWW5RtERraFLZHICFEhJTtClqM85C+fRrnNNMDq5sPaeaL1JdzGhBxOS263CjjZvWD TTow== X-Gm-Message-State: AAQBX9cJXeuqVoN3RWMSa48QgYQu6Nm1eMh81YUarqLg8XNfez4F9HG8 sQbzjJSl63SyxDk1g5VGpQtP6v828EA= X-Received: by 2002:a17:903:288b:b0:1a2:63af:e980 with SMTP id ku11-20020a170903288b00b001a263afe980mr12693741plb.13.1680260172104; Fri, 31 Mar 2023 03:56:12 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56: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 V7 02/23] mmc: core: Prepare to support SD UHS-II cards Date: Fri, 31 Mar 2023 18:55:25 +0800 Message-Id: <20230331105546.13607-3-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881316083937322?= X-GMAIL-MSGID: =?utf-8?q?1761881316083937322?= Updates in V7: - Drop sd_uhs2_set_ios function. - Used ->uhs2_control() callback for uhs2_set_ios in sd_uhs2_power_up(). - Used ->uhs2_control() callback for uhs2_set_ios in sd_uhs2_power_off(). - Drop MMC_TIMING_SD_UHS2 in favor of MMC_TIMING_UHS2_SPEED_A. - Modify sd_uhs2_legacy_init to avoid sd_uhs2_reinit cycle issue. 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 Signed-off-by: Victor Shih --- drivers/mmc/core/Makefile | 2 +- drivers/mmc/core/core.c | 17 ++- drivers/mmc/core/core.h | 1 + drivers/mmc/core/sd_uhs2.c | 294 +++++++++++++++++++++++++++++++++++++ include/linux/mmc/card.h | 7 + include/linux/mmc/host.h | 22 +++ 6 files changed, 341 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 3d3e0ca52614..ba8808cd9318 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2244,6 +2244,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) { @@ -2276,10 +2288,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 37091a6589ed..920323faa834 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..06b2aab52b93 --- /dev/null +++ b/drivers/mmc/core/sd_uhs2.c @@ -0,0 +1,294 @@ +// 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_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_UHS2_SPEED_A; + host->ios.power_mode = MMC_POWER_ON; + + err = host->ops->uhs2_control(host, UHS2_SET_IOS); + + return err; +} + +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; + if (host->flags & MMC_UHS2_SD_TRAN) + host->flags &= ~MMC_UHS2_SD_TRAN; + + return host->ops->uhs2_control(host, UHS2_SET_IOS); +} + +/* + * 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; + + 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; + + err = sd_uhs2_legacy_init(host, host->card); + 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 c726ea781255..4a42f31b7bb0 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; @@ -317,6 +322,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 461d1543893b..a27bb520bf9a 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -63,6 +63,10 @@ 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_UHS2_SPEED_A 13 +#define MMC_TIMING_UHS2_SPEED_A_HD 14 +#define MMC_TIMING_UHS2_SPEED_B 15 +#define MMC_TIMING_UHS2_SPEED_B_HD 16 unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ @@ -91,6 +95,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 +153,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 +415,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 +442,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 Fri Mar 31 10:55:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77742 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479700vqo; Fri, 31 Mar 2023 04:10:42 -0700 (PDT) X-Google-Smtp-Source: AKy350ZrtqEPicZk2tAa93Beg0/lC1AwUMV0j1UzxicfrTslZSj4Mx8xiKfY+Qsf933WGQb1zLCD X-Received: by 2002:a17:902:ec91:b0:1a1:dd3a:7509 with SMTP id x17-20020a170902ec9100b001a1dd3a7509mr31233011plg.48.1680261041825; Fri, 31 Mar 2023 04:10:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680261041; cv=none; d=google.com; s=arc-20160816; b=xjQL6Cn4HPj2DpOFdcMgcndtAz1VES6zmzLQi7gFahI9F24cYJNOhx1MHw+0ymJPpy JbOHIQwqTK2wjKNVguYcKPpYW5J6pnJNe7QLhRBeVYxesBYubMC5mkkkSqJC60+7RdsV 0zdd6/xasK696IxPXqGIi4sokwJA4JY/eiej3r+aQKcbamiVjBmQHHwxzi0KSd9jlKd9 zZ5eJg4NpYlgtd6cPE7uKLO18SaV7wEpB65KXW9AmYtFRSgiZY0hrhhgFzg7FzI91RY1 e07XcJDlqo6PIHc9bL+IsrFmxqiZC2lijVxtgE0nzpbB8iPsOKEnqi3qB8ckkNLw5+Pn XcaQ== 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=57+Q3zgUW+vus6MufB9IOoUHGrT/XyfGfE6odShrlgU=; b=B2BNKXNYDy0lidooa7Da3h8n4WiyXklo9cRQzM4e3bEdmST0A2xyn4jkIcTLbZ+Qu0 rY8zUkjeH2A8GX3C5urT70e8rM7z+O3pC2U0eBPtlhqwgb+D/QOOwX0PygqtTIK2AtP9 lKYnaGqwU7t0Piw5yh37qp19JQioc8ciR1HLbRCkHVnLl/IndmkUuHO7gmX+fYkaQBkP zXZcvjNn0f1f3e2piAdTBTgsKu71lsAAqFIMLUFGtbnpZau4fkWzODyyZQAEaEV+hNUp o9RqEN1Hx24kYcT5hDHcx7tCCqAJGVWQXQ4uRNJxx/AyBM8larhBt4zweeLNZAbrVbS9 aDlA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=qTHZTx92; 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 v202-20020a6361d3000000b0050bcc130779si2067758pgb.28.2023.03.31.04.10.29; Fri, 31 Mar 2023 04:10: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=qTHZTx92; 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 S231757AbjCaK4t (ORCPT + 99 others); Fri, 31 Mar 2023 06:56:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231736AbjCaK40 (ORCPT ); Fri, 31 Mar 2023 06:56:26 -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 7ADFB1EA0B; Fri, 31 Mar 2023 03:56:15 -0700 (PDT) Received: by mail-pl1-x62e.google.com with SMTP id z19so20883212plo.2; Fri, 31 Mar 2023 03:56:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260174; 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=57+Q3zgUW+vus6MufB9IOoUHGrT/XyfGfE6odShrlgU=; b=qTHZTx92EJRF6NVQOJCdZho24EEOslckI6CvV+V8nsg4XBXvZ7KAuM1B2FwaL5MAP3 +s9TDsx+P2/+6sGRoMD73EOyV/5CedDlQ8hbp8cEDXxbVnRzNgtTOAIRblWk2nJvXgyn vWSwxT0pXtxb2JzbNxWLiUWnkANduf/+hRp6Hl9Wd4eXhofPH+c2Ojr7I8l95YxAgYqO G/2uoUs5v0VSYn3NMCwnCDFcrQnpDZMyZqge6Y0foFMIBS96tW0Vir5C4MV3mvnSsGjK JBeysyraJNU+WAYrJUNuSPACLYKhRekO/UApc17zps04GR4fHG6a0Z/I8m8g59opiqHT Hovg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260174; 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=57+Q3zgUW+vus6MufB9IOoUHGrT/XyfGfE6odShrlgU=; b=qohyz4ljGiW0iA6VMo8JMDMQzaASgMlXxoEaRW8TrpKPE7EBGiQTPWg9vikEsT2+zm SPirt+spmJb540Vba78is5B0jAfNJ/yMEcD645Ef5IhopRqVMvKFQqj+Znhn7vXkxpIj H15yp34kRqbDLYgi+LLH8V/ICsofb+qmvY2uWHjpL/QOa3nSGVk8Gwx1FTXDkaL+YRix McaXV7wDcRH/DLAbilh0VH9NyyhSYsyNxnCT2vbl5dr6yGQWYjhMoH3wGFxFD7kfGBw3 Rnz+0ao2Xs4pUaUl7oQIHfeQGleEZLaPVP9mdSo3joBrUP03VYAPTjYpoHaTvHBDhsym 0KRg== X-Gm-Message-State: AAQBX9ekg2IoGR+4IHcJ7bCZdA0J9gB10DZyJZdze8l4mZFvGRkhMF9z hgUxXBeYVsE9dt1VJqaaBFM= X-Received: by 2002:a17:902:e5c7:b0:1a1:be45:9857 with SMTP id u7-20020a170902e5c700b001a1be459857mr31113011plf.1.1680260174516; Fri, 31 Mar 2023 03:56:14 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56: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 V7 03/23] mmc: core: Announce successful insertion of an SD UHS-II card Date: Fri, 31 Mar 2023 18:55:26 +0800 Message-Id: <20230331105546.13607-4-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881402381652147?= X-GMAIL-MSGID: =?utf-8?q?1761881402381652147?= Update in V7: - Drop MMC_TIMING_SD_UHS2 in favor of MMC_TIMING_UHS2_SPEED_A in mmc_card_uhs2 function. 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 Signed-off-by: Victor Shih --- drivers/mmc/core/bus.c | 4 +++- drivers/mmc/core/host.h | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index cf32cf135781..d9a3b3d38d8b 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..9f6e5e31dfea 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -89,5 +89,12 @@ 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_UHS2_SPEED_A || + host->ios.timing == MMC_TIMING_UHS2_SPEED_A_HD || + host->ios.timing == MMC_TIMING_UHS2_SPEED_B || + host->ios.timing == MMC_TIMING_UHS2_SPEED_B_HD; +} #endif From patchwork Fri Mar 31 10:55:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77736 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479114vqo; Fri, 31 Mar 2023 04:09:44 -0700 (PDT) X-Google-Smtp-Source: AKy350ZYvq6jsJ03wXSNIKxtXI3w/9yLUBZEof8/J38KdozWsC4HZRSkgQthAEj73QFkqHKMAoUg X-Received: by 2002:a05:6a20:4a30:b0:df:4e86:9c99 with SMTP id fr48-20020a056a204a3000b000df4e869c99mr17680777pzb.55.1680260984461; Fri, 31 Mar 2023 04:09:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260984; cv=none; d=google.com; s=arc-20160816; b=OfbYmC2tVDfyWAi3YIQ+xseMPr+WNUktcc7Pa3ZKQTqNq6XyL+4SaYE1rdZXDNMvzY 2ugZd0F7nr2LoyHDQVRDfEniWVrWo8JuViw5lUMWrCVwbh2sgG/SQdgXmsyMRnm3v2h4 tavGJ99uG8pl0UdDXUDd1adTkqthauiquhV0jypaKFcgT9J8kVOBFO85Z3MOdyWpx1By 01AN+0r2DqdMMHV5NvOXyTaKXGHdPLdDC/6P7hNPne4MLY9CYpa5xLhfaOiHAYyhXftL lGy7wy9oniPHzr+Z/iP2SmkdoBY8sSgbMzX8kgjO+Dkz9oDPVjQbndlR8OvMbj3h1Ei2 R7rA== 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=4nxZ6ysc0NWh8raehRAJJdNoEHZEjQQLqxHOoCPHHTo=; b=MXqVxspMOV3ZZPgAs9QxPTMcw0+oibvOQLnf9amHJh/IM0+VlLM8eA0K+TeyimxpwH o06lZKYcDHRvSOMEpaTyeKYo7dIkp4aGJOEVODiSSCrBYWparzgCk2jJC60wtc45ubYI rEcb4f/iGYZgmkfEyrWHlVYFFp/0RDzRHoKwV/CscFAQqXpnjfObz9pmuVkqJbq9kPTc A5iI+jUxvR6P52Udyu4ax+qV1a3ZExWXFnDo0e5xBnAd4RApuesotVAumGayLtAAOJs7 svpI5YcKC4nFBx+FSGFqBzICtaMKwN6wOPL9nZiGBqHGQO19COhuPXCi7dzSYAGBP2F9 S8aw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="G/m/Ch+x"; 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 h124-20020a636c82000000b0050b51e62c19si2052976pgc.825.2023.03.31.04.09.32; Fri, 31 Mar 2023 04:09: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="G/m/Ch+x"; 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 S231825AbjCaK44 (ORCPT + 99 others); Fri, 31 Mar 2023 06:56:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231345AbjCaK41 (ORCPT ); Fri, 31 Mar 2023 06:56:27 -0400 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0ADEA1D2FF; Fri, 31 Mar 2023 03:56:17 -0700 (PDT) Received: by mail-pj1-x102b.google.com with SMTP id h12-20020a17090aea8c00b0023d1311fab3so22960318pjz.1; Fri, 31 Mar 2023 03:56:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260177; 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=4nxZ6ysc0NWh8raehRAJJdNoEHZEjQQLqxHOoCPHHTo=; b=G/m/Ch+xFFuDeZPu8cxR+T17IjUad2Haj0sd6CNs/7OmVVTpO+X/h6HvDf6vDWKdza eY8NcGX6r1wUrTSinX6eugftnMxzCL/U7HtaAVJQsXfwiTumywnRxvrWqSIqtz5Nfc35 gHDKp2ivEWjMnzalHZSEgkjzf94NMzUShTxD4z9ev+d7OHShPKpEHTml30+hExruUchB 2uC5+1YcRdgd/Wx2TlEEfI9QcE3cC41j3EVrYmMis75ex6VmfwDRhhlqaCDdRIkXfjGL sFlSAmT3HT985w0R7GAOxYGFcUg2xj/NFZ/T/q8t6YrckwXVczsmHqw47NENfCmFjrLz a83A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260177; 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=4nxZ6ysc0NWh8raehRAJJdNoEHZEjQQLqxHOoCPHHTo=; b=QU068WaWY5W3WrN/yDb85pI41HY4ESrw7DSJTI/wVWfWvPWi33CdQYnw54XMxMPhE4 0Wc78MXgd/fB1NAaLKYLMzUqFR3HcSmhIhHIzb9sZKyzR9GsYwoKeSkxgGoRJRSh9KbP eVphQbdiWvZasng5ihVRfnvsgdY+xatpHUKMMlRcDPK0UPU9Nv09TD/fQUR1vuBwZtyy hyr5oiWpodsqftiHmaL51945B+thNb4qEynBR9GmDWyOTt551hTEbnMUYBg09sauv/VI gtoZsVU4qQVZGgDpUuZ+wMhB60ImwvSHw0vIa4VZUoHMs8q1HRhSoExzDTP+Pm865Rq1 EisQ== X-Gm-Message-State: AAQBX9el3LV6jz70T4WlTDBdkAQ07IDrcfhVBsttdpyCQff8owaDXgan UO3DDznzJGQHaTau97r0MAs= X-Received: by 2002:a17:903:11c4:b0:1a1:a727:a7fd with SMTP id q4-20020a17090311c400b001a1a727a7fdmr30907595plh.29.1680260177019; Fri, 31 Mar 2023 03:56:17 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:16 -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 V7 04/23] mmc: core: Extend support for mmc regulators with a vqmmc2 Date: Fri, 31 Mar 2023 18:55:27 +0800 Message-Id: <20230331105546.13607-5-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881342395736458?= X-GMAIL-MSGID: =?utf-8?q?1761881342395736458?= 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 005247a49e51..208c27cfa505 100644 --- a/drivers/mmc/core/regulator.c +++ b/drivers/mmc/core/regulator.c @@ -226,6 +226,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) @@ -252,6 +279,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) @@ -271,6 +299,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 a27bb520bf9a..703f5ce9713c 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -74,6 +74,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 @@ -324,6 +327,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 { @@ -605,6 +609,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, @@ -618,6 +623,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 Fri Mar 31 10:55:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77725 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp477023vqo; Fri, 31 Mar 2023 04:06:12 -0700 (PDT) X-Google-Smtp-Source: AKy350Yf55bsAp+aSM1EM+zcEmzhuQoSdr4GJaEQVTjD7kRSXRYitn99oMcSTFuPeBAFuk2FG6Tb X-Received: by 2002:a17:90b:350a:b0:23b:4388:7d8a with SMTP id ls10-20020a17090b350a00b0023b43887d8amr27625650pjb.21.1680260771834; Fri, 31 Mar 2023 04:06:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260771; cv=none; d=google.com; s=arc-20160816; b=RMqXBPZGNYXr/0XMVy8nKrn3EpSYfuCayGFessu6K/+zooVW2vWcvMGaSbheT39CFN 88iID/7RlgmCMmDfgGMh3K+e3LKb7d2QrpoEu37fpIjg0A/TOXa26QOSQbwSivl12+PC HEcV8iygfJHi1Mbag6lpsQxZE86KJcJnYvXbbliPoghw/2bOdIM/8tFrUPxn47cgc784 s4tgPgP4RG0CVyZjQjzn1dJ78CJ+BcH+M1eiJWCBSaqYP44ANoUFeyCVI6dzmTlVCG+w c6TUitz1EduPlW0Nb1zceXVApVIZwcn4w96jcuo2QOIjxFC8dACZTdPOJkzvR6zLONwC GjkQ== 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=t6RUdpSX04dBLtzIjrw3rQA0gsbOjhQ17pBF0AtYfG4=; b=iZkmz1kC/4O1UlN7TzYFBmG3hZ0Cv3WbyNPQpWzc7ITCOGkABcYnaBV7rNY9adhIEg bPcp0KfxzQoistzP+LFlnGJePpvqDtIYJT41cFBIMy7o96z5WbjistrAE3ZkOnJu4+5c fTwHCuK4eNjii9C85WBadZX5I8/XA8t2UX/cyT/aVaLJsBnSiCj9ektbwu7RQFkvKaNn Fzq3vJD/VeqWQ+CShj99F1K3acqQdchjzEwqu44H59JQeH/81C0BlaTjNRS7/I/MHwjG e8ouXIVgRtcTaSBcYn2WS3XzL0PLTyb/g1a2RpaQpADTIW2DlpLpTITRrye331xzcggt qYUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=U0DNnLkK; 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 n16-20020a170902d2d000b0019a95ab6b4esi2093821plc.407.2023.03.31.04.05.57; Fri, 31 Mar 2023 04:06:11 -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=U0DNnLkK; 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 S231387AbjCaK5F (ORCPT + 99 others); Fri, 31 Mar 2023 06:57:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230445AbjCaK43 (ORCPT ); Fri, 31 Mar 2023 06:56:29 -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 5DA0D1EA14; Fri, 31 Mar 2023 03:56:20 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id mp3-20020a17090b190300b0023fcc8ce113so24960230pjb.4; Fri, 31 Mar 2023 03:56:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260180; 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=t6RUdpSX04dBLtzIjrw3rQA0gsbOjhQ17pBF0AtYfG4=; b=U0DNnLkKdkpLgcuRd6vf7YEJwVGwJNtZ/U7pteehdz5Ahtcw3lMNzPVtmPaoAyaSKX K23K6VbF0ii+iFa8h46X5e7hVteboctr1gguVSL5XAZk8PZ3Kak7h2+h4DOmDqGqaBbF pxX4Qyb+13heq6Hvqj5iqwVqRO3wupShDtsJDIFhpu8+7XQh6Ows5CkVwuei4SbeTSk4 xpXaQEWz9Mk8ED+63hrCpmJejBO+/5MxlptZ5kKTu9BkQHj7qtxvapE0hBBL+do69FR4 f+apy8t17JQoJ1TOj8khAigtKvcJWQMtQp1a1r7GteMSZIh3LMtwmLwCwT1qDw4b+ZFP RQdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260180; 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=t6RUdpSX04dBLtzIjrw3rQA0gsbOjhQ17pBF0AtYfG4=; b=aivNKO087IjYuzx1hz2Wz/yz1ul4uYT+ft/bJ36eiw9S6OGeMhmR1Tcj/uQfW1nIBX 9Hc0uKK5LZIyDs+XEIPKLOkLxSOsq9KiaT/inoLk8QqP/fA+XAGhrbTnkPnrYtDG69cO 93r4PNi1RSvj7Kwn/+Cp7KMwRYfzBmUFhUa/N0G3qMxtLnJLRj7aWVaqqnC5dAvWptnY SzIeC2es9wI8Tu96+F6qKGAmg3cG/KVBMR1u0z8vhyGwsw+CZVbQOGTK4wsOQSADYB2J MAtOuDfXYQ9YG58nEq5g/EejCX1iFv0gJeA1M2QilAxVyisB3dDhhYDPe3RdDfe7yP6+ Pszg== X-Gm-Message-State: AO0yUKWrsR9Dd8U6XVcpOaGC/koRY6ZF/VfH3jfuVpS5HHHyHPGnytHN mAjyrgPjWKA1UC2acxjqCrg= X-Received: by 2002:a17:90b:4a8b:b0:23f:1165:b49f with SMTP id lp11-20020a17090b4a8b00b0023f1165b49fmr27211459pjb.38.1680260179697; Fri, 31 Mar 2023 03:56:19 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:19 -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 V7 05/23] mmc: core: Add definitions for SD UHS-II cards Date: Fri, 31 Mar 2023 18:55:28 +0800 Message-Id: <20230331105546.13607-6-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881118653973715?= X-GMAIL-MSGID: =?utf-8?q?1761881118653973715?= 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 | 31 ++++- include/linux/mmc/core.h | 13 ++ include/linux/mmc/host.h | 60 ++++++++- include/linux/mmc/sd_uhs2.h | 240 ++++++++++++++++++++++++++++++++++++ 4 files changed, 341 insertions(+), 3 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 4a42f31b7bb0..3a712dc09492 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -190,6 +190,12 @@ 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) + +#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 }; struct sd_ext_reg { @@ -213,7 +219,30 @@ struct sd_ext_reg { struct sd_uhs2_config { u32 node_id; - /* TODO: Extend with more register configs. */ + + 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 max_retry_set; }; struct sdio_cccr { 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 703f5ce9713c..8803fe46ed24 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 */ @@ -99,7 +100,40 @@ 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 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; +}; + +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_IOS, }; struct mmc_host; @@ -234,6 +268,14 @@ 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); + + /* + * 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 { @@ -326,6 +368,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 */ }; @@ -347,10 +390,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 */ @@ -446,7 +491,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 */ - struct sd_uhs2_caps uhs2_caps; /* Host UHS-II capabilities */ + int flags; +#define MMC_UHS2_SUPPORT (1 << 0) +#define MMC_UHS2_SD_TRAN (1 << 1) + + bool uhs2_app_cmd; /* Host UHS-II APP Command */ + struct sd_uhs2_caps uhs2_caps; /* Host UHS-II capabilities */ int fixed_drv_type; /* fixed driver type for non-removable media */ @@ -698,6 +748,12 @@ static inline void mmc_debugfs_err_stats_inc(struct mmc_host *host, host->err_stats[stat] += 1; } +static inline int mmc_card_uhs2_hd_mode(struct mmc_host *host) +{ + return host->ios.timing == MMC_TIMING_UHS2_SPEED_A_HD || + host->ios.timing == MMC_TIMING_UHS2_SPEED_B_HD; +} + 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); diff --git a/include/linux/mmc/sd_uhs2.h b/include/linux/mmc/sd_uhs2.h new file mode 100644 index 000000000000..7abe9bd870c7 --- /dev/null +++ b/include/linux/mmc/sd_uhs2.h @@ -0,0 +1,240 @@ +/* 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) + +#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 + +#endif /* LINUX_MMC_UHS2_H */ From patchwork Fri Mar 31 10:55:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77723 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp476754vqo; Fri, 31 Mar 2023 04:05:46 -0700 (PDT) X-Google-Smtp-Source: AKy350aMTluYG+0T8X1TrMQq6E7TMRBSAgcCwGW7eWuUMqgqFXh1uH7GxzW4YxS41JpAUfGD+pWn X-Received: by 2002:a17:903:228f:b0:19d:62b:f040 with SMTP id b15-20020a170903228f00b0019d062bf040mr33923691plh.37.1680260745773; Fri, 31 Mar 2023 04:05:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260745; cv=none; d=google.com; s=arc-20160816; b=n7mYLjMGGww8aGEFa04P2B0rmrzu3vahBe7P+3a69awp5QjvzueNN3oTjaoWwxDmSQ /9gvC7dFqCFxKHOPeI5FHng2ksK0C0G/QXw/KYzQnpdQmTxiV23VfPx+sNVV4agrRLQ9 1Sgqn4BpbTqZ11gIBDZPUO7eA2Y9Q55ktNt0lCxnJ6HnaYBdNEJ82rme8NgUqs/dGZkJ fGgxO37eQzhI46BHObWiMSuKkcACo+U/3J69EeXM4zL7jUJzlfThwnpAwd77vuixAaZY jwhgrEN9Uw+pi6eT/5rcqB4PzbTWDj76idlsR/AfwWTigGjU0Ss+KU6qwHPWl5/E1Q5p Jy9Q== 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=HbiaWE6V/Wv3PAod5FCtStRR4zeo+xmTMbTMF/+vBd4=; b=HWapxYfn9fhDQwoqyNGKr1/dW7Ul0IpVrdMlAVan9s9rU3X0U4GlKzoVQ5GI1qtHJO PN0BuaZF2dKrtiRwQb1PoDsTbK1vD5wD/ylvfjKSf55XABCYrceF4/wfmsMrl+SzYA5R mjFNTFBPDF3hzetom5NmAmH5FiMXv1pPvUeC1Ay0kxoKPu1iq833RtWd7D7qlSMdiX0B fDWkU+y4tQVg+8wv3IvZ5eYBaf9gluPpL5pNpUrlTHyDyaoN8ZC/NOgKoEjRJvA7v/jJ gXPK3Gx3vyHIytNlXc4v+mlbazx9/BdtWcGBheDxg2taJ8Q0xGrGjAZ9O56NalcarDp1 k8Yw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=YSVo8uzr; 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 e4-20020a656884000000b0050fa6fbde45si2038234pgt.504.2023.03.31.04.05.32; Fri, 31 Mar 2023 04:05:45 -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=YSVo8uzr; 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 S230226AbjCaK5V (ORCPT + 99 others); Fri, 31 Mar 2023 06:57:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59956 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231770AbjCaK4m (ORCPT ); Fri, 31 Mar 2023 06:56:42 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD8691D84E; Fri, 31 Mar 2023 03:56:23 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id h12-20020a17090aea8c00b0023d1311fab3so22960557pjz.1; Fri, 31 Mar 2023 03:56:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260183; 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=HbiaWE6V/Wv3PAod5FCtStRR4zeo+xmTMbTMF/+vBd4=; b=YSVo8uzr04Ne60KSKIoa+xVA5afAZzq6PJZD9EysAtyk7bY352BOAGSgx6fdFjwvoJ SV58H3o5juIi7b4SaZwASjxPzLhvIbsc4fxYOFhTzdOsR+aWEGu7B17NP/p47jrh7rff 4uKH+JQeNnaAjEgZyn6TD3SFMlTQT1dc36xfK6NuW/L1A1XeE2pVsDkjnaVZJtOOyEqg Z0/ev7jzj3PAzV8CSC9uftE51zrIWrJEnVez13ospD3rtttnM3E5N1R5IN5Xd/x/HVT6 OakrU+0B3+ezq/syaojsq2UtfFcOisvHKmA/pkjhPO/3SGGV/SzP1IZ+a1IvmSej5KB8 yflA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260183; 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=HbiaWE6V/Wv3PAod5FCtStRR4zeo+xmTMbTMF/+vBd4=; b=S85416Rhn//7t/qBPyueslm85tKdcxNpTAbTRIR36b71nsJqxed43hbYlyWM11CouZ sjZBsTHb1V6FqEJuaOjGVcY41X4gf753es/dH2jYrIiqzMkgIGOTYSRhgjzqZbKfQdw9 XH/FdT98LVOSfamxaF+bYjJ857wg3X4fRAH6CQQ06PkASrofxsmLcoDEhtSvRt2dqyOI vt7ca+52uJCMUW0EOfLYlEXZWE+YPH/BDVtDTiajgEhCfO7qEhINYXqjsIav43Tiw/I6 t9m8MdD8nnQsoCyJPtYZcnr1DXBH560ofuArxKZb1/2jErUPK7OrlqSHiR7ZotkCso7S 9MxA== X-Gm-Message-State: AAQBX9doX6RUBEjr9PvgbmSaFzQSQB7hiv8+XWRxk8vn9QJq6Jj64PpT ee11T0qIHUohPZSKEqTOj5g= X-Received: by 2002:a17:90b:4b8d:b0:239:fd9b:85bd with SMTP id lr13-20020a17090b4b8d00b00239fd9b85bdmr30965660pjb.27.1680260182393; Fri, 31 Mar 2023 03:56:22 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:22 -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 V7 06/23] mmc: core: Support UHS-II card control and access Date: Fri, 31 Mar 2023 18:55:29 +0800 Message-Id: <20230331105546.13607-7-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881091845970544?= X-GMAIL-MSGID: =?utf-8?q?1761881091845970544?= Embed UHS-II access/control functionality into the MMC request processing flow. Signed-off-by: Ulf Hansson Signed-off-by: Jason Lai Signed-off-by: Victor Shih --- drivers/mmc/core/block.c | 18 +- drivers/mmc/core/core.c | 8 + drivers/mmc/core/mmc_ops.c | 25 +- drivers/mmc/core/mmc_ops.h | 1 + drivers/mmc/core/sd.c | 13 +- drivers/mmc/core/sd.h | 4 + drivers/mmc/core/sd_ops.c | 11 + drivers/mmc/core/sd_ops.h | 18 + drivers/mmc/core/sd_uhs2.c | 1138 ++++++++++++++++++++++++++++++++++-- 9 files changed, 1176 insertions(+), 60 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 672ab90c4b2d..ecd3cbd81d5f 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -911,15 +911,9 @@ static int mmc_sd_num_wr_blocks(struct mmc_card *card, u32 *written_blocks) struct scatterlist sg; - cmd.opcode = MMC_APP_CMD; - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, 0); - if (err) - return err; - if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD)) - return -EIO; + err = mmc_app_cmd(card->host, card); + if (err) + return err; memset(&cmd, 0, sizeof(struct mmc_command)); @@ -1605,6 +1599,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->host->flags & MMC_UHS2_SD_TRAN) ? true : false; mmc_blk_data_prep(mq, mqrq, recovery_mode, &do_rel_wr, &do_data_tag); @@ -1615,7 +1612,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. */ @@ -1628,6 +1625,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 ba8808cd9318..f5dc653eafb0 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -334,6 +334,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); @@ -351,6 +353,8 @@ int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) if (err) return err; + mmc_uhs2_card_prepare_cmd(host, mrq, uhs2_cmd, payload); + led_trigger_event(host->led, LED_FULL); __mmc_start_request(host, mrq); @@ -430,6 +434,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; /* @@ -450,6 +456,8 @@ int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq) if (err) goto out_err; + mmc_uhs2_card_prepare_cmd(host, mrq, uhs2_cmd, payload); + 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 3b3adbddf664..8ae205a07f9b 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 72b664ed90cf..2ff9c37a1975 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; @@ -904,7 +904,7 @@ int mmc_sd_get_csd(struct mmc_card *card) return 0; } -static int mmc_sd_get_ro(struct mmc_host *host) +int mmc_sd_get_ro(struct mmc_host *host) { int ro; @@ -1616,11 +1616,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; @@ -1644,7 +1639,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; @@ -1692,7 +1687,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_sd_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..d31259919ee5 100644 --- a/drivers/mmc/core/sd.h +++ b/drivers/mmc/core/sd.h @@ -11,10 +11,14 @@ struct mmc_card; int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr); int mmc_sd_get_csd(struct mmc_card *card); +int mmc_sd_get_ro(struct mmc_host *host); void mmc_decode_cid(struct mmc_card *card); int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, bool reinit); 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..1f9580491ad0 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -27,6 +27,15 @@ 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 (host->flags & MMC_UHS2_SD_TRAN) { + host->uhs2_app_cmd = true; + return 0; + } + cmd.opcode = MMC_APP_CMD; if (card) { @@ -281,6 +290,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 +354,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..8c2da57ca2c2 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,27 @@ 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); + +static inline void mmc_uhs2_card_prepare_cmd(struct mmc_host *host, struct mmc_request *mrq, + struct uhs2_command uhs2_cmd, __be32 payload[4]) +{ + if (host->flags & MMC_UHS2_SD_TRAN) { + uhs2_cmd.payload = payload; + mrq->cmd->uhs2_cmd = &uhs2_cmd; + mmc_uhs2_prepare_cmd(host, mrq); + } +} + +static inline int mmc_sd_can_poweroff_notify(struct mmc_card *card) +{ + return card->ext_power.feature_support & SD_EXT_POWER_OFF_NOTIFY; +} #endif diff --git a/drivers/mmc/core/sd_uhs2.c b/drivers/mmc/core/sd_uhs2.c index 06b2aab52b93..9afbcfda6c0a 100644 --- a/drivers/mmc/core/sd_uhs2.c +++ b/drivers/mmc/core/sd_uhs2.c @@ -1,23 +1,51 @@ // 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 + * + * Copyright (C) 2023 Genesys Logic, Inc. + * Authors: Victor Shih + * * 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 }; +struct sd_uhs2_wait_active_state_data { + struct mmc_host *host; + struct mmc_command *cmd; +}; + static int sd_uhs2_power_up(struct mmc_host *host) { int err; @@ -50,6 +78,43 @@ static int sd_uhs2_power_off(struct mmc_host *host) return host->ops->uhs2_control(host, UHS2_SET_IOS); } +/** ++ * 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; +} + /* * 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 @@ -57,7 +122,15 @@ static int 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; } /* @@ -66,6 +139,82 @@ 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++; + } + return 0; } @@ -76,6 +225,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; } @@ -86,6 +281,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; } @@ -100,26 +470,357 @@ 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); + + /* + * 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) { + 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->ios.timing = MMC_TIMING_UHS2_SPEED_B_HD; + nMinDataGap = 1; + } else { + /* Only support 2L-FD so far */ + host->ios.timing = MMC_TIMING_UHS2_SPEED_B; + nMinDataGap = 3; + } + card->uhs2_config.speed_range_set = UHS2_DEV_CONFIG_PHY_SET_SPEED_B; + } else { + 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->ios.timing = MMC_TIMING_UHS2_SPEED_A_HD; + nMinDataGap = 1; + } else { + /* Only support 2L-FD so far */ + host->ios.timing = MMC_TIMING_UHS2_SPEED_A; + nMinDataGap = 3; + } + card->uhs2_config.speed_range_set = UHS2_DEV_CONFIG_PHY_SET_SPEED_A; + } + + 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; } -/* - * 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) +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_go_dormant_state(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 + }; + + 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 void sd_uhs2_remove(struct mmc_host *host) +{ + mmc_remove_card(host->card); + host->card = NULL; +} + /* * 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; @@ -133,9 +834,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; @@ -148,18 +854,226 @@ static int sd_uhs2_init_card(struct mmc_host *host) if (err) goto err; - host->card = card; + /* If change speed to Range B, need to GO_DORMANT_STATE */ + if (host->ios.timing == MMC_TIMING_UHS2_SPEED_B || + host->ios.timing == MMC_TIMING_UHS2_SPEED_B_HD) { + err = sd_uhs2_go_dormant_state(host, node_id); + if (err) + return err; + } + + host->flags |= MMC_UHS2_SD_TRAN; + return 0; err: - mmc_remove_card(card); + 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; +} + +/* + * 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. + * 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) +{ + int err; + u32 cid[4]; + u32 ocr; + u32 rocr; + u8 *status; + 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"); + goto err; + } + + /* + * Probe SD card working voltage. + */ + err = mmc_send_app_op_cond(host, 0, &ocr); + if (err) + goto 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) + goto err; + + err = mmc_send_cid(host, cid); + if (err) + goto 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) + goto err; + + err = mmc_sd_get_csd(card); + if (err) + goto err; + + /* + * Select card, as all following commands rely on that. + */ + err = mmc_select_card(card); + if (err) + goto err; + + /* + * Fetch SCR from card. + */ + err = mmc_app_send_scr(card); + if (err) + goto err; + + err = mmc_decode_scr(card); + if (err) + goto 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. + */ + status = kmalloc(64, GFP_KERNEL); + if (!status) + return -ENOMEM; + + 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 = mmc_sd_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? + */ + + kfree(status); + + return 0; + +err: + sd_uhs2_remove(host); + return err; } static int sd_uhs2_alive(struct mmc_host *host) @@ -185,34 +1099,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_sd_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_app_cmd) { + arg |= UHS2_SD_CMD_APP; + host->uhs2_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 (mmc_card_uhs2_hd_mode(host)) + 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 = { @@ -223,7 +1279,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, }; @@ -231,6 +1287,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; @@ -239,7 +1297,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; @@ -256,21 +1314,32 @@ static int sd_uhs2_attach(struct mmc_host *host) goto remove_card; mmc_claim_host(host); + 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; @@ -285,6 +1354,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 Fri Mar 31 10:55:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77722 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp471804vqo; Fri, 31 Mar 2023 03:58:34 -0700 (PDT) X-Google-Smtp-Source: AK7set9xZwfqMMXRTTPUDbLABtIJC321oBLN4n/rrrnCfhfjArbpZ1lp+FZtDU9rDN5jOCzMjEfK X-Received: by 2002:a05:6a20:dc:b0:d9:76fa:3502 with SMTP id 28-20020a056a2000dc00b000d976fa3502mr22086058pzh.36.1680260314081; Fri, 31 Mar 2023 03:58:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260314; cv=none; d=google.com; s=arc-20160816; b=pU62o9Mhgsnegf93azuks47pnhEEfqfA1irNHaPzKL7esSideJOgBG/B4J9ij1zaL9 mMR/YZ6f2RQ408nxhUDjU/CVBR4lhSRAfAub7EyNiOLyo5O7sBdY1PX4VES/qBaCYX7W rdmqVgMBreGfjgeY9HQGyH+edczjT1kaE1D9W1ryy86aj3IFj1vIwJIRvx4oGJp3qeWF Nl7mdVi5grOXjSZrwjEXLnrhMeub3arIoELq4KuqZ2qKuwPqfj3/D0InWLklkx//ttnF dV3Of5MaATTVe2dsBg2zYssYjOB5U/3B4IyfilfkycNpxl80nG97qs+myg9DWtmeMHuR lXYA== 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=rRJgGv/WKN6qp6VsAmVW33zFoeLZBxDjjAldRLuUtFQ=; b=0Dt1NOeyknnqh/obdLd++LpPMNexZTe5uHJqAAtuCb5ax8MjnBWZ4cT9JZtm0LNx4f PkJqpK2cf/jUSF20P6E6c2c41qEyX7nv/wrm5t+GhRH4a8422hIl1KQAn7ux3W4cd0RY BbdIaoLUSogyQuBr8IxNd59nmgtRTJsRE4YdNIzxPl3daRAC3YzSsmgI0lEtyNxbJogU jaI8+5vtkuGNZUcDtDt2u0hWVzRTpPM1BNwbzu8YwvcSnsuANfGtQdFnIF/MUPUtS00y vs1Y356CNYfyROmFNArTypqf0WAboD/+uqISVHCLwob5prkn6TLup4C0gQ6Ef3ObNflX QTJw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=elCJbOnd; 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 b7-20020a656687000000b00513b22d821fsi2019671pgw.135.2023.03.31.03.58.20; Fri, 31 Mar 2023 03:58: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=elCJbOnd; 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 S231889AbjCaK51 (ORCPT + 99 others); Fri, 31 Mar 2023 06:57:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230403AbjCaK4o (ORCPT ); Fri, 31 Mar 2023 06:56:44 -0400 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 15BA51D93C; Fri, 31 Mar 2023 03:56:25 -0700 (PDT) Received: by mail-pj1-x1031.google.com with SMTP id lr16-20020a17090b4b9000b0023f187954acso22953398pjb.2; Fri, 31 Mar 2023 03:56:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260185; 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=rRJgGv/WKN6qp6VsAmVW33zFoeLZBxDjjAldRLuUtFQ=; b=elCJbOndKKDBLUCrvaqP4Q4lmZ8cn5JMqp4zdUjUat6MCwoK0BdM/hjuMLVAqPrK8/ 0gqErqoRMQxPaLofQ0ybJnQS/RYpwZ9cTNCRTDpeMNf6fck1OFEAkgdQlTnfZxuYj6z0 ZHG1GE79ODhlafwel4p+OAkfjH3rdn4TJX/X3jMHiFB/mAJGgnVmRl9B/L2qWvi/Gign ol8HBABAOq/ahb78tpV0d9kX9NF1kJt6R199TDwb6CLFYvOq56CrJOzRZwU403YNUQ6j 9GP+Xj00+ubeIEbEA7iicLrD6R7qwMzPFGWdm5sLCuky4ruMwEGijhjfzCHGHe8ta5e3 xriA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260185; 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=rRJgGv/WKN6qp6VsAmVW33zFoeLZBxDjjAldRLuUtFQ=; b=TU25dunTLvYfj/KTCAxonq2WALgImRpH/ns/mtII/X3q8DAL++aiL1fGC2HmY2047B vdVcgioc+NEPRw8WTCGDLjujBbPNW7TIKUMMTqqlGWQg2g6lHe8VU0msl//bdG4Jb4aL EI3GBZkrRJu7XK/dxmv+wz9N3syxzg5FwQA5HnRfcVcpYgEEHkvfnpDGv+9XlRGI8lV8 IOrrfDTha7z6zR2lLrealYcxjInfFyFZlvVMWrXeDCoZgZAGlu5MGYQXlaUC/jJJTMcJ 0CF+vnYGpHRB4+6YAeZwDzJee4E0mIHRi/AByWZPd3oXq/TzueoUKJRp7+rVEwrRtYM7 n+Kg== X-Gm-Message-State: AAQBX9fkwubLMoboLMuPRLJCjNXx4OkD/jnT0YOVCO+QXmOJMk+748/z PnHikPGDneP2AX1QtI/7lMQ= X-Received: by 2002:a17:902:ce92:b0:1a2:1042:cadc with SMTP id f18-20020a170902ce9200b001a21042cadcmr31238192plg.18.1680260184922; Fri, 31 Mar 2023 03:56:24 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56: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 V7 07/23] mmc: sdhci: add UHS-II related definitions in headers Date: Fri, 31 Mar 2023 18:55:30 +0800 Message-Id: <20230331105546.13607-8-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=0.6 required=5.0 tests=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?1761880639037979393?= X-GMAIL-MSGID: =?utf-8?q?1761880639037979393?= 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 | 178 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.h | 62 +++++++++++- 2 files changed, 239 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..c47debb7497e --- /dev/null +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -0,0 +1,178 @@ +/* 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. + * + * Copyright (C) 2014 Intel Corp, All Rights Reserved. + */ +#ifndef __SDHCI_UHS2_H +#define __SDHCI_UHS2_H + +#include + +/* SDHCI Category C registers : UHS2 usage */ + +#define SDHCI_UHS2_CM_TRAN_RESP 0x10 +#define SDHCI_UHS2_SD_TRAN_RESP 0x18 +#define SDHCI_UHS2_SD_TRAN_RESP_1 0x1C + +/* SDHCI Category B registers : UHS2 only */ + +#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_CMD 0x9E +#define SDHCI_UHS2_CMD_SUB_CMD BIT(2) +#define SDHCI_UHS2_CMD_DATA BIT(5) +#define SDHCI_UHS2_CMD_TRNS_ABORT BIT(6) +#define SDHCI_UHS2_CMD_CMD12 BIT(7) +#define SDHCI_UHS2_CMD_DORMANT GENMASK(7, 6) +#define SDHCI_UHS2_CMD_PACK_LEN_MASK GENMASK(12, 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_SEL_MASK GENMASK(3, 0) +#define SDHCI_UHS2_DEV_SEL_INT_MSG_EN BIT(7) + +#define SDHCI_UHS2_DEV_INT_CODE 0xBF + +#define SDHCI_UHS2_SW_RESET 0xC0 +#define SDHCI_UHS2_SW_RESET_FULL BIT(0) +#define SDHCI_UHS2_SW_RESET_SD BIT(1) + +#define SDHCI_UHS2_TIMER_CTRL 0xC2 +#define SDHCI_UHS2_TIMER_CTRL_DEADLOCK_MASK GENMASK(7, 4) + +#define SDHCI_UHS2_INT_STATUS 0xC4 +#define SDHCI_UHS2_INT_STATUS_ENABLE 0xC8 +#define SDHCI_UHS2_INT_SIGNAL_ENABLE 0xCC +#define SDHCI_UHS2_INT_HEADER_ERR BIT(0) +#define SDHCI_UHS2_INT_RES_ERR BIT(1) +#define SDHCI_UHS2_INT_RETRY_EXP BIT(2) +#define SDHCI_UHS2_INT_CRC BIT(3) +#define SDHCI_UHS2_INT_FRAME_ERR BIT(4) +#define SDHCI_UHS2_INT_TID_ERR BIT(5) +#define SDHCI_UHS2_INT_UNRECOVER BIT(7) +#define SDHCI_UHS2_INT_EBUSY_ERR BIT(8) +#define SDHCI_UHS2_INT_ADMA_ERROR BIT(15) +#define SDHCI_UHS2_INT_CMD_TIMEOUT BIT(16) +#define SDHCI_UHS2_INT_DEADLOCK_TIMEOUT BIT(17) +#define SDHCI_UHS2_INT_VENDOR_ERR BIT(27) +#define SDHCI_UHS2_INT_ERROR_MASK ( \ + SDHCI_UHS2_INT_HEADER_ERR | \ + SDHCI_UHS2_INT_RES_ERR | \ + SDHCI_UHS2_INT_RETRY_EXP | \ + SDHCI_UHS2_INT_CRC | \ + SDHCI_UHS2_INT_FRAME_ERR | \ + SDHCI_UHS2_INT_TID_ERR | \ + SDHCI_UHS2_INT_UNRECOVER | \ + SDHCI_UHS2_INT_EBUSY_ERR | \ + SDHCI_UHS2_INT_ADMA_ERROR | \ + SDHCI_UHS2_INT_CMD_TIMEOUT | \ + SDHCI_UHS2_INT_DEADLOCK_TIMEOUT) +#define SDHCI_UHS2_INT_CMD_ERR_MASK ( \ + SDHCI_UHS2_INT_HEADER_ERR | \ + SDHCI_UHS2_INT_RES_ERR | \ + SDHCI_UHS2_INT_FRAME_ERR | \ + SDHCI_UHS2_INT_TID_ERR | \ + SDHCI_UHS2_INT_CMD_TIMEOUT) +/* CRC Error occurs during a packet receiving */ +#define SDHCI_UHS2_INT_DATA_ERR_MASK ( \ + SDHCI_UHS2_INT_RETRY_EXP | \ + SDHCI_UHS2_INT_CRC | \ + SDHCI_UHS2_INT_UNRECOVER | \ + SDHCI_UHS2_INT_EBUSY_ERR | \ + SDHCI_UHS2_INT_ADMA_ERROR | \ + SDHCI_UHS2_INT_DEADLOCK_TIMEOUT) + +#define SDHCI_UHS2_SETTINGS_PTR 0xE0 +#define SDHCI_UHS2_GEN_SETTINGS_POWER_LOW BIT(0) +#define SDHCI_UHS2_GEN_SETTINGS_N_LANES_MASK GENMASK(11, 8) +#define SDHCI_UHS2_FD_OR_2L_HD 0x0 /* 2 lanes */ +#define SDHCI_UHS2_2D1U_FD 0x2 /* 3 lanes, 2 down, 1 up, full duplex */ +#define SDHCI_UHS2_1D2U_FD 0x3 /* 3 lanes, 1 down, 2 up, full duplex */ +#define SDHCI_UHS2_2D2U_FD 0x4 /* 4 lanes, 2 down, 2 up, full duplex */ + +#define SDHCI_UHS2_PHY_SET_SPEED_B BIT(6) +#define SDHCI_UHS2_PHY_HIBERNATE_EN BIT(12) +#define SDHCI_UHS2_PHY_N_LSS_SYN_MASK GENMASK(19, 16) +#define SDHCI_UHS2_PHY_N_LSS_DIR_MASK GENMASK(23, 20) + +#define SDHCI_UHS2_TRAN_N_FCU_MASK GENMASK(15, 8) +#define SDHCI_UHS2_TRAN_RETRY_CNT_MASK GENMASK(17, 16) +#define SDHCI_UHS2_TRAN_1_N_DAT_GAP_MASK GENMASK(7, 0) + +#define SDHCI_UHS2_CAPS_PTR 0xE2 +#define SDHCI_UHS2_CAPS_OFFSET 0 +#define SDHCI_UHS2_CAPS_DAP_MASK GENMASK(3, 0) +#define SDHCI_UHS2_CAPS_GAP_MASK GENMASK(7, 4) +#define SDHCI_UHS2_CAPS_GAP(gap) ((gap) * 360) +#define SDHCI_UHS2_CAPS_LANE_MASK GENMASK(13, 8) +#define SDHCI_UHS2_CAPS_2L_HD_FD 1 +#define SDHCI_UHS2_CAPS_2D1U_FD 2 +#define SDHCI_UHS2_CAPS_1D2U_FD 4 +#define SDHCI_UHS2_CAPS_2D2U_FD 8 +#define SDHCI_UHS2_CAPS_ADDR_64 BIT(14) +#define SDHCI_UHS2_CAPS_BOOT BIT(15) +#define SDHCI_UHS2_CAPS_DEV_TYPE_MASK GENMASK(17, 16) +#define SDHCI_UHS2_CAPS_DEV_TYPE_RMV 0 +#define SDHCI_UHS2_CAPS_DEV_TYPE_EMB 1 +#define SDHCI_UHS2_CAPS_DEV_TYPE_EMB_RMV 2 +#define SDHCI_UHS2_CAPS_NUM_DEV_MASK GENMASK(21, 18) +#define SDHCI_UHS2_CAPS_BUS_TOPO_MASK GENMASK(23, 22) +#define SDHCI_UHS2_CAPS_BUS_TOPO_SHIFT 22 +#define SDHCI_UHS2_CAPS_BUS_TOPO_P2P 0 +#define SDHCI_UHS2_CAPS_BUS_TOPO_RING 1 +#define SDHCI_UHS2_CAPS_BUS_TOPO_HUB 2 +#define SDHCI_UHS2_CAPS_BUS_TOPO_HUB_RING 3 + +#define SDHCI_UHS2_CAPS_PHY_OFFSET 4 +#define SDHCI_UHS2_CAPS_PHY_REV_MASK GENMASK(5, 0) +#define SDHCI_UHS2_CAPS_PHY_RANGE_MASK GENMASK(7, 6) +#define SDHCI_UHS2_CAPS_PHY_RANGE_A 0 +#define SDHCI_UHS2_CAPS_PHY_RANGE_B 1 +#define SDHCI_UHS2_CAPS_PHY_N_LSS_SYN_MASK GENMASK(19, 16) +#define SDHCI_UHS2_CAPS_PHY_N_LSS_DIR_MASK GENMASK(23, 20) +#define SDHCI_UHS2_CAPS_TRAN_OFFSET 8 +#define SDHCI_UHS2_CAPS_TRAN_LINK_REV_MASK GENMASK(5, 0) +#define SDHCI_UHS2_CAPS_TRAN_N_FCU_MASK GENMASK(15, 8) +#define SDHCI_UHS2_CAPS_TRAN_HOST_TYPE_MASK GENMASK(18, 16) +#define SDHCI_UHS2_CAPS_TRAN_BLK_LEN_MASK GENMASK(31, 20) + +#define SDHCI_UHS2_CAPS_TRAN_1_OFFSET 12 +#define SDHCI_UHS2_CAPS_TRAN_1_N_DATA_GAP_MASK GENMASK(7, 0) + +#define SDHCI_UHS2_EMBED_CTRL_PTR 0xE6 +#define SDHCI_UHS2_VENDOR_PTR 0xE8 + +#endif /* __SDHCI_UHS2_H */ diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index f4f2085c274c..2c7ab4453248 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -43,8 +43,23 @@ #define SDHCI_TRNS_READ 0x10 #define SDHCI_TRNS_MULTI 0x20 +/* + * Defined in Host Version 4.0. + */ +#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. + * For example with SDIO, CMD52 (sub command) issued during CMD53 (main command). + */ +#define SDHCI_CMD_SUB_CMD 0x04 + #define SDHCI_CMD_CRC 0x08 #define SDHCI_CMD_INDEX 0x10 #define SDHCI_CMD_DATA 0x20 @@ -65,6 +80,9 @@ #define SDHCI_PRESENT_STATE 0x24 #define SDHCI_CMD_INHIBIT 0x00000001 #define SDHCI_DATA_INHIBIT 0x00000002 + +#define SDHCI_DAT_4_TO_7_LVL_MASK 0x000000F0 + #define SDHCI_DOING_WRITE 0x00000100 #define SDHCI_DOING_READ 0x00000200 #define SDHCI_SPACE_AVAILABLE 0x00000400 @@ -80,6 +98,15 @@ #define SDHCI_DATA_0_LVL_MASK 0x00100000 #define SDHCI_CMD_LVL 0x01000000 +/* Host Version 4.10 */ + +#define SDHCI_HOST_REGULATOR_STABLE 0x02000000 +#define SDHCI_CMD_NOT_ISSUED_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 +127,14 @@ #define SDHCI_POWER_300 0x0C #define SDHCI_POWER_330 0x0E +/* + * VDD2 - UHS2 + * VDD2 power on/off and voltage select (UHS2) + */ +#define SDHCI_VDD2_POWER_ON 0x10 +#define SDHCI_VDD2_POWER_120 0x80 +#define SDHCI_VDD2_POWER_180 0xA0 + #define SDHCI_BLOCK_GAP_CONTROL 0x2A #define SDHCI_WAKE_UP_CONTROL 0x2B @@ -110,7 +145,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 +174,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 +191,9 @@ #define SDHCI_INT_AUTO_CMD_ERR 0x01000000 #define SDHCI_INT_ADMA_ERROR 0x02000000 +/* Host Version 4.0 */ +#define SDHCI_INT_RESP_ERR 0x08000000 + #define SDHCI_INT_NORMAL_MASK 0x00007FFF #define SDHCI_INT_ERROR_MASK 0xFFFF8000 @@ -178,6 +220,9 @@ #define SDHCI_AUTO_CMD_END_BIT 0x00000008 #define SDHCI_AUTO_CMD_INDEX 0x00000010 +/* Host Version 4.10 */ +#define SDHCI_AUTO_CMD_RESP_ERR 0x0020 + #define SDHCI_HOST_CONTROL2 0x3E #define SDHCI_CTRL_UHS_MASK 0x0007 #define SDHCI_CTRL_UHS_SDR12 0x0000 @@ -186,6 +231,7 @@ #define SDHCI_CTRL_UHS_SDR104 0x0003 #define SDHCI_CTRL_UHS_DDR50 0x0004 #define SDHCI_CTRL_HS400 0x0005 /* Non-standard */ +#define SDHCI_CTRL_UHS2 0x0007 #define SDHCI_CTRL_VDD_180 0x0008 #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 #define SDHCI_CTRL_DRV_TYPE_B 0x0000 @@ -194,9 +240,12 @@ #define SDHCI_CTRL_DRV_TYPE_D 0x0030 #define SDHCI_CTRL_EXEC_TUNING 0x0040 #define SDHCI_CTRL_TUNED_CLK 0x0080 +#define SDHCI_CTRL_UHS2_ENABLE 0x0100 +#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_ENABLE 0x4000 #define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 #define SDHCI_CAPABILITIES 0x40 @@ -219,11 +268,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 #define SDHCI_DRIVER_TYPE_A 0x00000010 #define SDHCI_DRIVER_TYPE_C 0x00000020 #define SDHCI_DRIVER_TYPE_D 0x00000040 @@ -232,6 +283,7 @@ #define SDHCI_RETUNING_MODE_MASK GENMASK(15, 14) #define SDHCI_CLOCK_MUL_MASK GENMASK(23, 16) #define SDHCI_CAN_DO_ADMA3 0x08000000 +#define SDHCI_CAN_VDD2_180 0x10000000 /* UHS-2 1.8V VDD2 */ #define SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */ #define SDHCI_MAX_CURRENT 0x48 @@ -239,11 +291,14 @@ #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_1 0x4C +#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_INT_ERROR 0x52 #define SDHCI_ADMA_ERROR 0x54 @@ -262,10 +317,15 @@ #define SDHCI_PRESET_FOR_SDR104 0x6C #define SDHCI_PRESET_FOR_DDR50 0x6E #define SDHCI_PRESET_FOR_HS400 0x74 /* Non-standard */ + +/* 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 From patchwork Fri Mar 31 10:55:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77735 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp478880vqo; Fri, 31 Mar 2023 04:09:20 -0700 (PDT) X-Google-Smtp-Source: AKy350aMKsYEwtd6gl58F18nFSYCMv7M/1NNy49/k1GIJzcz9aMO7bqQMANemCbCE+UPCWD3FNAE X-Received: by 2002:a17:903:244f:b0:19f:3b86:4710 with SMTP id l15-20020a170903244f00b0019f3b864710mr33589880pls.49.1680260960407; Fri, 31 Mar 2023 04:09:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260960; cv=none; d=google.com; s=arc-20160816; b=FcQS85kRqsJiIUw2IcJXdw340Y8g3unArtawUbGqb94AB8C1h+m7NREDeKhri6+Zwv c4O3MlCnAX3opDBwPP8a7l4gb8k3Dd1DMDgI1lBTxArh8XKr8/hTjAH6DRefkVz46FwT RmDh6+UgnvtnfhefooQwCl4kkBBrGBSwEF/9B3d5NKaXSo/WbeXmRG+gZKBn0/PaZCIj st6Gfv3z+CDonDdAaNNqUsfSfTprwKe6EOFh4L0ZMUx8O0eTj9J6oBeMaLeBCn4cvYSj c9EcEdF84V5NugFDptflUiC9ixDY8FIHrXNb4kqwJiWqEI7fcqirumxRmOg2gsqeWBqL sXpw== 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=T8o3QnZZe0BwtsQOwaSyBuN6haWTDyey9fLQnDZwlMg=; b=Xs9UOvl7K5BVrFAL4DYLItIw2bwpWRSduWfZGC6SIAracHNLZOSt5Qdhg17kJ9Be2N r2J2mIOKTdvvQtbRy364G6lye5TL0aiHWXZfq7W4Yfjk8JKIA7OM8r2zA7XRH3wdB6de 73WzMzLr1oMG/rkXUaosXZT7INp0d/nU0h96ZSZEQpMXu2w56XUiY4mwYwL5jmP9BjoE 40Erqy7BVb/VU13xHhnbeXUf5JFDKkAsXOXlQ7nlY6s7L94BIrV7jq3m73mpElbzQrlw FXuskohol3CeF10HxukJnuhZFrAw0ymIlynYqWslH1yZacIVZEBmO6s6/RFxVqOgQogV 86pA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="M/QFjr7Z"; 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 u6-20020a170902e5c600b001a23cfb3517si1904621plf.359.2023.03.31.04.09.07; Fri, 31 Mar 2023 04:09:20 -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="M/QFjr7Z"; 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 S231904AbjCaK5d (ORCPT + 99 others); Fri, 31 Mar 2023 06:57:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231538AbjCaK4r (ORCPT ); Fri, 31 Mar 2023 06:56:47 -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 149A31EA1F; Fri, 31 Mar 2023 03:56:27 -0700 (PDT) Received: by mail-pj1-x102a.google.com with SMTP id mp3-20020a17090b190300b0023fcc8ce113so24960547pjb.4; Fri, 31 Mar 2023 03:56:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260187; 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=T8o3QnZZe0BwtsQOwaSyBuN6haWTDyey9fLQnDZwlMg=; b=M/QFjr7Zm2tc+5MCHdgnzK5JGqwd+tL4k1dOieeOdUeDAw9Da+YbFkP6xtUJ0eyhMe FHfyoj0bFkZaSeAUSaaeep2nFFSmW6ys5sIAZeZDI5G9U7LUpLSD2wxK0eJgcdyaWIoT q2eETYoIu6ZQhi8R9lV5Y3KQuXTLRhf9JAMkX9obYEone01CPe7AQGstvUJLnHgk0/YN 551OJouEdv2pIcoK/pmVDah8CKP7x6xconRwHC8O0uWbMKpDJetaSABGqOIHrjnKAjZH wNI7IUgNip/JhciohKf1X2Hu0oWBNG/3iHTGMzA/B5fKHmtDsUet9EHpalDGGpAZASVR n/mQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260187; 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=T8o3QnZZe0BwtsQOwaSyBuN6haWTDyey9fLQnDZwlMg=; b=daEHuwm22moxUDYVbcOPEi0whHowm9bsi13DoGaBB//4D3tM29vrSQQu4XbxuiE53l NSAD8oenrKSNYtgpI0OgBGNGfAISva5IG2Ipjb7fKvGvy/ANyC8y/FUmaEYpylFZvUOY lD4aT1FLwhgySHSvkxaD36viv4Aa/+TVgzbQWte3MOkVKUhGNx01wpDWsp/WaZwJz5RZ 8cQg8sfU9cJjFEd+uJSmRPUPxHlWbJkAi6IJIXxT+AI7S4R4lBmlMlgQLJxtWhCbzTod 3xsJwYAzJBIrQbVDJvFOleflU2TvPDnyFaELTwOW9SJvHIVILkVxKqvR+kVkK8CaxUUQ ZuRg== X-Gm-Message-State: AAQBX9fUYsX3ZNr6yAvYUyrVEbqySuhgZmaezKa6k9ueRz1hR3X7IID4 qlamwXkT9jEo/irnZn+Uoyw= X-Received: by 2002:a17:903:787:b0:1a1:b5ce:5d03 with SMTP id kn7-20020a170903078700b001a1b5ce5d03mr20502102plb.10.1680260187419; Fri, 31 Mar 2023 03:56:27 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:27 -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 V7 08/23] mmc: sdhci: add UHS-II module and add a kernel configuration Date: Fri, 31 Mar 2023 18:55:31 +0800 Message-Id: <20230331105546.13607-9-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881316965144932?= X-GMAIL-MSGID: =?utf-8?q?1761881316965144932?= This patch adds sdhci-uhs2.c as a module for UHS-II support. This is a skelton for further development in this patch series. 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 Signed-off-by: Victor Shih --- drivers/mmc/host/Kconfig | 9 +++++++ drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-uhs2.c | 46 +++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 drivers/mmc/host/sdhci-uhs2.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 4745fe217ade..06ab111eba3b 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -98,6 +98,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 diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index a693fa3d3f1c..799f21d1f81f 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..8e15bd0dadee --- /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_mod_exit(void) +{ +} +module_exit(sdhci_uhs2_mod_exit); + +MODULE_AUTHOR("Intel, Genesys Logic, Linaro"); +MODULE_DESCRIPTION("MMC UHS-II Support"); +MODULE_LICENSE("GPL v2"); From patchwork Fri Mar 31 10:55:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77728 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp477248vqo; Fri, 31 Mar 2023 04:06:36 -0700 (PDT) X-Google-Smtp-Source: AKy350adLU558DBYv8Qrtr0v5AZiSubQ0bzMntIKogQ2sATjUhqkJQWdJjTUOESCjUAJmuf642nT X-Received: by 2002:a17:903:7cc:b0:1a1:97b5:c63e with SMTP id ko12-20020a17090307cc00b001a197b5c63emr25786082plb.38.1680260795939; Fri, 31 Mar 2023 04:06:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260795; cv=none; d=google.com; s=arc-20160816; b=QJwnJP+N3ttpDMQ4hRVGZ+qbTgj3Kx6snQi5nXHy/7fKNmiD3OK6cTQfJrlL8SdzrF L4ZktJBJRijsPTN9sljRxwfGxVdXjtoAVw/GCyncCGVOZvyCy2uKWZWaIpusZJkermtG widXNCy21LeyK2a6fmZqKD502TLeXqu0TufU4RP9MsIbcDeu31Z36WPE5jT+P8zJP/X5 TWwNPQbfHxE/ZSrxkplaQOHV3gcOafh5/IbNwveABNd09v7NW1JgWItpDYiq5hoDfyMy oESXjg2p9XF/76LNMhxOM+GLZ7TdBACrZk6NsabJ8nQoAKSjoiWiF/UDo4qsqBsT7HgI AsjQ== 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=/woB6K4XFTtpMN98j7WdlX6OjSE0xBfoMVdNx6lVGwc=; b=lBC72zYSSbY7PQYnBoflag0qTZDmecIP9sYvYEGg1DsUqRZ9TWc47/5UwvdsK8Mioa 0aPwBcOwQQNT7VMrnARCr0dYsaQmMqha3Ct0c8f2pFf/Vmrw8JLH7BVnl7OFoZtSNg2t HKU0BYEzxFon8dMez/R56LFDZ80brBPfJKkbT9NbcodEy8SjucbLdEIN3Zlx/z5oAiEc 0zzQnL9Akx7HasOeQMlCAZany7jmIJzMN2d9j5tRrDmQTQaTwMddMIyFoSGnY/+i7Cwt +txEP3vf9YGP0lPhpfHjJw+JTBsS043TjX1tOli2IXaOGCy5eDBW97oy4Z6ce8sTHf89 rwgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=Wv8MCAJZ; 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 n16-20020a170902d2d000b0019a95ab6b4esi2093821plc.407.2023.03.31.04.06.24; Fri, 31 Mar 2023 04:06:35 -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=Wv8MCAJZ; 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 S231806AbjCaK5r (ORCPT + 99 others); Fri, 31 Mar 2023 06:57:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231751AbjCaK4s (ORCPT ); Fri, 31 Mar 2023 06:56:48 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E03901D878; Fri, 31 Mar 2023 03:56:30 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id gp15-20020a17090adf0f00b0023d1bbd9f9eso25022544pjb.0; Fri, 31 Mar 2023 03:56:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260190; 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=/woB6K4XFTtpMN98j7WdlX6OjSE0xBfoMVdNx6lVGwc=; b=Wv8MCAJZnkMPDeuI707fO8JWnKgpUVgaxCXvIJvFbsnwT9G6JmsL/rFXRWL4gNRRcV HLEnt6/6j+iCBgZIZf22DLVdJj7rCKrocNMmlzA2jMWMSq+C5soUToy1LWtsPJanU5gy UIzFy+yPuC41zGpCJot+a3se+2+KEm23Td+pHMDTlihNyJ9qvs8Lr9y4kqE7le37brn2 zSWEYxH+ycm936YR/ezTuikkvERRbok0/HMRuT/t2KX1NWw95zmkxXpFJnnP+1nA9rAW RWkRbLJlR552WcJQ0e2pYv5FzTTmCguKL0ufKdyP7Hrn34t+hJ6J9ln47E502BLz7ifj Xlbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260190; 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=/woB6K4XFTtpMN98j7WdlX6OjSE0xBfoMVdNx6lVGwc=; b=qQ5bcfDjWUjcHVQzcmh+QXFFr98eelF1gUFBHqrNs1cUk1BbHkNyFyuvar4Do2CXR2 8YMupli7/jCXPntyDCZvCtSPMH0Ymx/M1pt4hxFft3VGFEPKetXFMQtCaIS6zOP8b58d Sc8K90bt96VeQRVi9PDfM9MwJl0hf6ZogPOmvCLd7KSJoqSX5ZKfFLi/OncxLQmYaHOR 8tae6ynLWPWrmsPBGBf9X5ekVA65HB2lAhJggr2hTmFevrGpYotFM8xt/mCKwvwk6bdB CepX4PZWhSzjSSeDIwYkt8vsLu7d/HWViF9YAWVQBhSnAAsWpEgfND+Zyqu8amladTG4 DSOA== X-Gm-Message-State: AAQBX9fKTFhpW4fkOtUDBqaBHaWWsaTpbSl6fGJx+Ck/5dHf5oR9P+uc jUtVO1Kgu619IqRG/Xt6tTk= X-Received: by 2002:a17:902:e485:b0:1a1:cce7:94ed with SMTP id i5-20020a170902e48500b001a1cce794edmr20055154ple.67.1680260190120; Fri, 31 Mar 2023 03:56:30 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:29 -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 V7 09/23] mmc: sdhci-uhs2: dump UHS-II registers Date: Fri, 31 Mar 2023 18:55:32 +0800 Message-Id: <20230331105546.13607-10-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881144778599895?= X-GMAIL-MSGID: =?utf-8?q?1761881144778599895?= Dump UHS-II specific registers, if available, in sdhci_dumpregs() for informative/debugging use. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 30 ++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 4 ++++ drivers/mmc/host/sdhci.c | 3 +++ drivers/mmc/host/sdhci.h | 1 + 4 files changed, 38 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 8e15bd0dadee..524d7cb6f2fd 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 (!(sdhci_uhs2_mode(host))) + 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_CMD), + 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_INT_STATUS), + sdhci_readl(host, SDHCI_UHS2_INT_STATUS_ENABLE)); + SDHCI_UHS2_DUMP("ErrSigEn: 0x%08x\n", + sdhci_readl(host, SDHCI_UHS2_INT_SIGNAL_ENABLE)); +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); /*****************************************************************************\ * * diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index c47debb7497e..e948119348da 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -175,4 +175,8 @@ #define SDHCI_UHS2_EMBED_CTRL_PTR 0xE6 #define SDHCI_UHS2_VENDOR_PTR 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 3241916141d7..e79e1b5d5cd4 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); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 2c7ab4453248..5dffa334d3fc 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -721,6 +721,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 Fri Mar 31 10:55:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77739 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479263vqo; Fri, 31 Mar 2023 04:09:59 -0700 (PDT) X-Google-Smtp-Source: AK7set8iWuMnVOoDyjYjXSPI5n2hiAA8SrlijaVp7TE9nfk8WNWEU1NCGB6ViU8dsBt7Hqe/LeAK X-Received: by 2002:a05:6a20:8c01:b0:d6:df31:8ac2 with SMTP id j1-20020a056a208c0100b000d6df318ac2mr24661590pzh.42.1680260998728; Fri, 31 Mar 2023 04:09:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260998; cv=none; d=google.com; s=arc-20160816; b=nrcR1FL8+gajDVBd2JFwImvaAaoRHD7Oys/m/8VpjzcZFGBH1UWV3ARFdPe0gTRu+4 UrVLoJUqzCsf2xZrJFACYN7HiZsrNcp4MkosNh2hYI3ww9CxVkcyKeRcsEutWkPTljlQ O6hI62AurUB7eRm9oLHlnZwrzk34FUi/AojcEBAfeaL6UR9aVfg6RNasZv9SFN/+jRtr DFoD6HUWvAwBRuM6wRmrCfxHjwNlXKibL2MOg8Pkgc3WyckEzEw4pyzGgJhcROAY5scP XFT93fGnBFOon5TqKvRNVqLD0mc+t1OvhoW9HVj0VHdqZvcgupkCYGvdvO7OrOqxnSnu OIgw== 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=jCMev1nbO+uuzvPQJsJ7FQNJs6v52W+KGPPzbe65Jwo=; b=KFuGRqoyM/pf4NFZrSCmnBcWXsLyg52xYH19O9mIUFLPs+phqOnpV1KHlx9ASrBFkl jG9rSPr+j9KWKI5Zodae4kINYPgiKiT+Aa16qwUq2+k542Wg3Yk/rjpDvyNssg+p2uMk LaWTpeZ9RaVakafeQfkhYLyOYtyW9mukXwaBfNNPfRXfM8jFrXuXh6Qu8KdC8uN4kq/v 611VKzS5IImPlVeODJ8M0tlG67Vmu6Yjr30L18MyLkdgUbnKGJ6fD+6M+QwJv2VcOEjX tYAc/eCpybnR/j8uGS6dvAXKtiU9apHRscukrpH6JNYOsp6S+yPL4wRLmdA7c20GgHTx 2S0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="Y/fPM0PQ"; 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 r29-20020aa7963d000000b005a8ac97d6cdsi2169713pfg.344.2023.03.31.04.09.46; Fri, 31 Mar 2023 04:09:58 -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="Y/fPM0PQ"; 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 S231812AbjCaK5w (ORCPT + 99 others); Fri, 31 Mar 2023 06:57:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60168 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230254AbjCaK4s (ORCPT ); Fri, 31 Mar 2023 06:56:48 -0400 Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 219D71D923; Fri, 31 Mar 2023 03:56:33 -0700 (PDT) Received: by mail-pl1-x630.google.com with SMTP id ja10so20872333plb.5; Fri, 31 Mar 2023 03:56:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260192; 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=jCMev1nbO+uuzvPQJsJ7FQNJs6v52W+KGPPzbe65Jwo=; b=Y/fPM0PQSUaFh/SZthdDFBwWRhhuk20FQcvG3ObHvEcEL9fXxMhG/c1Sjvbv/bYkFe Cf8RXvgLgISrqy7s6GNT3ekziSFs4mX9AJWorYMk/qhKAFJNiffUlBvagOIECI3cZmJG 3lvuHWoAESxZiTFuBROpTPgG9qoJ2/fuNyPpRPHUq7q9B3PDfPdLukdjNPoLP6mYIMJt oHC6i+QRkPTG6+bHoKt5UeFVC+Ah7WCLc1WzefMheyHwVqMN/FvCv2rt+xRzaDZOGrJq BdJnLdJEY3cX3VzPymZc0PKbV3Fm6gP87G5RVQuvIb0Unntj83ov9+AJ/VC0oZH8Wesl Cl2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260192; 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=jCMev1nbO+uuzvPQJsJ7FQNJs6v52W+KGPPzbe65Jwo=; b=Ec222QqlOIyHKkd0pGKAiijr2CVfO6+cnyUGwzsonI9j59MJvGqchpa7VQ91oSYR25 1w2n4DwMn13edrCATKaMk+8eIFn3aIeP/rE6juwyhy0DPk4x7ssJ40htzPpnCk8H876N zF2w8aG1QZmc8BP+yoIAgLzKnJzADYpSFjISd5rjFuSNpOYo1eK928ofdweWf99e3pvx tdmLeONg3+48GwGYB9XTrRmNcQfcnAZhHZyWWaJsR5OGzOIOl8ZSCwLL9Kc9n5nqpLFB WzNb+P0sfb3xmAYW2g0f/8aOzYIIx88sQcsYTHV4ZNYTcOHcRSOw+IcCom+fpRZLSq0e kZVg== X-Gm-Message-State: AAQBX9d04zsQjpropepcS5WRpIJ5yzCRJzaYf1y/EU7Ml+vZ867R6pZj D4vv/shZ1XtEkFMEt7bC/ms= X-Received: by 2002:a17:90a:35d:b0:237:9a13:5841 with SMTP id 29-20020a17090a035d00b002379a135841mr29400619pjf.3.1680260192611; Fri, 31 Mar 2023 03:56:32 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:32 -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 V7 10/23] mmc: sdhci-uhs2: add reset function and uhs2_mode function Date: Fri, 31 Mar 2023 18:55:33 +0800 Message-Id: <20230331105546.13607-11-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881357460925904?= X-GMAIL-MSGID: =?utf-8?q?1761881357460925904?= 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-uhs2.c | 46 +++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 524d7cb6f2fd..67621eaabafc 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -10,7 +10,9 @@ * Author: AKASHI Takahiro */ +#include #include +#include #include "sdhci.h" #include "sdhci-uhs2.h" @@ -49,6 +51,50 @@ void sdhci_uhs2_dump_regs(struct sdhci_host *host) } EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); +/*****************************************************************************\ + * * + * Low level functions * + * * +\*****************************************************************************/ + +bool sdhci_uhs2_mode(struct sdhci_host *host) +{ + return host->mmc->flags & MMC_UHS2_SUPPORT; +} + +/** + * sdhci_uhs2_reset - invoke SW reset + * @host: SDHCI host + * @mask: Control mask + * + * Invoke SW reset, depending on a bit in @mask and wait for completion. + */ +void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask) +{ + unsigned long timeout; + u32 val; + + sdhci_writew(host, mask, SDHCI_UHS2_SW_RESET); + + if (mask & SDHCI_UHS2_SW_RESET_FULL) + host->clock = 0; + + /* Wait max 100 ms */ + timeout = 100000; + + /* hw clears the bit when it's done */ + if (read_poll_timeout_atomic(sdhci_readw, val, !(val & mask), 10, + timeout, true, host, SDHCI_UHS2_SW_RESET)) { + pr_err("%s: %s: Reset 0x%x never completed.\n", + __func__, mmc_hostname(host->mmc), (int)mask); + pr_err("%s: clean reset bit\n", + mmc_hostname(host->mmc)); + sdhci_writeb(host, 0, SDHCI_UHS2_SW_RESET); + return; + } +} +EXPORT_SYMBOL_GPL(sdhci_uhs2_reset); + /*****************************************************************************\ * * * Driver init/exit * diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index e948119348da..6834893eee85 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -178,5 +178,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 */ From patchwork Fri Mar 31 10:55:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77724 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp476841vqo; Fri, 31 Mar 2023 04:05:55 -0700 (PDT) X-Google-Smtp-Source: AK7set8RlooXVNKMBIKLmzxMDW22e6veK2f7fSy4N7dsX+sOAP8J43PtILO0QnfyHNX1zxEBZQt0 X-Received: by 2002:a05:6a20:3402:b0:dd:df53:4351 with SMTP id i2-20020a056a20340200b000dddf534351mr20723455pzd.40.1680260755345; Fri, 31 Mar 2023 04:05:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260755; cv=none; d=google.com; s=arc-20160816; b=Dewco3/Qsr/8bFRvwxZhitFafEkSrKfSwNHxdzds1BIFM4cpQiRTQMwCZgvStZa4p0 9OjhV1ZG8/99ArfwRAsRKFxCkH3khh5r92NGAhKY0z6ey4bU/nVqIqv01aL+IIuzN226 WxFN16hgnlZ+9fHg03aN2lYWoPaB2hKYeqxDxvQFH4GHV4gBs38wxP2kFs8NKptdFIGE OdKcxidK/i7ssuwY/8csKoXo2In+MrJ3T+LwsmDEzd1nmcYU3mpDfQ/9H6czYqLlND2W 2X21f+fcS8Ox3ERF1z3fduoXUamgMn6JWzqO7W62s7wLe3JlJcko2WAnVGN7qAl41Gtv 806w== 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=0Iovf4syaqrV5QF9RpdQC8yFp3zM2t9jD65R/OIUlEE=; b=mJvW0Z9RZbEHwpm0hD36dglX7OFLT09/ymeiZIEhT7ZUAC8ERSE06C3PFoffYp4gaP ai6K+NYzYQr3bQRHe2xY0JkHAgp1uC9h8+Tex8xmMLBA08nQEyeS8znLQukngUbLhKJh 8nO6xDBFhJy4khBTu8XuPYEBESkSAp20YybxQRtIOi+rMjYo/dJDtkumCWWJAJBdP/So eeJeSQ6ZNgyKUOjavxnCH1jkP8oFyV9oEuJFUABISOGYBEsz6j2IF2mzcX1BPDgqIpvu EBF3EAG3MZlOCNOIfS3NMyT8Clhtz4LU3CL1QREvPljymWISdf2qD9eqC50yC+M6C34l YpJQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=IGR2QqPh; 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 h18-20020aa79f52000000b005a8b856ad47si2213258pfr.7.2023.03.31.04.05.42; Fri, 31 Mar 2023 04:05:55 -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=IGR2QqPh; 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 S231948AbjCaK54 (ORCPT + 99 others); Fri, 31 Mar 2023 06:57:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231801AbjCaK4u (ORCPT ); Fri, 31 Mar 2023 06:56:50 -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 C0B851DF97; Fri, 31 Mar 2023 03:56:35 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id f22so16746597plr.0; Fri, 31 Mar 2023 03:56:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260195; 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=0Iovf4syaqrV5QF9RpdQC8yFp3zM2t9jD65R/OIUlEE=; b=IGR2QqPhO3v3CqqC7Dj91QDOQjaTsziUerRzLnW1G9f9RASHKLEtP4dKPaXhe0V4Fa nNH2zuOTd8ATQMEr/WCCEZmHoNlaCzCbtAjAuMqOphdJvKt5xRlBASvKZvRvwdAT4+4Z UexP/Hsyo78fp+8BSkp+sX/g+XzhXdtn9UaoZCfwEKQBKkWd9nfLUqXNxWxHQJnOGEKO 8akIjkpBYrF9m3VYZJ3AEgCFG9EpnS9LfbUOkSt8UrXsiRIJaElel81RxKjK6e2w+zCQ y9eZy3OHwgJm97dEz9d/IMuut8mrJaqqqJXw+LNP0kPtcS/sJfp8kfUklhCVTl7Z1KAP HTKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260195; 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=0Iovf4syaqrV5QF9RpdQC8yFp3zM2t9jD65R/OIUlEE=; b=D/oOKigWTMTVBNQblB47d4aY4Aum0njTqXBrctib144/lLk1MsDDMzhHaZBo67d8dK 0AfT3kKY5L5O6Yww5+HO7jZe0roQ2JCF8Se40Zn8CkVD12QKpQ8sAgeqVkGLXqzToozF pxwAGiLjCtvBrq66VZgh90UTmXX11lRNESx7EgtDSi56VpVFfJQ3GWvOzeNyWo3DYyiW Mum/tp/kClC1RGyI+vq1voiX+nvIYG14j9ZCW8DBWCtWYY6Aur+s2CkCnGbYoCf8UoAJ Ho4QzcQVWjmatA+2w+e+U7fsLcKc9JC7n2ssy17ZpSFe1rH1hNRwZoQTMITYZ3mda6vj 1CGw== X-Gm-Message-State: AAQBX9fbkWQARyho/5PRFyf+iYfdS8b05r987Ay2MF08201DTIrc0PVg VlJySKXmUJXcZllfOWRPm2nAPlHneFY= X-Received: by 2002:a17:902:f54c:b0:1a1:b238:d1ab with SMTP id h12-20020a170902f54c00b001a1b238d1abmr28269878plf.69.1680260195453; Fri, 31 Mar 2023 03:56:35 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:35 -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 V7 11/23] mmc: sdhci-uhs2: add set_power() to support vdd2 Date: Fri, 31 Mar 2023 18:55:34 +0800 Message-Id: <20230331105546.13607-12-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881101570064176?= X-GMAIL-MSGID: =?utf-8?q?1761881101570064176?= 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 | 49 ++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c | 61 +++++++++++++++++++---------------- drivers/mmc/host/sdhci.h | 1 + 3 files changed, 83 insertions(+), 28 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 67621eaabafc..3f232f4e0820 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -57,6 +57,13 @@ EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); * * \*****************************************************************************/ +static inline int mmc_opt_regulator_set_ocr(struct mmc_host *mmc, + struct regulator *supply, + unsigned short vdd_bit) +{ + return IS_ERR_OR_NULL(supply) ? 0 : mmc_regulator_set_ocr(mmc, supply, vdd_bit); +} + bool sdhci_uhs2_mode(struct sdhci_host *host) { return host->mmc->flags & MMC_UHS2_SUPPORT; @@ -95,6 +102,48 @@ void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask) } EXPORT_SYMBOL_GPL(sdhci_uhs2_reset); +static void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, + unsigned short vdd) +{ + struct mmc_host *mmc = host->mmc; + u8 pwr; + + 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); + + mmc_opt_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + mmc_opt_regulator_set_ocr(mmc, mmc->supply.vmmc2, 0); + } else { + mmc_opt_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); + /* support 1.8v only for now */ + mmc_opt_regulator_set_ocr(mmc, mmc->supply.vmmc2, fls(MMC_VDD_165_195) - 1); + + /* Clear the power reg before setting a new value */ + sdhci_writeb(host, 0, 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); + } +} + /*****************************************************************************\ * * * Driver init/exit * diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e79e1b5d5cd4..a68a2dce0efe 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -23,7 +23,7 @@ #include #include #include - +#include #include #include @@ -2061,41 +2061,46 @@ 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) +{ + 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: + return SDHCI_POWER_180; + case MMC_VDD_29_30: + case MMC_VDD_30_31: + return SDHCI_POWER_300; + case MMC_VDD_32_33: + case MMC_VDD_33_34: + /* + * 3.4V ~ 3.6V are valid only for those platforms where it's + * known that the voltage reange is supported by hardware. + */ + case MMC_VDD_34_35: + case MMC_VDD_35_36: + return SDHCI_POWER_330; + default: + return 0; + } +} +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 5dffa334d3fc..02ea4a00ad63 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -838,6 +838,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 Fri Mar 31 10:55:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77738 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479265vqo; Fri, 31 Mar 2023 04:09:59 -0700 (PDT) X-Google-Smtp-Source: AKy350aI4fQNQoDncoAKany7YYTcCunFYIv6YUrbPBb40YrCNmB0tWUH6foti4NywkBqIx3m4nnP X-Received: by 2002:a17:903:2289:b0:1a1:a5ac:29ba with SMTP id b9-20020a170903228900b001a1a5ac29bamr34677672plh.1.1680260998898; Fri, 31 Mar 2023 04:09:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260998; cv=none; d=google.com; s=arc-20160816; b=KeVBJ3YlCc5Kb3+zpARNiJokix0HsSBZeac0qLKSu2C5/7u3W0w2p8UmKF0rLsVyf9 suY4MKWNh/jlcybS+wOoTkDUhdY+8cS7POhlgB+C0aF61QrATt3V3LJ3H045xXD5Cx9j FQeluXInrEgrALhpWtetgBPpB/sH9wXkqH0tRxVs5swOZn/KPKvxtxDVnSA/Y9S1kxVL pyr0eu50NBSANU2C5h9MLQWhHUhPTAQLLT++9A8+70IUnXP9VLliDbLCBLU6QaBdpOu8 or6DKF5bvLZqCL4W5QX22Hfpu8PV1kPJ/X2o5XNNX4c2RxdG8SK9i3YT4dm2binOSO3o vltA== 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=3SMQ46G8IRFQna3g+4B67sNj9wZf4cksdhNQ4IUcuW4=; b=I9a7KrtXow2uxnJ8hKDE6NiF0kEkSWoo9iSssKjwnRLerlEJq1zuRnqg1CI1qp0xpJ dH3HXcvxtU8bYR5jVV+PZd3Z5A5yDllKhMcSSNYizU7S/74T/wIcOd3h0GdbQ8aXfH6l p0ALsiFM8bt5hU2vu5SR09wjbkG9/aCmmiAyGhs8hy/qxgEhNVHPuL8tN6WqpjlecRwH eVSg1VpO6SCINmCkMLPUw9t+pXjHaQNhwQY39Xt7yuNh3PStaJHze0SLzziMzYkrdMm+ 2Be397649FhG+vHw9aSjBcitaAxEo8VT2mxm68poePS2mhEUJJhz2924LZJI4hcnlmEI hcpA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=fX6Lk+BZ; 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 q14-20020a6557ce000000b005073e3342eesi2113004pgr.143.2023.03.31.04.09.47; Fri, 31 Mar 2023 04:09:58 -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=fX6Lk+BZ; 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 S231964AbjCaK6B (ORCPT + 99 others); Fri, 31 Mar 2023 06:58:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231814AbjCaK4y (ORCPT ); Fri, 31 Mar 2023 06:56:54 -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 855E11DFB2; Fri, 31 Mar 2023 03:56:38 -0700 (PDT) Received: by mail-pj1-x102a.google.com with SMTP id h12-20020a17090aea8c00b0023d1311fab3so22961153pjz.1; Fri, 31 Mar 2023 03:56:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260198; 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=3SMQ46G8IRFQna3g+4B67sNj9wZf4cksdhNQ4IUcuW4=; b=fX6Lk+BZ2iQGVeeWcpYCgL6buScSfsomo/VT9UiB3OraK0hYkzgQR5/VCi2Vq1pqyY ZRa5t3MdvPpKsBk8H1cW2QnqaTl9icu8tR7nMsMm85HLOfB2bXv1tONgGrYaujnCOCaL 1Agi8+gBOSXKGPq8W9K4H3aEAMkBNf/04UrduOPkpRomXKGlw7lN3bF+IDbEgSQFmsx5 PreEhJMkw6N4vnzVhhFvnSajBT+s0VNzilC/t+ND/QZ9ktiHiLneBZ7cOb6u2x4k3iJC yS0Id9irHqVAzko2NjcP0aLtMch2WcU0WiTjT6eZnXnyRB/t+0s6y5Y5bcr/M2YfNOfQ lV3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260198; 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=3SMQ46G8IRFQna3g+4B67sNj9wZf4cksdhNQ4IUcuW4=; b=Q+ArwnLPOerVnzAOdLnv4fxGHc/uplolu9Xzwq9DBJfDcixrj3ARx63pEQhyXHwyTK Fm5LX3l0nTeUYnhzejbcOByfQkjC27G5Qll6mxH4U2StmshsiL3dLdXysKZvXO07qAWX 7prfPSr7yBRhycYXJVN878zQ1YNtK9UQloQIX7lqxLHuWE+3DlzRay8xoIm3wy8J2U59 Kpo+N7j5Z/eMJPLqbkDfyzeW6TVqJpSOYojsDsO5+sR3pfiyza7bwBcq6zyEO0RPLhBx QQLI3LZhvxZfw2fSTibl/je0lYCLxIVyX5BHtXDYaiz08Pfklmun8i+/edsMtD5U1siY 1SwA== X-Gm-Message-State: AAQBX9crP4ij1t7SwIIrMdyAL5Aq8oGSeOJDS2vF6G3RxBAKuWQpbMYl 2Z5PGGj+GbkdSWI8+mKS38QoVNjstmw= X-Received: by 2002:a17:902:e0c5:b0:1a0:6eb4:3871 with SMTP id e5-20020a170902e0c500b001a06eb43871mr21529970pla.20.1680260198024; Fri, 31 Mar 2023 03:56:38 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56: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 V7 12/23] mmc: sdhci-uhs2: skip signal_voltage_switch() Date: Fri, 31 Mar 2023 18:55:35 +0800 Message-Id: <20230331105546.13607-13-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881357024073965?= X-GMAIL-MSGID: =?utf-8?q?1761881357024073965?= 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 3f232f4e0820..388d87537847 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -144,6 +144,27 @@ static void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, } } +/*****************************************************************************\ + * * + * 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 * @@ -152,6 +173,9 @@ static void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, 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 Fri Mar 31 10:55:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77727 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp477147vqo; Fri, 31 Mar 2023 04:06:25 -0700 (PDT) X-Google-Smtp-Source: AKy350bu4UdrrWqundL4I2/xOb3izxPsEM0ZOFzoZYSCwOhy/q7TwrgkT1m3kI1I2bbZ61690bFW X-Received: by 2002:a17:903:2903:b0:1a1:6584:31b0 with SMTP id lh3-20020a170903290300b001a1658431b0mr23823859plb.30.1680260785433; Fri, 31 Mar 2023 04:06:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260785; cv=none; d=google.com; s=arc-20160816; b=q7xlmu0ePLKhrV3Z4acItwRHJYebBaRVPl5HMI7/V4G9Fk3Y9a7+U35al5wa3Ai6EG +xKlRqGqK//IxZYC5LHNl23ANG8/TeKiRB9xvs0hQw4lzb+1vSoFCdBg9EvdAJkP+ACf zchk1AES74FuCpAobg5xIQTalV3riFvr2rspVtb5tIb248Ank1FVHjVzg/kXGC2PjxQu X96Jb0IpSuAI0UUoURXF9EZV/4GEkpBuhbC3iysPDVUJ9l5bfd6Ir/vaSQn7+ihTV02x gvKPTQ7xefBdfbpYDh+KysxTfLKFiA/yiUNHXHSvT39Dtq7mkcBZaylom/M5QKjdfS0I 0r0g== 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=Wp30TZgq7jKbpo8InJLkytMfD3sdBwQgwReNUO4+h3A=; b=orwQgAVafOG4DlXiTp8TDYtN4goalVEMTm89vEuj1woYLa7aDuq41b0/4KihfO6fDl NcN6aZsRNHWOTtrOrGNTA3pOsxYD/xuLxAnTfXfUalEuI46VtcG7JGILlJPpVerSqUv2 bVohaa5cf8kdrV7kVwucE2ITGkZ/ONzFwceVF7/f5+6ytybW7wvbVqAngu3q1C9Iae15 peLoxpnJDgQMci4brlmlWcVIq0O/miOnir68IiB1K26Kqvv/IR07eCX4Ml1lQLbH95TT BDmnRBvEuxtsj0XZbkkStagOYmPcIk7fldDa+bcvQiiMEmpAlIegtLheRMSPMZ+2cHmO lN5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=AMt6y63H; 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 t185-20020a6381c2000000b00513576ea7casi1611519pgd.795.2023.03.31.04.06.12; Fri, 31 Mar 2023 04:06: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=AMt6y63H; 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 S231967AbjCaK6G (ORCPT + 99 others); Fri, 31 Mar 2023 06:58:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60506 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231818AbjCaK4y (ORCPT ); Fri, 31 Mar 2023 06:56:54 -0400 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2499E1DFB8; Fri, 31 Mar 2023 03:56:41 -0700 (PDT) Received: by mail-pl1-x62b.google.com with SMTP id o11so20895222ple.1; Fri, 31 Mar 2023 03:56:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260200; 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=Wp30TZgq7jKbpo8InJLkytMfD3sdBwQgwReNUO4+h3A=; b=AMt6y63HsQkvVBB3Zl90YYI96BX3sSyiEmVwU15sWWTCfrngdEwCCD5PJLbd9pfBQc TwzS7RC1mydjAUl60PiuGX5Rfzcy+xLI6z3Pz3kQZUWNdTjmUmUEronBTUpj2dEm3gCV qdgvCiSJ/S1B35IrfC6+/12TDQ1y8WmHeWI/fs064v+W/+miiByDKuXpGitXmzrp8W6a m2q9A9U5GoBYeADyjPwhenyfCdZl1SlRa8zuKi2TYfRzQDbvWgsN1sAHtb2bd8fh+XfA N0OrC4tB+mZG1CZaHJJOJUK1jJi9bnxfv7K6Skuef7On8uC6zBR/q+gp42H/IAHO62nd f6jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260200; 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=Wp30TZgq7jKbpo8InJLkytMfD3sdBwQgwReNUO4+h3A=; b=kF+7Jyn6rYL73smwG6GbNqVWDDqNdIlesoybO4PiFLIBOnZVL18p23n7rYHgIunG4T aL1Mgem+SiD3AE7X4cwtT6sL1r8jAGrGG/fIwsdgLBC16AVAV4yG7pZ1i9vl8k5BW8oZ dRyGs3bbGHnYFOTvKjqdS8mOuEtqNZE9Ey2BXBZl8s/fBWihL1Er2NiaCaRa5twu9RmP FkCobZn4leuPtOTa9K4Yiimn4ND7sE7jExxF3LoC61iSqEGz+pCIttRvBpvlB7BhIrvw AfWanEqeQNCbMfbXNmxgZodUEH9dWxzTnhjO0Sft6hoxxe/PyFgsibHkehynCYBDeVPP Apyw== X-Gm-Message-State: AAQBX9cl2Z9icWnrUTZorWJuF4ZCCzf7fDnlf1rVlWtYMoAAuzBw3QzP 3DHOYep1dSh/QPrtQpCwvLk= X-Received: by 2002:a17:90b:180a:b0:23f:aa93:6cfd with SMTP id lw10-20020a17090b180a00b0023faa936cfdmr29807856pjb.18.1680260200590; Fri, 31 Mar 2023 03:56:40 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56: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 V7 13/23] mmc: sdhci-uhs2: add set_timeout() Date: Fri, 31 Mar 2023 18:55:36 +0800 Message-Id: <20230331105546.13607-14-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881133056495066?= X-GMAIL-MSGID: =?utf-8?q?1761881133056495066?= This is a UHS-II version of sdhci's set_timeout() operation. Signed-off-by: Ben Chuang Signed-off-by: AKASHI Takahiro Signed-off-by: Victor Shih --- drivers/mmc/host/sdhci-uhs2.c | 72 +++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 1 + 2 files changed, 73 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 388d87537847..e2e9ce51b768 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" @@ -144,6 +145,77 @@ static void sdhci_uhs2_set_power(struct sdhci_host *host, unsigned char mode, } } +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; + /* 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 |= FIELD_PREP(SDHCI_UHS2_TIMER_CTRL_DEADLOCK_MASK, dead_lock); + 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 (sdhci_uhs2_mode(host)) + __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 6834893eee85..fc03a178b676 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -180,5 +180,6 @@ 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_timeout(struct sdhci_host *host, struct mmc_command *cmd); #endif /* __SDHCI_UHS2_H */ From patchwork Fri Mar 31 10:55:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77731 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp478046vqo; Fri, 31 Mar 2023 04:07:53 -0700 (PDT) X-Google-Smtp-Source: AKy350ZNibupAFFMkltb4RGIwNf5byzUi+S0VTOthor3p1XtWdaIJxYEMQcySLW2d9eogc52kUBN X-Received: by 2002:a17:903:3293:b0:1a0:428b:d8c5 with SMTP id jh19-20020a170903329300b001a0428bd8c5mr23028805plb.45.1680260873190; Fri, 31 Mar 2023 04:07:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260873; cv=none; d=google.com; s=arc-20160816; b=U4xcsEtrgDJ+m049sYRhhPTX9cro03cz3XrLpy+EJalNpRDjmeamLNRBtuhhxmGcm7 iBYqSyVG0UE3KDCZkJwtnAOsVPW2eimAs3t1Sh6YyiqHPBcCLy2VG6Cd0wbfFL22zbzs u4iwLFHSnF9UPyiSWZEY20OQ0+TfDy8LVvKTSeQF12YR+0Q+59hjRdqABHYd+aqfcbQS Hy6sqXX1tfdzZvLjj1msPLRTR5Sbq48vy4gN4rEqyvipV3Iq2SdjZOguCeaM2iG18o1I UB9LhTw9bK3U/LaHoYRBOI3eRAjAYpmF9ECmCPTTZUy0zCyHUHNLdO07tqeH5Kgw3voa Yidw== 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=SaX6ZX9As6iE9cghj3tNzlL56Gn6HxEMDqoykFtItss=; b=utWLd9mTBpXz6PEzT2/7WuuQDc/mSylppJaQ6sqlvgzUIzWy8CW87wFIZhu0FJ1pOF heIulfFRHZeZWTzSl2Wk9b/89+eUyYYvcjwAmTZlRg1NQwfyIU/g3uGZvEGJ9M7edGwY mNT610svzNx9xT8VsrzRPwvQW6FRzjG6nM8YWfmbwkXQIhmmEwj2YyqpLgTOVzlBBGY9 dXMKlWS2OCxIjIzAr6upSU0EcTHC+LmW0LkmFGK9j3G9aR3bV2Nb5RquScBkcwWzZ+eP ZSTqSvI3CuiFjCdMIT2BM50lw94nfFj7QLJ5210gj2jK0jGJnarN9akkQfRxYUs6/70I mzBA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=PFd18HXG; 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 b7-20020a656687000000b00513b842f689si1596902pgw.597.2023.03.31.04.07.41; Fri, 31 Mar 2023 04:07:53 -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=PFd18HXG; 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 S231848AbjCaK6K (ORCPT + 99 others); Fri, 31 Mar 2023 06:58:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231831AbjCaK5E (ORCPT ); Fri, 31 Mar 2023 06:57:04 -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 04EEA1E731; Fri, 31 Mar 2023 03:56:43 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id p13-20020a17090a284d00b0023d2e945aebso8436338pjf.0; Fri, 31 Mar 2023 03:56:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260203; 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=SaX6ZX9As6iE9cghj3tNzlL56Gn6HxEMDqoykFtItss=; b=PFd18HXGEshNJr/1zmVloxXKBI2w4pZolguEUC7o3SsAOuEwuzRXpbWca6tsC8nSX+ +HYo2qFbh8eX7qIF7Gw5gjR4GMpzl1+uQb4z5bgwtQ3FYiamU35mJj/A06fgvP8mDu2c mA6nUyBKjYMsngrr+ovZec7QRfIPE0SuHGcoV+Zi5bW0aiblccKnnjEEpO8XArrSru6u Xn0tO1vS7GWoiCaYBlQrEfRZtE1pGRFx6txrp/t97zp1yq6PpKv4plDAP7g8SppaBrhc ydPNX0nsKYHEKJHsfiYIAobiJQtGbmtM0CjK3TIPLrPmQr+V+b+9lP4ib0+Baa8qGCRX KFoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260203; 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=SaX6ZX9As6iE9cghj3tNzlL56Gn6HxEMDqoykFtItss=; b=7FIOZwPzn4CriOvkqAYJkPbf3eG4/7ju1szwAZLu25Ws0bLDQHE7Qa/0o7nTzmrpVU qf8XVsKhpR25FiCAWoSKN2p+qYhd8r8HFN+T0Yff7E8JJvd7KLf+pEmWs/VR0ENdkuvC MopXcN1JEhjA53BOWdFk8G4q0F3GmHsAqJWZ2QradzTjd30WAvK5byuwpcmHkDW9cnJK e6JnS8A7RHAwca5rza1RAN1UwthAQsBVtN5vAMKt0i9GsHss8gnVKmOW7PSqpxF7x2fR aVwrKjIUaRPrDQA3Fk3i1NBsBIDi2Vxzccj7CPqzG+bfNzf97p6gINbz5iSbQBZAQN2r +/MQ== X-Gm-Message-State: AAQBX9f+wVB2w+4RSScK9RgO96BYQAxu2UOVuee1jXKB2xs7fU9RUJbw 5gPwpqleudujAXIzICRMvww= X-Received: by 2002:a17:90b:3b49:b0:237:62f7:3106 with SMTP id ot9-20020a17090b3b4900b0023762f73106mr27658621pjb.17.1680260203129; Fri, 31 Mar 2023 03:56:43 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:42 -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 V7 14/23] mmc: sdhci-uhs2: add set_ios() Date: Fri, 31 Mar 2023 18:55:37 +0800 Message-Id: <20230331105546.13607-15-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881225014694297?= X-GMAIL-MSGID: =?utf-8?q?1761881225014694297?= 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 | 91 +++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 1 + drivers/mmc/host/sdhci.c | 53 ++++++++++++-------- drivers/mmc/host/sdhci.h | 2 + 4 files changed, 126 insertions(+), 21 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index e2e9ce51b768..9b519bd6d76e 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -216,6 +216,67 @@ 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_INT_STATUS_ENABLE); + ier &= ~clear; + ier |= set; + sdhci_writel(host, ier, SDHCI_UHS2_INT_STATUS_ENABLE); + sdhci_writel(host, ier, SDHCI_UHS2_INT_SIGNAL_ENABLE); +} +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; + + /* UHS2 Timeout Control */ + sdhci_calc_timeout_uhs2(host, &cmd_res, &dead_lock); + + /* change to use calculate value */ + cmd_res |= FIELD_PREP(SDHCI_UHS2_TIMER_CTRL_DEADLOCK_MASK, dead_lock); + + sdhci_uhs2_clear_set_irqs(host, + SDHCI_UHS2_INT_CMD_TIMEOUT | + SDHCI_UHS2_INT_DEADLOCK_TIMEOUT, + 0); + sdhci_writeb(host, cmd_res, SDHCI_UHS2_TIMER_CTRL); + sdhci_uhs2_clear_set_irqs(host, 0, + SDHCI_UHS2_INT_CMD_TIMEOUT | + SDHCI_UHS2_INT_DEADLOCK_TIMEOUT); + + /* UHS2 timing. Note, UHS2 timing is disabled when powering off */ + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (ios->timing == MMC_TIMING_UHS2_SPEED_A) + ctrl_2 |= SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE; + else + ctrl_2 &= ~(SDHCI_CTRL_UHS2 | SDHCI_CTRL_UHS2_ENABLE); + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); + host->timing = ios->timing; + + 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); + + sdhci_set_clock(host, host->clock); +} + /*****************************************************************************\ * * * MMC callbacks * @@ -237,6 +298,36 @@ static int sdhci_uhs2_start_signal_voltage_switch(struct mmc_host *mmc, return sdhci_start_signal_voltage_switch(mmc, ios); } +static int sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + + pr_debug("%s: clock %uHz powermode %u Vdd %u timing %u\n", + mmc_hostname(mmc), ios->clock, ios->power_mode, ios->vdd, ios->timing); + + if (!sdhci_uhs2_mode(host)) { + sdhci_set_ios(mmc, ios); + return 0; + } + + if (ios->power_mode == MMC_POWER_UNDEFINED) + return 0; + + if (host->flags & SDHCI_DEVICE_DEAD) { + if (ios->power_mode == MMC_POWER_OFF) { + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc2, 0); + } + return -1; + } + + sdhci_set_ios_common(mmc, ios); + + __sdhci_uhs2_set_ios(mmc, ios); + + return 0; +} + /*****************************************************************************\ * * * Driver init/exit * diff --git a/drivers/mmc/host/sdhci-uhs2.h b/drivers/mmc/host/sdhci-uhs2.h index fc03a178b676..33e03b1b2b80 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -181,5 +181,6 @@ 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_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 a68a2dce0efe..90d990a84d4f 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) @@ -1877,6 +1875,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_UHS2_SPEED_A: + preset = sdhci_readw(host, SDHCI_PRESET_FOR_UHS2); + break; default: pr_warn("%s: Invalid UHS-I mode selected\n", mmc_hostname(host->mmc)); @@ -2323,24 +2324,9 @@ static bool sdhci_presetable_values_change(struct sdhci_host *host, struct mmc_i (sdhci_preset_needed(host, ios->timing) || host->drv_type != ios->drv_type); } -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); - bool reinit_uhs = host->reinit_uhs; - bool turning_on_clk = false; - u8 ctrl; - - host->reinit_uhs = false; - - 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. @@ -2357,8 +2343,6 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) sdhci_enable_preset_value(host, false); if (!ios->clock || ios->clock != host->clock) { - turning_on_clk = ios->clock && !host->clock; - host->ops->set_clock(host, ios->clock); host->clock = ios->clock; @@ -2374,12 +2358,38 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) mmc->max_busy_timeout /= host->timeout_clk; } } +} +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); + bool reinit_uhs = host->reinit_uhs; + bool turning_on_clk = false; + u8 ctrl; + + host->reinit_uhs = false; + + 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->set_power) host->ops->set_power(host, ios->power_mode, ios->vdd); else sdhci_set_power(host, ios->power_mode, ios->vdd); + if (!ios->clock || ios->clock != host->clock) + turning_on_clk = ios->clock && !host->clock; + if (host->ops->platform_send_init_74_clocks) host->ops->platform_send_init_74_clocks(host, ios->power_mode); @@ -2957,7 +2967,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) @@ -2985,6 +2995,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 02ea4a00ad63..17d467172fe4 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -848,6 +848,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 Fri Mar 31 10:55:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77740 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479416vqo; Fri, 31 Mar 2023 04:10:13 -0700 (PDT) X-Google-Smtp-Source: AKy350bGAZEbzHjmUcgWpcLAA9VHVvTKyObAfiiUMWA0R/T064OBugClyjhMz2gtNk7P9t9ELjqP X-Received: by 2002:a05:6a20:b394:b0:e4:9f3c:21f3 with SMTP id eg20-20020a056a20b39400b000e49f3c21f3mr645353pzb.35.1680261013626; Fri, 31 Mar 2023 04:10:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680261013; cv=none; d=google.com; s=arc-20160816; b=QYuGKWo0zJYEHJvlp9N8pNjY9Iz6pNFghPKvv9lSHTg0GMyUGMCWoWVX32nRgwRW+r TclO5EyRS/sdmzzlJkJuMdC3n0nBOlpm4lyqwzliLoT6Yq8WntDYrTadJ/c5RHzg9gXf sPaAW+KAMwFIX5+pnyxPxxc9Oxaa90fQE7/9+P/3YxYyV63DSZQUb4mkSJRnLUS5zaR0 grDo76bpdsqI/psNgQ5q9lCKnAzKIgDfTVQ1xo4q5BPPUdNo34U+LshtyzxCOKhX4oEk Kmi2hl5zEpNSBmXlP5x94PYrMa3vOUf37KLc1CjuhbZ7Gm5KoHEBnysnbUHiGq/EcEuP Zrwg== 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=AEuXxhp4qHoiYKzslqhx+XlA1usXlIds0JD7B0pv+sQ=; b=EmRP5SF5qN4sCwFQKAuRPl3+CxyvKBuwDnzbSboQEZLP8inXOEUiRMWuf9tYBx2BAw xD5wV0Wv5J+ibD8Qtr092Obh5GPg/GdbSuiBiGQnbX3URCaubnggIT5Wsbwyl0BrombP AckJzOq418ExXjUnzAM5cjAq2F/pV3Ze43uR+Bdl0pDk2G2T8IixtiU0HDDAA4YDD600 D0zBud6U1qgy7OD/tOrpn7iLJGlKofoLmBpAsucYkqQrE+D4iiIs7h3W9urdp1781ZEw ZfsxgtlHihsks3HjuBBOTgB0ig+VgIKsBS8keDGVXax8wFQBFvg72lQ2drbl9u9QLfxy 7pAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=fMKpoleo; 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 t185-20020a635fc2000000b004fc21da0340si2200461pgb.129.2023.03.31.04.10.01; Fri, 31 Mar 2023 04:10:13 -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=fMKpoleo; 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 S231991AbjCaK6Q (ORCPT + 99 others); Fri, 31 Mar 2023 06:58:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231858AbjCaK5G (ORCPT ); Fri, 31 Mar 2023 06:57:06 -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 C0FF51DF8C; Fri, 31 Mar 2023 03:56:46 -0700 (PDT) Received: by mail-pl1-x632.google.com with SMTP id f22so16746882plr.0; Fri, 31 Mar 2023 03:56:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260206; 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=AEuXxhp4qHoiYKzslqhx+XlA1usXlIds0JD7B0pv+sQ=; b=fMKpoleouzT/PMHQEvIT0IL81Eu92Q3JpbP/8juEzoG/UH+914z6TViQ4oxMLe/9Fn YjdmYtoblGXOwA2JiZeKLu2MY0BTErd/+0cgqO2psWPTLPue1uJIxsz1Uf4tcoZDGV6H +tRNDfz17JigB7GZfIYju/NQLCA7q70DP1cin2FwxDnDDV4hGtywkpMXlM1uC5Xaq39h 8p04kHF9adhJ/hUYUpQAgd7ru0GngxHbZ488uH3STSs/SfZXLsyghjX7T97NCOcnu1GY l4ols/rLNUrybUP21xPCowpTGVzQkKdAN3E9tenoXdW7KNmOVKBxpSdYSIOaDxEZR+VJ YPwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260206; 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=AEuXxhp4qHoiYKzslqhx+XlA1usXlIds0JD7B0pv+sQ=; b=g2px2WYbczltxB51cv0OPlo3srHhcV4+ekvtlXUhtgocU5p7ood0Zuc5QVLb72+LmO tTD4NDWKSwDBQRcji3VwngEKkH6VF5uknB8F4RSv4HU1i7VT3HIM9AXID898aUxvcaHh g0rjju7bE58vAejw8nsz5BGU7D1u9g9fp5WAbPN095pHInG11diJjhRAhprApd6tkl3J tasjJ1uhGm8svxDrZJWfNkzALdAwgYX/NBEQdqliqstFV5DCCgk1SVe09MkfRXG4sd1R kItqsudgfzcoSLPtOSuH8rnlCOVALYs25yax7szgMXBNyAE/DeYJqTOZa1n55Ji/jvwc 7twA== X-Gm-Message-State: AAQBX9cE06zjd9tEPfVs5VkOrdsQqIP8nx27N5dnS6qKbPGzcjqq0X66 kTLpSPrcHn9DTYr4ZytioDE= X-Received: by 2002:a17:902:e2ca:b0:1a2:9051:f0a3 with SMTP id l10-20020a170902e2ca00b001a29051f0a3mr3941023plc.24.1680260205949; Fri, 31 Mar 2023 03:56:45 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:45 -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 V7 15/23] mmc: sdhci-uhs2: add detect_init() to detect the interface Date: Fri, 31 Mar 2023 18:55:38 +0800 Message-Id: <20230331105546.13607-16-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881372529851374?= X-GMAIL-MSGID: =?utf-8?q?1761881372529851374?= 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 | 117 ++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 9b519bd6d76e..e2972be1889f 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -334,6 +334,123 @@ static 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_INT_ERROR_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; + + caps_ptr = sdhci_readw(host, SDHCI_UHS2_CAPS_PTR); + if (caps_ptr < 0x100 || caps_ptr > 0x1FF) { + pr_err("%s: SDHCI_UHS2_CAPS_PTR(%d) is wrong.\n", + mmc_hostname(mmc), caps_ptr); + return -ENODEV; + } + caps_gen = sdhci_readl(host, caps_ptr + SDHCI_UHS2_CAPS_OFFSET); + caps_phy = sdhci_readl(host, caps_ptr + SDHCI_UHS2_CAPS_PHY_OFFSET); + caps_tran[0] = sdhci_readl(host, caps_ptr + SDHCI_UHS2_CAPS_TRAN_OFFSET); + caps_tran[1] = sdhci_readl(host, caps_ptr + SDHCI_UHS2_CAPS_TRAN_1_OFFSET); + + /* General Caps */ + mmc->uhs2_caps.dap = caps_gen & SDHCI_UHS2_CAPS_DAP_MASK; + mmc->uhs2_caps.gap = FIELD_GET(SDHCI_UHS2_CAPS_GAP_MASK, caps_gen); + mmc->uhs2_caps.n_lanes = FIELD_GET(SDHCI_UHS2_CAPS_LANE_MASK, caps_gen); + mmc->uhs2_caps.addr64 = (caps_gen & SDHCI_UHS2_CAPS_ADDR_64) ? 1 : 0; + mmc->uhs2_caps.card_type = FIELD_GET(SDHCI_UHS2_CAPS_DEV_TYPE_MASK, caps_gen); + + /* PHY Caps */ + mmc->uhs2_caps.phy_rev = caps_phy & SDHCI_UHS2_CAPS_PHY_REV_MASK; + mmc->uhs2_caps.speed_range = FIELD_GET(SDHCI_UHS2_CAPS_PHY_RANGE_MASK, caps_phy); + mmc->uhs2_caps.n_lss_sync = FIELD_GET(SDHCI_UHS2_CAPS_PHY_N_LSS_SYN_MASK, caps_phy); + mmc->uhs2_caps.n_lss_dir = FIELD_GET(SDHCI_UHS2_CAPS_PHY_N_LSS_DIR_MASK, caps_phy); + 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_CAPS_TRAN_LINK_REV_MASK; + mmc->uhs2_caps.n_fcu = FIELD_GET(SDHCI_UHS2_CAPS_TRAN_N_FCU_MASK, caps_tran[0]); + if (mmc->uhs2_caps.n_fcu == 0) + mmc->uhs2_caps.n_fcu = 256; + mmc->uhs2_caps.host_type = FIELD_GET(SDHCI_UHS2_CAPS_TRAN_HOST_TYPE_MASK, caps_tran[0]); + mmc->uhs2_caps.maxblk_len = FIELD_GET(SDHCI_UHS2_CAPS_TRAN_BLK_LEN_MASK, caps_tran[0]); + mmc->uhs2_caps.n_data_gap = caps_tran[1] & SDHCI_UHS2_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("Begin do uhs2 detect init.\n"); + + 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. */ + sdhci_uhs2_reset(host, SDHCI_UHS2_SW_RESET_SD); + sdhci_uhs2_clear_set_irqs(host, SDHCI_INT_ALL_MASK, SDHCI_UHS2_INT_ERROR_MASK); + /* + * N.B 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 = From patchwork Fri Mar 31 10:55:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77743 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479752vqo; Fri, 31 Mar 2023 04:10:46 -0700 (PDT) X-Google-Smtp-Source: AK7set/uq80gMqaMoKdiD7dM9h5qjIDMZYH46P+fa2k6JaLjONOK0F6gUKUeHjDaO0L6u7N6Lx5a X-Received: by 2002:a05:6a20:1a91:b0:db:9a60:a533 with SMTP id ci17-20020a056a201a9100b000db9a60a533mr24144990pzb.16.1680261046663; Fri, 31 Mar 2023 04:10:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680261046; cv=none; d=google.com; s=arc-20160816; b=sUOlnPJlXfAWcnT9Nhly7GREulYp2QlCJL7aRQkyz68Qvr2mPqt68YJ7E7BvlIDgf4 w6+Qw/A4X7m1H2yTPCcvquuLYOzcVnfykzVufFOs63r+AgicY7wVieDhOLD/0mba8d1z AIJX9URMUKW42PdfwSBBsZiN1FMJMPfHFL8ZeTb7UE3zlrJHr8gKn5kec1TTZyEG1WHF bXxLB62j0tYPWV5+hrdwD7w+5G5y3fD0WjECsOw9IwyYTIGMEx3QGZwOMGmPvqnyeQD+ fO3p/4MhxbFsrLl8VbEWSPUJpmW6Gpwg1iHChOGZb0DWbA8OichPRDXudT1Z/oK7ifpy yU7g== 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=+epQ2fJqKm8pKG4mkhGCfxfL0+iUltjeegx/M8nHNZM=; b=EDU/jYTII8EyVyl3ZAybxNcbdzunYG2fbrilCLF+agtC5PKz90pwkz8TRdbMSLeRnZ 91py0yNIRonrGf0rMV3rqvNE1zkPDU9pJrI7vd/7mqWPCdNfv+XZNac48meQg3Jr50ur B1FY61xE50wO/ffsvvkgYJ6xoOIfK3RmCqkPavssVzEygkV2I5TP9XF/q5Fp0zQfT5d/ z0djeb1LKK6u0+3Pgj9wXLfASr7LUgwG2m7ZGV0QvS6jWz6mn4vJoonNUveQgit9h093 n24rcQynM0SCVbroHjHmy3owXpExO/cjZ6MwM8G94l3iuP/OCDMq2TPmZbbXBpbfqZfF KcNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="F/2D6Jiv"; 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 u12-20020a63ef0c000000b0050befeed881si2054571pgh.275.2023.03.31.04.10.34; Fri, 31 Mar 2023 04:10:46 -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="F/2D6Jiv"; 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 S231874AbjCaK6W (ORCPT + 99 others); Fri, 31 Mar 2023 06:58:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230339AbjCaK5H (ORCPT ); Fri, 31 Mar 2023 06:57:07 -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 42EB61F796; Fri, 31 Mar 2023 03:56:48 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id mp3-20020a17090b190300b0023fcc8ce113so24961322pjb.4; Fri, 31 Mar 2023 03:56:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260208; 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=+epQ2fJqKm8pKG4mkhGCfxfL0+iUltjeegx/M8nHNZM=; b=F/2D6JivO4dtadMidG0Cg3NGecqcU8zbFYmHvudTJRUP4hteyz4mksmwrkMh9Xqxfl 5vG9+GAyEkr5CknMcLJJP00E0GRZKJVRnGV6PS4bXhcrr2i6BBq8dlydMrHjcYL4TCSE TEIOOknwPG2sin07P87DoYHViZi6UfvF78/PiMMK5KA934jJuCTYR9b887Q8ayZa5ylQ 6Xf5fMQguNNzaEVLYgmAFODe95M4hOhqDQ09F/1Vlth4+3UWROYd0UPiKxAwESjUrDCf TuKAEgWFNDX07NM0nvRmT0+fUlofXdFQerJDFSQ9nvc4/0Mssa6wmgFqA+S1qtA2ccxh DGiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260208; 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=+epQ2fJqKm8pKG4mkhGCfxfL0+iUltjeegx/M8nHNZM=; b=QvBSeLGw90Y3kQ+BS/VVBwuAg2RW1FhiEEjNV72Uvjpqp3qvzCooVzcQrif5cpk5Li r1pSAdowIlQEjkiYBmpo4VUpp9w/oW+XK5vlHE42vO/T4xajOPu+r31TCNgjFOsS5WPq U2mYhsxtCsU2S0hHDU5V2gO7jZugP4UVgke7AKYGMf/qoQ+zb6VIKYHYE8so76jZdXUI HPbClmwm5xFi0afaCjeLEU07FAqWVo8GKolLfT7tDukKYKoaOoXTEqaEMykWqNiSEbL9 RjtQERQ0JUrY0Q2NAICNkQG40pQqzg11PCSiqZYTiIkZqy5Tl8xQsZM5Ygnmiy3sthNC 8QLg== X-Gm-Message-State: AAQBX9frfUqCJS3KLUeffe5QZmFYBIK4FV8dL1cYs4KakfiI9ifhN6Ev C2vpq1AsLCdD6sOzZSHoSzQFbXm7wK8= X-Received: by 2002:a17:902:d2d2:b0:1a0:6ed9:f9d0 with SMTP id n18-20020a170902d2d200b001a06ed9f9d0mr34107427plc.68.1680260208454; Fri, 31 Mar 2023 03:56:48 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:48 -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 V7 16/23] mmc: sdhci-uhs2: add clock operations Date: Fri, 31 Mar 2023 18:55:39 +0800 Message-Id: <20230331105546.13607-17-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881406932550009?= X-GMAIL-MSGID: =?utf-8?q?1761881406932550009?= 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 | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index e2972be1889f..71ac76065886 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "sdhci.h" #include "sdhci-uhs2.h" @@ -328,6 +329,37 @@ static 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 * From patchwork Fri Mar 31 10:55:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77729 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp477608vqo; Fri, 31 Mar 2023 04:07:10 -0700 (PDT) X-Google-Smtp-Source: AKy350bKKcOYC4BHuIfZ1d8HfjA1z3OFVetgGe533UifhuGdYi/NJucT9APjMCYDoVgiKZZar8y4 X-Received: by 2002:a17:903:64b:b0:1a1:cc9d:3d55 with SMTP id kh11-20020a170903064b00b001a1cc9d3d55mr21650550plb.20.1680260830101; Fri, 31 Mar 2023 04:07:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260830; cv=none; d=google.com; s=arc-20160816; b=ziyPTMTk72vcfzNXNKV9/Fdwu20yiF43OaEOmsh+Uav0MJXoM+rPjBXQ5MptX390lG tXv9d6Nk8nGXVD9p8KhDhW7OPMDKERdRt/Gfc2/22iu0vT5XyycfnybMSiHkMUbTzKYw RFdfMyJFoEUwtH/vItOVTr3A6BINncDXqRW5cr8rFNd7WLiVWi41zQymQU+8i2QS3nab eF5t0JX23QoV51k22LYZpu/NHis7X08KxseZSLN7myftZdUInPPGJwB00uQ2hhYXWQXt N5vhyKgcT4+Kk+7K6pP24/RZ2WtbvkqNbU0O8YAMPPjytfZ+nVZhgeolU7Sdunda8mn6 MEkA== 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=pcc2+sS71Kh88KtU/433SQ0C3GbsggZ0n9u9i4f8nKw=; b=VEjWo8Un5DU6bu9ObOIEd/upRCciBHBqk9YuusRPPX5MfAp9m8mqYybZ6VBTPRJKRE w7nR36EVfv6JQaKaLrd+vxAoBwPYqef83SApOkTaX+wzbI6xI6YFYgb0Px0qutZukSo0 gi8QPK7YCbq2/tyJr187fa26cKtCOmo5SzbwbxQKMSmvv6l4TBoGx+dOjwY1RtluCW+b tFbIvEprMWEOWGxLTGu4yBc1jBYbvf9R6BfvtSYQ8w2iwDBYuWpo2vBNVEFv42sfL3Fm bau8vmO1XxCIXPZs5hVHr9VlQaaIHOnQqfcWzOIHr9VNHJ7FN8VqOr7VxbefhKpXsPI0 lhtA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=YD9DpU2b; 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 u6-20020a170902e5c600b001a23cfb3517si1904621plf.359.2023.03.31.04.06.57; Fri, 31 Mar 2023 04:07:10 -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=YD9DpU2b; 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 S232021AbjCaK6o (ORCPT + 99 others); Fri, 31 Mar 2023 06:58:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58724 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231464AbjCaK5P (ORCPT ); Fri, 31 Mar 2023 06:57:15 -0400 Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 794661D85E; Fri, 31 Mar 2023 03:56:51 -0700 (PDT) Received: by mail-pl1-x630.google.com with SMTP id ja10so20872848plb.5; Fri, 31 Mar 2023 03:56:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260211; 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=pcc2+sS71Kh88KtU/433SQ0C3GbsggZ0n9u9i4f8nKw=; b=YD9DpU2b/jVawT1SbE0ATgh1rbUv4kzpx4mAwToL/9YybPrcKX0cvIuqVspHkZGnHx YkW3MzuABLspV+Om0zt/x/1jteVmrmlj/Rp6l7T6goyIdtvNUpr4gjnkkoIKZmzM6LA8 Hkyg55ZsEvlSgJJEfZoTmzZWTlDA/YXKjhcTNjjnC16CnuktVBArIabXCoNVKr+Z0KGD FdYtnAUKyJGO3z0QPbhWVbOENg//QOSuBLrnZu5oxb4IEidGcrzOJABCC2zcqHivNEzs ibnyFmbRrpOkoRlSo5CkA3t5zWUc4xP+T5CcHA3RDyzOUgW9IOO1WtSYTTYVGMg2tcHd aToA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260211; 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=pcc2+sS71Kh88KtU/433SQ0C3GbsggZ0n9u9i4f8nKw=; b=fx07sgt8UJjB6dWbbuma9ixo51sp5vm24d7VYzZNdNuMzUiE5leKZCoSlgEas8P7k5 dmr+8ceM45uJhTUTPcb+/7HDyPFfeNFjWNkOd6A04ot5C2Fm2y14avT/mH5aPxaW1R0D TgWvoIkZBzGQ0CX5ymDBwoWnlwZJdnDpmfJAvu5hyj1rea/AY4Bioiquy5muGlU9j1iR /lv6g9W9crAwyuKB1E3ULcs/w1Q+LQsl+h09xjuAxGwLJaSD+wWPUUhveva2X4x1AHbs 5f4PuCYnCrQSpVPVVBA076K4m+JfBROZq19vx/3zNUY728JtRT36/mb08Qu9qedDKDp8 O4ug== X-Gm-Message-State: AAQBX9cOItUb/Cdf6Jac3RT5wHTEl0ZVXQotUuUvRY1JlxU2SM4yVjl3 NnCh/6BtQXQTQJXk061x8s43ymPXkQE= X-Received: by 2002:a17:903:28ce:b0:1a0:6852:16e9 with SMTP id kv14-20020a17090328ce00b001a0685216e9mr20832732plb.14.1680260211068; Fri, 31 Mar 2023 03:56:51 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:50 -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 V7 17/23] mmc: sdhci-uhs2: add uhs2_control() to initialise the interface Date: Fri, 31 Mar 2023 18:55:40 +0800 Message-Id: <20230331105546.13607-18-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881180106478951?= X-GMAIL-MSGID: =?utf-8?q?1761881180106478951?= 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 | 89 +++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 71ac76065886..6fe394b1a7be 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -278,6 +278,49 @@ static void __sdhci_uhs2_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) sdhci_set_clock(host, host->clock); } +static void sdhci_uhs2_set_config(struct sdhci_host *host) +{ + u32 value; + u16 sdhci_uhs2_set_ptr = sdhci_readw(host, SDHCI_UHS2_SETTINGS_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 */ + value = FIELD_PREP(SDHCI_UHS2_GEN_SETTINGS_N_LANES_MASK, host->mmc->uhs2_caps.n_lanes_set); + sdhci_writel(host, value, sdhci_uhs2_gen_set_reg); + + /* Set PHY Settings */ + value = FIELD_PREP(SDHCI_UHS2_PHY_N_LSS_DIR_MASK, host->mmc->uhs2_caps.n_lss_dir_set) | + FIELD_PREP(SDHCI_UHS2_PHY_N_LSS_SYN_MASK, host->mmc->uhs2_caps.n_lss_sync_set); + if (host->mmc->ios.timing == MMC_TIMING_UHS2_SPEED_B || + host->mmc->ios.timing == MMC_TIMING_UHS2_SPEED_B_HD) + value |= SDHCI_UHS2_PHY_SET_SPEED_B; + sdhci_writel(host, value, sdhci_uhs2_phy_set_reg); + + /* Set LINK-TRAN Settings */ + value = FIELD_PREP(SDHCI_UHS2_TRAN_RETRY_CNT_MASK, host->mmc->uhs2_caps.max_retry_set) | + FIELD_PREP(SDHCI_UHS2_TRAN_N_FCU_MASK, host->mmc->uhs2_caps.n_fcu_set); + 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 * @@ -360,6 +403,51 @@ 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); + struct mmc_ios *ios = &mmc->ios; + int err = 0; + + DBG("Begin uhs2 control, act %d.\n", op); + + 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_uhs2_clear_set_irqs(host, 0, SDHCI_INT_CARD_INT); + break; + case UHS2_DISABLE_INT: + sdhci_uhs2_clear_set_irqs(host, SDHCI_INT_CARD_INT, 0); + 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_SET_IOS: + err = sdhci_uhs2_set_ios(mmc, ios); + break; + default: + pr_err("%s: input sd uhs2 operation %d is wrong!\n", + mmc_hostname(host->mmc), op); + err = -EIO; + break; + } + + return err; +} + /*****************************************************************************\ * * * Driver init/exit * @@ -487,6 +575,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_control = sdhci_uhs2_control; return 0; } From patchwork Fri Mar 31 10:55:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77737 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479116vqo; Fri, 31 Mar 2023 04:09:44 -0700 (PDT) X-Google-Smtp-Source: AKy350ZaY9bDi+1+7dekRLNbaYwVTgIPDmHA2dTCdKrd1hIHNsF8ee8DkZOp2FJ6TC+csZ2dlOYg X-Received: by 2002:a17:902:e847:b0:19e:d6f2:feea with SMTP id t7-20020a170902e84700b0019ed6f2feeamr33362634plg.9.1680260984640; Fri, 31 Mar 2023 04:09:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260984; cv=none; d=google.com; s=arc-20160816; b=xHVW/ievycHCKguyE//W4jo/w2GCOQ0X8NJcY0xwsVU+A/HM6ydhqB3/Qk2FBVF0bT QUhjRPFYOwDO3BeIb9zCjD8VwCcJ82x7AOsgDH4YEjrQGGV0YCxK63pWrF2lsKx5XLJm m0WhkcauDdr0l/DQX/36G4X/bHasUpQTq6bxd/62/3NVtueQngIcchmMYWeJvTqvYsQZ Ru89Sr+eSy0yyDYrkybwih9xK/KBDdJbPrHH2hGsWGNL9HMG+2fO6CkNvQAXoypc91hO 8Lc1BoNFU8K8ziL+y2RiGtdqu1C1XNT0i2qS6QK2fONODp5oescAXP81x60cEvraL6Qg 85Zw== 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=itrAqSr5pvQKa7Mg+soRBc5THRtMGfS+qzlsOXp5UNw=; b=nahuNyKPdmtZJ4nQdEryrill6+QVdqfK+tr9Uv5v2lGgLomSeYfHpkscvOaeaCr1zn IPuVqxCMkhZlEUFSBSb8AAUO3RMw6Gj6IhGfR3Y7mEm8Tn4Sx6Gu8nLv19brL8ULpPGi roDK4kjtCNO5XI4BkePAjLQf21RNs4E1/52dXSkcIV8OV7Tk7xlMNxuLnEQIZlf9PnJu LvQZpK7yVfuGPj6EuY7JHeF6g0BqeOsqMqSlrwmijeqleIztYwZRmelxZKu1XrKD+irR OtP4q2cjJmEg0KEoz+LZlr/xMfpIliY3C43vNWy5EZhsPzyo2W6XWOo5nD4XS/u+GkzS evlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="ZCURw/u/"; 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 u6-20020a170902e5c600b001a23cfb3517si1904621plf.359.2023.03.31.04.09.32; Fri, 31 Mar 2023 04:09: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="ZCURw/u/"; 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 S232026AbjCaK6s (ORCPT + 99 others); Fri, 31 Mar 2023 06:58:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231915AbjCaK5q (ORCPT ); Fri, 31 Mar 2023 06:57:46 -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 7F5FC1E72D; Fri, 31 Mar 2023 03:56:53 -0700 (PDT) Received: by mail-pl1-x62e.google.com with SMTP id z19so20884417plo.2; Fri, 31 Mar 2023 03:56:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260213; 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=itrAqSr5pvQKa7Mg+soRBc5THRtMGfS+qzlsOXp5UNw=; b=ZCURw/u//vIMhCr//il5xdl9EKBStg6IsM6ql5RYF58YY6GfyuMMh1QhelR9wK0/pd a2OHbHiH11GeWjzL5veL/QYGPPUQd4paWn9BL4LaWTpdIi+I5WF4UCzyaaVD1N9bP9jj zvxd0ndOPJml2icBt8ijePwTozeI6gwuP13uf/u7+xw+2Nd5I+mEzZCORCPVM2gPDOZ6 oK7992S2fYZR7lAgEpdI6RQU21blbYKkMwLKDxF/kEm1MJxLWu+0g7MQ0PKSowSIw9Tr yKNXieG0kgQBTJ02rwlV6tky3KViv8IHbqxxMvi6QQZKy+TGNjyi41uZimQQW/UCcvZb EYoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260213; 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=itrAqSr5pvQKa7Mg+soRBc5THRtMGfS+qzlsOXp5UNw=; b=7SZPws5m3z72EFnYo1GIwQW2lcHRreNSGxROAK9AnmvQjyALLc2VfQU16f64WNr8y1 Nob221SeIrqC8xtQlDnhrQakgZj68xaYpcXPS5hbKHMAlLLwd5FtLtusYVUocuYpz12M k0zdFXjs3Q7sPcQ/0RARkiB7fFOqE5HUxEAGNKlErWVP8TxpqTvBGZV0iI+e/HDtu2ze 0mvm40Gsnj2HudN3p0bZXNNdQsdVbIJcmUsBrzPYWjS4em/4E5c4Zxg1mj3XpsfJLin7 O0AajlT4Y8GKHKWQmj4+YfxZK6qdSZgFPuN2GW5K1owNfqiL/WklbpiRQoJkWBZttE63 1O3A== X-Gm-Message-State: AAQBX9eMlZAXzBmV4OnQyGH7QkB1R3vEZGWdKNVllsAzH0LRb9gcI0Rr ji2ujdWMGXTQTI5Y84U4TZk= X-Received: by 2002:a17:903:2451:b0:1a1:add5:c355 with SMTP id l17-20020a170903245100b001a1add5c355mr32633986pls.5.1680260213575; Fri, 31 Mar 2023 03:56:53 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56:53 -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 V7 18/23] mmc: sdhci-uhs2: add request() and others Date: Fri, 31 Mar 2023 18:55:41 +0800 Message-Id: <20230331105546.13607-19-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881341911264209?= X-GMAIL-MSGID: =?utf-8?q?1761881341911264209?= 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 | 417 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c | 51 +++-- drivers/mmc/host/sdhci.h | 8 + 3 files changed, 459 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 6fe394b1a7be..a9655b9546ea 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "sdhci.h" #include "sdhci-uhs2.h" @@ -25,6 +27,8 @@ #define SDHCI_UHS2_DUMP(f, x...) \ pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x) +#define UHS2_ARG_IOADR_MASK 0xfff + void sdhci_uhs2_dump_regs(struct sdhci_host *host) { if (!(sdhci_uhs2_mode(host))) @@ -59,6 +63,11 @@ EXPORT_SYMBOL_GPL(sdhci_uhs2_dump_regs); * * \*****************************************************************************/ +static inline u16 uhs2_dev_cmd(struct mmc_command *cmd) +{ + return be16_to_cpu((__be16)cmd->uhs2_cmd->arg) & UHS2_ARG_IOADR_MASK; +} + static inline int mmc_opt_regulator_set_ocr(struct mmc_host *mmc, struct regulator *supply, unsigned short vdd_bit) @@ -448,6 +457,413 @@ 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); +} + +static void sdhci_uhs2_finish_data(struct sdhci_host *host) +{ + struct mmc_data *data = host->data; + + __sdhci_finish_data_common(host); + + __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; + + if (!data) { + /* clear Auto CMD settings for no data CMDs */ + if (uhs2_dev_cmd(cmd) == 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; + } + + 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 ((mmc_card_uhs2_hd_mode(host->mmc)) && !cmd->uhs2_tmode0_flag) + mode |= SDHCI_UHS2_TRNS_2L_HD; + + sdhci_writew(host, mode, SDHCI_UHS2_TRANS_MODE); + + 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; + + 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); + + 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 = FIELD_PREP(SDHCI_UHS2_CMD_PACK_LEN_MASK, cmd->uhs2_cmd->packet_len); + if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) + cmd_reg |= SDHCI_UHS2_CMD_DATA; + if (cmd->opcode == MMC_STOP_TRANSMISSION) + cmd_reg |= SDHCI_UHS2_CMD_CMD12; + + /* UHS2 Native ABORT */ + if ((cmd->uhs2_cmd->header & UHS2_NATIVE_PACKET) && + (uhs2_dev_cmd(cmd) == UHS2_DEV_CMD_TRANS_ABORT)) + cmd_reg |= SDHCI_UHS2_CMD_TRNS_ABORT; + + /* UHS2 Native DORMANT */ + if ((cmd->uhs2_cmd->header & UHS2_NATIVE_PACKET) && + (uhs2_dev_cmd(cmd) == UHS2_DEV_CMD_GO_DORMANT_STATE)) + cmd_reg |= SDHCI_UHS2_CMD_DORMANT; + + DBG("0x%x is set to UHS2 CMD register.\n", cmd_reg); + + sdhci_writew(host, cmd_reg, SDHCI_UHS2_CMD); +} + +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 (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) + 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); + + __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_SD_TRAN) { + 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; + + __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; + + if (!(sdhci_uhs2_mode(host))) { + sdhci_request(mmc, mrq); + return; + } + + mrq->stop = NULL; + mrq->sbc = NULL; + if (mrq->data) + mrq->data->stop = NULL; + + /* 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 * @@ -576,6 +992,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_control = sdhci_uhs2_control; + host->mmc_host_ops.request = sdhci_uhs2_request; return 0; } diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 90d990a84d4f..55725edd4b91 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,11 @@ 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); static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) { @@ -502,14 +501,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) { @@ -1076,8 +1076,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); @@ -1090,6 +1089,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) @@ -1112,12 +1112,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; @@ -1202,6 +1198,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); } @@ -1519,7 +1525,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; @@ -1543,15 +1549,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; @@ -1585,6 +1593,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 - @@ -1719,8 +1735,8 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) return true; } -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; @@ -1729,6 +1745,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, diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 17d467172fe4..775407dad8da 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -829,6 +829,14 @@ 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_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); +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_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 Fri Mar 31 10:55:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77730 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp477677vqo; Fri, 31 Mar 2023 04:07:18 -0700 (PDT) X-Google-Smtp-Source: AKy350ZWeTht8qhmCaq+n3JmGEstGI/bgYAdGnB3cuMlcYIVCLJ1iT/irH5+mBgk2lqNC1Glf2jl X-Received: by 2002:a17:902:f946:b0:1a2:85f0:e73d with SMTP id kx6-20020a170902f94600b001a285f0e73dmr6330813plb.33.1680260838642; Fri, 31 Mar 2023 04:07:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260838; cv=none; d=google.com; s=arc-20160816; b=Dz+2ICZ+gWYBMd2qOquD6ltP7s1RaWruN1z+tFy7bnFwBAG0ohV9HlZVttPseNPO1r VoRblSAVI3l07Y81bO6+N1GDdUQg3zrBz9h4HFvdaRxj0tYTQNcxtFItnrJlbEEMvv1S 6nS3JhOrquctvsVryy1la8sqQdFY45sPuQyO6qt7SIOM9QQ9E+xTB9W197gqmVaJaBS6 1/aNUJa9FHqJ6VJYih1fkV6yY6oIOsr9MvdnlPxbYGK827JcSfp/aoKpFr/G3od2Z6IY 6DkQEOcjSWLufzBUwplvMpY9nHYvXfkxFsbxpwazjsXT6REMpOGticuhGFF5IM8XP7Ne 8FJA== 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=2eoJmW8KZ9RsKCE8olOoKSzdQJgdO+xir25dsg87dCc=; b=rICI0sut94T+K8gJgG/gLF9ayxHs+ySuogieC6TPYhWu3hoB/+zLrYv2KCXyuiLjCg dbeHv7WaIMpC8yzWfTRboTKAQO7AwyCFtaBr1hNynD1BMiykmpD100eHVG8J9eI4p/Do tuxaKI8uoqS7aLhw2THgqzxZVyjdxXeCI3sLttvo3TkXKvxZs5aFnFkUKV/eWrCG2Gk5 Efm8rDEcLqdlJDOzUgPOkMNs/IynmWwqwpLmt0iPBFOLJEpZOcPClFujbNl1Z18HhxPp mPIpL20sOx1RcSUpxuYueK3ICVgx3zYAzYpL7qhDk2gS4LVbClRhAyZtA/UsQCbuy2Qz R1rw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=KT6M2LvS; 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 x7-20020a1709027c0700b0019b354d0268si1835559pll.280.2023.03.31.04.07.05; Fri, 31 Mar 2023 04:07:18 -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=KT6M2LvS; 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 S232034AbjCaK66 (ORCPT + 99 others); Fri, 31 Mar 2023 06:58:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231952AbjCaK55 (ORCPT ); Fri, 31 Mar 2023 06:57:57 -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 E1E3E1F78F; Fri, 31 Mar 2023 03:56:56 -0700 (PDT) Received: by mail-pj1-x102d.google.com with SMTP id l9-20020a17090a3f0900b0023d32684e7fso8157160pjc.1; Fri, 31 Mar 2023 03:56:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260216; 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=2eoJmW8KZ9RsKCE8olOoKSzdQJgdO+xir25dsg87dCc=; b=KT6M2LvSncScbdeje1pi/9JISbRrmjNJRYwpM5WYIQdyPLoeE+7peFydTUcpcjof+p CEVXIJjWsA4U1ZZ7sspvw2I7BStAtaRjSy6NcRZYUBPUuNlXLaoqonSKy/GaQ1TvdBRM Dgm1czSLfYaPs9TamyjkofT0M40+H2N+bJOqva4fVT9YvnIXw02fYkYHhrtKGyUmrhtc s2Pwdu8WDmq5JBgfOIkq1HP51/ee09nG9ZjScUbwjzI9/0LknU/JERi6xnyrn4s6TFf1 6KYC9rqzBwYN8oDVFlVi/I/F+NcLOTVmSGGRrhhg9mzCWipxGi8c0cJzUcWBf5DmKxSM gaIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260216; 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=2eoJmW8KZ9RsKCE8olOoKSzdQJgdO+xir25dsg87dCc=; b=lN8x+besxA2L/Pg6Gm/18S/IN8rRPOASjIoke1O1yemIdaj7+JmHF2Ccb9OfM3j654 fSOMQVP352HrhiKvWMS0i4gvVjHFgDQmO5PhQcIre2OJJGpOOsHvOUFU9RayrIc/WSsm 5/B/IrXv8HHYOhN/UY601c/Q8uV1u7tB6+Oq7OwLY+bYQzPYvzsW7RrvjndNmGOQE0A8 tT9hB1GDwghuXUnbq2W7avjKHF2iv7Ji4XkCryDbNKkfWyRio8TwK1Fjgll8RXoMidus BAtp+GQQLBRBr6u3mORrNJHpjCHFJMWHlSAKp3XR7i2HPkb549XIOBVazwGB+WhKL2gR 9hlQ== X-Gm-Message-State: AAQBX9csjY894DzxJ2x451nusKwEl6+zuWkagRYXHt5NgoI/aC8DLfA7 4O1xBMSIH61fxF1EBiw8aTk= X-Received: by 2002:a17:902:d48b:b0:1a1:d70f:712d with SMTP id c11-20020a170902d48b00b001a1d70f712dmr33648201plg.31.1680260216047; Fri, 31 Mar 2023 03:56:56 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56: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 V7 19/23] mmc: sdhci-uhs2: add irq() and others Date: Fri, 31 Mar 2023 18:55:42 +0800 Message-Id: <20230331105546.13607-20-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881189305641290?= X-GMAIL-MSGID: =?utf-8?q?1761881189305641290?= 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 | 215 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 3 + drivers/mmc/host/sdhci.c | 106 +++++++++-------- drivers/mmc/host/sdhci.h | 5 + 4 files changed, 283 insertions(+), 46 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index a9655b9546ea..63f4bfce70b8 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -789,6 +789,221 @@ 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; + + 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) + 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; + } + + sdhci_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); + + if (!sdhci_uhs2_mode(host)) { + sdhci_complete_work(work); + return; + } + + 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_INT_CMD_ERR_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_INT_CMD_TIMEOUT) + host->cmd->error = -ETIMEDOUT; + } + + if (uhs2mask & SDHCI_UHS2_INT_DATA_ERR_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_INT_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_INT_ADMA_ERROR) { + 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 (!sdhci_uhs2_mode(host)) + goto out; + + if (intmask & SDHCI_INT_ERROR) { + uhs2mask = sdhci_readl(host, SDHCI_UHS2_INT_STATUS); + if (!(uhs2mask & SDHCI_UHS2_INT_ERROR_MASK)) + goto cmd_irq; + + /* Clear error interrupts */ + sdhci_writel(host, uhs2mask & SDHCI_UHS2_INT_ERROR_MASK, + SDHCI_UHS2_INT_STATUS); + + /* Handle error interrupts */ + __sdhci_uhs2_irq(host, uhs2mask); + + /* Caller, sdhci_irq(), doesn't have to care about UHS-2 errors */ + intmask &= ~SDHCI_INT_ERROR; + mask &= SDHCI_INT_ERROR; + } + +cmd_irq: + 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, sdhci_irq(), doesn't have to care about UHS-2 commands */ + 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; + + if (!sdhci_uhs2_mode(host)) + return sdhci_thread_irq(irq, dev_id); + + 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 33e03b1b2b80..f733c733c692 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -182,5 +182,8 @@ bool sdhci_uhs2_mode(struct sdhci_host *host); void sdhci_uhs2_reset(struct sdhci_host *host, u16 mask); 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 55725edd4b91..b3cf4a26eed5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -47,6 +47,8 @@ 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"); @@ -1495,7 +1497,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) || @@ -1503,8 +1505,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; @@ -1524,6 +1527,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) { @@ -3106,6 +3110,55 @@ static const struct mmc_host_ops sdhci_ops = { * * \*****************************************************************************/ +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); + static bool sdhci_request_done(struct sdhci_host *host) { unsigned long flags; @@ -3170,48 +3223,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; @@ -3226,7 +3238,7 @@ static bool sdhci_request_done(struct sdhci_host *host) return false; } -static void sdhci_complete_work(struct work_struct *work) +void sdhci_complete_work(struct work_struct *work) { struct sdhci_host *host = container_of(work, struct sdhci_host, complete_work); @@ -3234,6 +3246,7 @@ static void sdhci_complete_work(struct work_struct *work) while (!sdhci_request_done(host)) ; } +EXPORT_SYMBOL_GPL(sdhci_complete_work); static void sdhci_timeout_timer(struct timer_list *t) { @@ -3689,7 +3702,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) return result; } -static irqreturn_t sdhci_thread_irq(int irq, void *dev_id) +irqreturn_t sdhci_thread_irq(int irq, void *dev_id) { struct sdhci_host *host = dev_id; struct mmc_command *cmd; @@ -3719,6 +3732,7 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id) return IRQ_HANDLED; } +EXPORT_SYMBOL_GPL(sdhci_thread_irq); /*****************************************************************************\ * * diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 775407dad8da..9e9158f811b1 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -833,6 +833,8 @@ bool sdhci_data_line_cmd(struct mmc_command *cmd); 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); +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); @@ -862,6 +864,9 @@ 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); +void sdhci_complete_work(struct work_struct *work); +irqreturn_t sdhci_thread_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 Fri Mar 31 10:55:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77733 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp478464vqo; Fri, 31 Mar 2023 04:08:40 -0700 (PDT) X-Google-Smtp-Source: AKy350a7vVbECYWKcCK8fYZepEJkNqDIJ9Tz2oO+ljP6pb6ULFhqWw+l6jE+9a76ueTS7qqUVmlM X-Received: by 2002:a05:6a20:4f11:b0:db:ae75:c70e with SMTP id gi17-20020a056a204f1100b000dbae75c70emr11324753pzb.15.1680260920480; Fri, 31 Mar 2023 04:08:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260920; cv=none; d=google.com; s=arc-20160816; b=NHG2tBarugeZxXblYCxGBq4YrvLvjVfg2rAS5RGMucr2tue+x/oqQjRba9QqVKTQ5Z lTiCqjoUy2tHeXxv7/ptQBJUnNZ/vE/vPctokslUPmxiSgKRXnZ+QOcLmFVG7ww4NCtx UbDw01iAMpehoq7/4imFSsINTOfp2o/QxxsYjVZes3Y3lJumxrO8BN44x28uDXJDzmEH 0swbcsjvQIOd9GzLwRtqNpmw0r+c9vcuDrFzKwzPvmLNFc07nGbjSART40eC0SfgYdtP 0+SWgvJ2MFMpRd5P6W8FquEGmrEQsESdoom9sV6qcmQtg3A/+sqsrvDzmeDX2yiDPc/3 pFKg== 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=bpfFQxpEiIXQHS9Jg84GzFFvnKJzIeWLgkIMGgTsZVY=; b=QAT0vLU5lxPioQTELr9baQW1bAsYmdoI5PdcksD4cWkzWRdqEl9ChIRco4Au9HbLKF OWso/gsJq46bH4d2zOMBKpN5rtubBkaWaKYFf/SxclfzTPaVLePTVlsfTbudJ49gAQlb ddZ1L2b1Kygv4g4YaSuk8ZAwELffL6ge4+iW3I9m4rucDL5IzgxMzmSa/h5Z8bcem897 AfkzxLdCRkKK5HBAOQYtraPHuoM2b9tBWMcObrMoPk9m7ob36DXa4xRihp5HNoHRHQAT V6qUIipPPYtuiR+VbyFoybM3ls+/Rq/AroNSIjEY/mzg/yEQalIWFV6TWnpo3wTLZ8q+ K6GQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=lysbxNCz; 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 j6-20020a625506000000b005a8c65d57a0si2259596pfb.257.2023.03.31.04.08.28; Fri, 31 Mar 2023 04:08:40 -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=lysbxNCz; 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 S231983AbjCaK7E (ORCPT + 99 others); Fri, 31 Mar 2023 06:59:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231852AbjCaK6O (ORCPT ); Fri, 31 Mar 2023 06:58:14 -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 B97F920314; Fri, 31 Mar 2023 03:56:59 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id ix20so20882027plb.3; Fri, 31 Mar 2023 03:56:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260219; 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=bpfFQxpEiIXQHS9Jg84GzFFvnKJzIeWLgkIMGgTsZVY=; b=lysbxNCzFina25gZALdwhtTELcVZ8zT7pOB3j3iZ4i2dFPsnhIOEXVFXI3T9ZIXDU7 8uo3HjCQVTMHrgY0KVZgatQ1I3c0dCEKFK6cK7GWLDDNxXy9jDmw/PWFVtzB/XansiDi 6+iL8o1JevwQkP0mtRxjVeLJUuRWAPENes3NfCmVqH/Cud9BudURH83Zk2U6TMkcJ2ys ascd/UOfVtHHEEObllBNyMjmgQv3gc607lgfvNvyF6mndTd1/5JlBOc6fSOpe5hYJBd3 pS+59pqSOHFk3tHzwsq5ktEW1Qr5bG+ZgxMfSEJv12CJbzwcoLQgAvLe0WA4JB0K5yYn YW7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260219; 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=bpfFQxpEiIXQHS9Jg84GzFFvnKJzIeWLgkIMGgTsZVY=; b=WF7cmCA5WNQ/ILgksWwRiTRyz1jj0lMeIwzoEEjV4bBnS/c2PBTKSyAcaGOhLdM0t9 8bwaD8ueIVdUjtoPSqBkLJ9JCCgan2dBxd8T25dn+1mrt57axUsd2FlciFuESb5yja+/ TWgA+pkh57EmC+N4C+RDHzDFa9IwEVYW2bvOiatm+6rwd3Jw3J0jJGrLVeIpDUod1G8a BOUv+uwZJZAdyf6XWIxGg+JjiuDf/Ir3/dNkTfJCluTBXPEUGkEBLRdJwtcdCMuCDug2 DiORGjq2KEzwR6PfnKeTkAnIbv35rHMoJYNQHCXOZZulUIzr7R9qYByMH8wbDrg9iqf8 x8Kw== X-Gm-Message-State: AAQBX9cm5UeyhFK84NFStXlcAInLzxgdJDDWINvTpfS4jUjVJLlbDLkf ve9El70LmM0FTI2LIiJTmog= X-Received: by 2002:a17:902:f2d3:b0:199:1160:956c with SMTP id h19-20020a170902f2d300b001991160956cmr6648225plc.31.1680260218688; Fri, 31 Mar 2023 03:56:58 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:56: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 V7 20/23] mmc: sdhci-uhs2: add add_host() and others to set up the driver Date: Fri, 31 Mar 2023 18:55:43 +0800 Message-Id: <20230331105546.13607-21-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881275053311097?= X-GMAIL-MSGID: =?utf-8?q?1761881275053311097?= 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 | 119 ++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-uhs2.h | 2 + drivers/mmc/host/sdhci.c | 7 +- drivers/mmc/host/sdhci.h | 3 + 4 files changed, 129 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci-uhs2.c b/drivers/mmc/host/sdhci-uhs2.c index 63f4bfce70b8..610780d425bc 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "sdhci.h" #include "sdhci-uhs2.h" @@ -1004,6 +1005,124 @@ 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_CAN_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_CAN_VDD2_180) { + mmc->ocr_avail_uhs2 |= MMC_VDD_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 void __sdhci_uhs2_remove_host(struct sdhci_host *host, int dead) +{ + if (!sdhci_uhs2_mode(host)) + return; + + if (!dead) + sdhci_uhs2_reset(host, SDHCI_UHS2_SW_RESET_FULL); +} + +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; + + /* overwrite ops */ + if (mmc->caps2 & MMC_CAP2_SD_UHS2) + sdhci_uhs2_host_ops_init(host); + + host->complete_work_fn = sdhci_uhs2_complete_work; + host->thread_irq_fn = sdhci_uhs2_thread_irq; + + /* LED support not implemented for UHS2 */ + host->quirks |= SDHCI_QUIRK_NO_LED; + + ret = __sdhci_add_host(host); + if (ret) + goto cleanup2; + + return 0; + +cleanup2: + 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 f733c733c692..5b5b4a8d4f27 100644 --- a/drivers/mmc/host/sdhci-uhs2.h +++ b/drivers/mmc/host/sdhci-uhs2.h @@ -185,5 +185,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 b3cf4a26eed5..d976d3a6ff8d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -4105,6 +4105,9 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, host->max_timeout_count = 0xE; + host->complete_work_fn = sdhci_complete_work; + host->thread_irq_fn = sdhci_thread_irq; + return host; } @@ -4854,7 +4857,7 @@ int __sdhci_add_host(struct sdhci_host *host) if (!host->complete_wq) return -ENOMEM; - INIT_WORK(&host->complete_work, sdhci_complete_work); + INIT_WORK(&host->complete_work, host->complete_work_fn); timer_setup(&host->timer, sdhci_timeout_timer, 0); timer_setup(&host->data_timer, sdhci_timeout_data_timer, 0); @@ -4863,7 +4866,7 @@ int __sdhci_add_host(struct sdhci_host *host) sdhci_init(host, 0); - ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq, + ret = request_threaded_irq(host->irq, sdhci_irq, host->thread_irq_fn, IRQF_SHARED, mmc_hostname(mmc), host); if (ret) { pr_err("%s: Failed to request IRQ %d: %d\n", diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 9e9158f811b1..e16267f5a3c0 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -627,6 +627,9 @@ struct sdhci_host { struct timer_list timer; /* Timer for timeouts */ struct timer_list data_timer; /* Timer for data timeouts */ + void (*complete_work_fn)(struct work_struct *work); + irqreturn_t (*thread_irq_fn)(int irq, void *dev_id); + #if IS_ENABLED(CONFIG_MMC_SDHCI_EXTERNAL_DMA) struct dma_chan *rx_chan; struct dma_chan *tx_chan; From patchwork Fri Mar 31 10:55:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77732 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp478200vqo; Fri, 31 Mar 2023 04:08:09 -0700 (PDT) X-Google-Smtp-Source: AKy350ZWzGfTe9E7p+Z0w0g7rdPrDWRpqACoU16EbBEIT6H+ELMi28HuemvrkLTBqdbzd63vUTFM X-Received: by 2002:a17:903:2311:b0:1a1:b656:2149 with SMTP id d17-20020a170903231100b001a1b6562149mr31606895plh.50.1680260889202; Fri, 31 Mar 2023 04:08:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680260889; cv=none; d=google.com; s=arc-20160816; b=Csaowr1TnIniOha8jqtsXetjqsfF+F5/+DyZG7rZOzyK9fJVm3EcMsN7RukTEKcJqO 0ex8WO9u0XbVUsIxAkQ75RNhzOj9scG6pkCVGd4uaO6mWpkMnkqaZmAoi95N7smkkIEZ /wBuEMryh/ztj7x41kAVwOjcX6wHpWcg/Vr2EmQHd9oJeEikyipUq/5Zm/xsw2WQs4ch kDYlm/TF/+f2lIMrb5IKvZnyP4CkapHwAzZfY9kpOJqNflRCPAaVzMwn922rR3dnauC0 G0nNatCu7gqTcWyiVtGtMc1vO8g+dajZbmUJVQj1zSMkXH3p90D5HWOFjoFqpUmVAOxb m/ZQ== 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=sOx1y1Jd69koEjxiT6HO9K3rjpe/SDeJDjw2BGkWhNc=; b=Pejhy/CO1Aj52jzzH+l1hQsrYrkRZir/fEYlyyFRCEYtz1vYZs8C63pKRznzjTqxru Y0V50VRzvcAL8HWUnZj5Gc88havmV7s0l4EtFp6P2SsU7OHrTHaVl9l6wXj7RsYWbwRT dQ4b531Kp/xPvk8LRubhE5uIRzSyomH6Jm+WmPeELM/mjBOAwPz7oD9fansNszvVn2gg /MqL72cOpHIGPrpbhVYPN23TdNFM/3O8g2Pg8mOu52Y6Rw2DBMNw+Ihv+nJmj8fi2N0Q ItqYm/dgFCtkcwb5V4/JxL8qanRzvuL8C8FY0geYvp1P8+2oQKhcLX3QrG6gXbGgaRL5 cWiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=dNFqwmJo; 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 n16-20020a170902d2d000b0019a95ab6b4esi2093821plc.407.2023.03.31.04.07.57; Fri, 31 Mar 2023 04:08:09 -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=dNFqwmJo; 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 S232069AbjCaK7U (ORCPT + 99 others); Fri, 31 Mar 2023 06:59:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230428AbjCaK63 (ORCPT ); Fri, 31 Mar 2023 06:58:29 -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 884D120334; Fri, 31 Mar 2023 03:57:01 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id p13-20020a17090a284d00b0023d2e945aebso8436757pjf.0; Fri, 31 Mar 2023 03:57:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260221; 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=sOx1y1Jd69koEjxiT6HO9K3rjpe/SDeJDjw2BGkWhNc=; b=dNFqwmJoAtjAPbH36EklXZf0y1aBwi5QcwLEzcpFo2UuRIVEKEYIMZ3Jgi9WzHyL3s 4t5w/Ba0kq9jucRG42t3gYfbSLnsMWsxWk4TyYsrsxpPgXa8kIiHTdoNiSuoxjoBdEqf tIjYL0PzKT86JtQrZJ38AszIvqu+TfZ3hWe6IRoZM4I2kTQjtDkkndoftROUG8iwJxEX 27Xoag4FOqtlvDG9/hebA8U8anIA0JY6agdVeBitpwMvlnvN4F7PdZ7R9N0zKccDoPaG gmrwxtMQqHZ8MAu+2UhKz95YO9ux9v1deqrPP4nrl47wwyWpjHSrnsuaAwyHiS3E1KXv RJdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260221; 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=sOx1y1Jd69koEjxiT6HO9K3rjpe/SDeJDjw2BGkWhNc=; b=Z39HxTZCl39hklVSleApcCeceW3PTzAW8rkgE7oaO7ryrECsVMOlzgDLiAfsB22XYI Hdr7GBGZlE8PV0aPBTZWb2UY6nDJuFSPgE1ATnRFRUaBKe3ZqiOKEgTqg8kJiZKCnbFw e4PV1VUhyT/im4y4OB/QqEWzH3WgfAjYn4keycUeujtS90q5h5fJUPwuV2s7rSCUsalT 5j2XLBmpZQCNoICrhgmrBA16G4R/yS0kPdzWrZzWF50MeR20rR4fz5MCpBSB8U7OdtMZ IBp1VZxzl1k9DErwVvVOQCi32+inMG/ViXx1pH5zq8VXk//rELsIQ6gDQu0ot/XYt1WC vRPA== X-Gm-Message-State: AAQBX9fiG5SuE5/DbyzQfJRiO40LigqulmtaIgQg5uF1DLvo9QXEE2yJ VAtFR4S3SRqi7zW990LjmDc= X-Received: by 2002:a17:90a:b10f:b0:23f:e4b7:afb3 with SMTP id z15-20020a17090ab10f00b0023fe4b7afb3mr30577831pjq.9.1680260221253; Fri, 31 Mar 2023 03:57:01 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.56.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:57:01 -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 V7 21/23] mmc: sdhci-uhs2: add pre-detect_init hook Date: Fri, 31 Mar 2023 18:55:44 +0800 Message-Id: <20230331105546.13607-22-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881242102048996?= X-GMAIL-MSGID: =?utf-8?q?1761881242102048996?= 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 610780d425bc..610cd57864e4 100644 --- a/drivers/mmc/host/sdhci-uhs2.c +++ b/drivers/mmc/host/sdhci-uhs2.c @@ -1295,6 +1295,9 @@ static int sdhci_uhs2_do_detect_init(struct mmc_host *mmc) DBG("Begin do uhs2 detect init.\n"); + 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 e16267f5a3c0..ec7e5d77a18a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -725,6 +725,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 Fri Mar 31 10:55:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77741 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479650vqo; Fri, 31 Mar 2023 04:10:35 -0700 (PDT) X-Google-Smtp-Source: AKy350aOrV6kiCtI00bTFfMctwXMLt48HhJIT64TyxngQ3EUY62wXfqX5RW9s2RfYefO+9JAuM+o X-Received: by 2002:a62:7b52:0:b0:622:8a8e:8cf8 with SMTP id w79-20020a627b52000000b006228a8e8cf8mr10319719pfc.14.1680261035300; Fri, 31 Mar 2023 04:10:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680261035; cv=none; d=google.com; s=arc-20160816; b=VaP+OHLoFGK7Vt4Ql2oU12prK0CiY6IbWvm6+SKkNmrIUoHb574lsi2eMAcgrp5m+S 8p52O6MLvk37tKzTj1Ffm5ocPyYyXvcK5gkAV4fqbQR5jimHF9FPkO8VdxIMEVUl5Lit AJ3jSVWBuCuB6A6ZQqyL71ADhTc93TBgsBNw82z2gMbofc99eQ9qgMRFVmdytUd36igP g8EuILY43bY8xCxvieHjX5OfqUkcvOfifnHe8wZx1rKZKzw88BqUCCqJzEAmME7ijTmu SH98Bwk9FAy1H3FsvzlVR/chc5QjnL+h+K6CL0j47PLpF4QttoUVlcGFVMGWzxNEYbGd z0pQ== 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=wYAJZrrmPDxkvadC2nk65J6PT+UmOKiqvEkS1eMtgqA=; b=RcgU6jdSUas10yeDCm4Jl9pmaJgjKLTkzlSWqNI1JUF757Ax7Ydtbf9cWTxJ/a2EfZ 8FOsH2VVZFiY49qS0wnbNbWLc3vVmBn0DSsqjXgopxCxrkH7bsIswiNXAmiYCvlsPEGp lHk8mNUXhx2NnlyVlbVSFUjTFORXIIyB0iYgWegyH9ze3MQPTYC6n4/mjw4Bj8XNK8HT o32aGGsUm/Mk+A0ysaDaChQ4+rOqYw0tzhYYoRSbc08IdF/503cGtAQui+LpffS9/jNl bFpLQ2WBdykokXWNrXZxxoP4PC5M5wN2TRcovNDfHIb6yg740i7WCREgvCkaZiMMugLW FAew== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b="p8gyTC/4"; 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 w71-20020a63824a000000b004dccf388f93si2188917pgd.522.2023.03.31.04.10.23; Fri, 31 Mar 2023 04:10:35 -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="p8gyTC/4"; 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 S231913AbjCaK73 (ORCPT + 99 others); Fri, 31 Mar 2023 06:59:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232017AbjCaK6o (ORCPT ); Fri, 31 Mar 2023 06:58:44 -0400 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 360FB1F792; Fri, 31 Mar 2023 03:57:06 -0700 (PDT) Received: by mail-pl1-x636.google.com with SMTP id n14so5007108plc.8; Fri, 31 Mar 2023 03:57:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260223; 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=wYAJZrrmPDxkvadC2nk65J6PT+UmOKiqvEkS1eMtgqA=; b=p8gyTC/4ugFMOo0es9UFLm2LbJvpmSnkrRAuPb5Gu8IefYRfrWJQgGu0PviEsO3Dx5 8RNScoffG6T+tISDt9fR1eMzmf9n3ru7lXh/f/665cXZbAGV9AkTgcA1dIBNfpP/aiCx c/KqhR/tAsusPhX2K8mgwJDu1OavdLUXRff0YiQKoB1LmAPoCrZIs/cLcwvZZwJWY16M LArPmICAxbGoXpAzFUVyDnYHH3HAsLHqHJbqbDRlMTl7atlFCKHChjNOXvt7QuLn+Ai7 FCNBZ1B1f78GFdaxz0x6tuTTf4nSMqtlPtcZHaBTeUaaqpidGKxnjqs52ptKUkvgBpqN NTSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260223; 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=wYAJZrrmPDxkvadC2nk65J6PT+UmOKiqvEkS1eMtgqA=; b=JVFLQ5BlegbYU9n1EUx34OKnb+f2McXi62FDj1mbSstGOX8f8xznF+fdXsrJeVraxg 7dsVddzNiYtRpxJudz6rvECbN0bpK1ZMeYWnqDLi4bnZxgNg5sPEQqkNkA+2Fp+bZiy7 S2tqIPTf7v5c2nLIoWpxZXGUidI6rmwovIgMK2ot4WeCYDaHLR6zpFxOCHeqFf2abnuh QFAhkIgFcjxyoxyyphSIsduQLabniDGylOMwQuU/3dC6Ia3wODIUG+iJzlIMgdGKgDvW x8wgeEhUE/IaroMedeE/nnFzZRoeFW/BKjUVSjAE73pw6gsxDIe4zq1X7+0gSal335XX 8g/Q== X-Gm-Message-State: AAQBX9f3cDabCoHUb+gyKQdG3CZfLplHEIIKTTix+uSAa3b9EDmOHqdJ dRI/whxg0ZkNeYbrF/jCZMo= X-Received: by 2002:a17:902:ce8e:b0:1a2:940c:e452 with SMTP id f14-20020a170902ce8e00b001a2940ce452mr4233954plg.9.1680260223728; Fri, 31 Mar 2023 03:57:03 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.57.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:57: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 V7 22/23] mmc: sdhci-pci: add UHS-II support framework Date: Fri, 31 Mar 2023 18:55:45 +0800 Message-Id: <20230331105546.13607-23-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881395087687548?= X-GMAIL-MSGID: =?utf-8?q?1761881395087687548?= 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 01975d145200..6b5109f7feef 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -40,6 +40,7 @@ #include "sdhci.h" #include "sdhci-cqhci.h" #include "sdhci-pci.h" +#include "sdhci-uhs2.h" static void sdhci_pci_hw_reset(struct sdhci_host *host); @@ -2155,7 +2156,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); @@ -2163,6 +2167,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 Fri Mar 31 10:55:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Shih X-Patchwork-Id: 77744 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp479753vqo; Fri, 31 Mar 2023 04:10:46 -0700 (PDT) X-Google-Smtp-Source: AK7set9S6kmxfcqznQSLVi45dwa/qLqQlNWyW6VAhI2hoVOXKfUmqWI7iJRckSfkoNQotzpzWb6s X-Received: by 2002:a05:6a20:8b26:b0:d8:d061:96ec with SMTP id l38-20020a056a208b2600b000d8d06196ecmr23012075pzh.27.1680261046582; Fri, 31 Mar 2023 04:10:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680261046; cv=none; d=google.com; s=arc-20160816; b=Jv/0UkS/THj+LAkCsKWe1557JusV5x7Gf0SZfXFLEsM/amzSWQ62BIxLlfM0WWUng+ IRa+XE06I+Y7rNVhHgrSrW2aT6rf82kom1QmWPj/ULPjvXRCwcwmjym9HOAyk4BuqaaZ j3N5Pd7JOclh1rHO+fovOAorcKKLmv/O3A6Z2UQfFDVU5oGP+2c/039hhJk0QQM649SL lt6Lnr8w0+aUiR32kotRc7P/4xj7B+54GtCnh1g/uMRWn2IjlMkXNfqIL/z6p82XWUbw KZgOHDlG+IZpNXOYM61eXlexPjv+DX+/uROsRUgOOC6r6maTvAPe4Z5Gp4fUO9fUfTgd vLaQ== 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=nNFBbkrxb1xRadz9HBDQES/8XThBIrrIswMwdN275hA=; b=XB7PoZpi2DMCBbJVz+vjZp8w1vqIF6WssblX7pteq4Vq9N/Z+PwM/9qyGIRXHwUECD 0Bzxtf40z5IyLmLnPZzg1FP2ntHrrjdmp1jhAmwZ3q3fycR+IGiKgS7fwcJb9AZY3lf8 yI65Qk1GEON2t/QtQE21pUgAGkc9M3tMM+Gr4bX6qpaCWhQLkXG6f53KlLYnvL4KhO4T fWbliN9IExM9odq2o94B/VDCvrfTUGWW3pSpe7nYq1xusgvmuVMu4ZInwYa0RHPNDpZw JR3O4+00mxoEoYZrr45tXu8nHPEgwFj0l5C6JSkS5QBOoDJl+f4Oqn6+2LJfbiO06NZ1 dsYA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=liKW0ism; 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 i191-20020a6387c8000000b0050fab1dcafesi2135397pge.109.2023.03.31.04.10.33; Fri, 31 Mar 2023 04:10:46 -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=liKW0ism; 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 S232035AbjCaK7d (ORCPT + 99 others); Fri, 31 Mar 2023 06:59:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231886AbjCaK6p (ORCPT ); Fri, 31 Mar 2023 06:58:45 -0400 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22B811DFA9; Fri, 31 Mar 2023 03:57:08 -0700 (PDT) Received: by mail-pj1-x1031.google.com with SMTP id o6-20020a17090a9f8600b0023f32869993so24979230pjp.1; Fri, 31 Mar 2023 03:57:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680260226; 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=nNFBbkrxb1xRadz9HBDQES/8XThBIrrIswMwdN275hA=; b=liKW0ismgHt9YlmndI5gPDI/VmyhKJb1UM9e8taWntj9w2KBSAp47cs5xIt7NzXg3Z JQXade6CIb8pla2H+MbowM2rbQpl0gvV/J+fOIjpKLUTSBJqRY7aYC0ecUkX1LRSAVD6 YYjeHpRVrDpoQQUGTNnAQnHuwZ/pSQVuYWIjIGe20WeSwduSP1Wnzewh1+qBQkdgj2GC N8MftNclP/PMbaw/FLuJt+66hVMVawPTHRVFMsbiLKqgm6WL6zbLEmEZEtGoQW88LbFI FjZUiwgewlLNTSnFB5UGyVvAVGjF7EXs8tfR9gGNhwdgQOcappg3m835n338AWFVcJnX uTyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680260226; 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=nNFBbkrxb1xRadz9HBDQES/8XThBIrrIswMwdN275hA=; b=HhOnNH8ghgnbzXPfyGFjJS4+TIq2bqh7NkWidqtRnWUiwMabyg2/irRm7N6LTvOD83 Sld9jZ15pPIBSPhJTiZyM6pMzdoe43nIsd9Xby5CKmAZ3zgZY5en6NO4RxdINwgx2da3 sw4KJhX+Rls0TI85kRaWedVXuMUI0g0GJrUmOPgqmfiYImp1xwhh2D5bCk+n/qaDr1Hr 8i5XaHIDwIgXiqxCTvriDJvK2iieyYowOQ20hZ3+cGrORHRCEPmuinySbJQjBLEXovb9 PRGMyJkraFvK8EraNnRhD7TVoti1CVGnfEYHz2PhzON1M282921a/2z3U0dMkHNZPyCx fqbw== X-Gm-Message-State: AAQBX9e41v5uNxvKiTkzGsMYko+w1RA67mXMHSgnXopKGOHYFNP+zL/Y IERM31NYpvBut2Uu/gbskwE= X-Received: by 2002:a17:902:da82:b0:1a1:a996:feb3 with SMTP id j2-20020a170902da8200b001a1a996feb3mr36052305plx.26.1680260226234; Fri, 31 Mar 2023 03:57:06 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e25c-983f-c7ff-3efd-77d9-6c16.emome-ip6.hinet.net. [2001:b400:e25c:983f:c7ff:3efd:77d9:6c16]) by smtp.gmail.com with ESMTPSA id f19-20020a170902e99300b0019acd3151d0sm1287665plb.114.2023.03.31.03.57.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Mar 2023 03:57: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 V7 23/23] mmc: sdhci-pci-gli: enable UHS-II mode for GL9755 Date: Fri, 31 Mar 2023 18:55:46 +0800 Message-Id: <20230331105546.13607-24-victor.shih@genesyslogic.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> References: <20230331105546.13607-1-victor.shih@genesyslogic.com.tw> MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on 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?1761881406897492142?= X-GMAIL-MSGID: =?utf-8?q?1761881406897492142?= Changes are: * Disable GL9755 overcurrent interrupt when power on/off on UHS-II. * Enable the internal clock when do reset on UHS-II mode. * 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 | 276 ++++++++++++++++++++++++++++++- 2 files changed, 276 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 06ab111eba3b..b89804d2da16 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -111,6 +111,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 633a8ee8f8c5..eedf6cd5c94a 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -18,6 +18,7 @@ #include "sdhci-cqhci.h" #include "sdhci-pci.h" #include "cqhci.h" +#include "sdhci-uhs2.h" /* Genesys Logic extra registers */ #define SDHCI_GLI_9750_WT 0x800 @@ -139,9 +140,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) @@ -693,6 +721,244 @@ 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_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_SD_TRAN) { + 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_INT_ERROR_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_ENABLE)) { + 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; @@ -713,6 +979,7 @@ static int gli_probe_slot_gl9755(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; } @@ -1085,17 +1352,24 @@ 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, + .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, }; 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,