Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp1696673rwd; Fri, 9 Jun 2023 00:22:57 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5Ewt1w14K4b/ZR8v43rJ3A+o2fZw8MZoxCjyaUV0v+sv6Ts/E+I1DJl9X86yc38W0Ie8OK X-Received: by 2002:a05:6a21:78b:b0:103:7b89:d70a with SMTP id mg11-20020a056a21078b00b001037b89d70amr298496pzb.54.1686295377742; Fri, 09 Jun 2023 00:22:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686295377; cv=none; d=google.com; s=arc-20160816; b=tHqP02LKpBDKWB9ioXd2A8Z2Zm5Sz+cotHWmj48HwWxHgGofaHsMy/hKEq6iQcgeQH qzLKJZSATmcoqpR0b7cVqVz4XBHR/ukIl2ip4741WC7JctmOBxp1ViooElxMPvHi1MV2 BjTtrOxK1d2JxBnKZooAz+tgvyxyqGIlcvHPNgLw1DHKMNBol/dh2jTbh8GUe08NVqPt AAHwpBf96LMKEHqlj6hvGgiUTN9Y8YxlumICt+IxozCVHNGX7uBIv9msxVGxXWPQZbnG Oe7QHgjdzz2fttLKRkeKKf9cEy/qfUYrkieH1ibyRgvTgbk99KX4PZmYhsZ8loWqaug8 EARg== 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=KT0A5bV8ZYXawSlOJrCHBHsTa040z+BQD92gFxV4MLs=; b=FoWnn57f/OqH9CbHAZrGj63AJNs+og+w2/VA70xG05c/AWn/AcrRljPRw9YlWfbHql 5NeRVata8RyDMdD3siJUWo/6PBCkbFaqaWiMMEyhBxM74hHk5cA13h0mdn+Jzmf9+/zI Q7otdxp88rWC4pY4a7rFrhDPsQSPqxJFgEoX58u7YCaix53bID9WXM8fgppJ/CIj/S7T bPv3LcEYoP9TUOGGgzgLkTcDkZKxENuoYrHLdmUlT12JTkX5oA/a2PFApNvLMMPF648o klwTPdtK+wbcPbXx11YpAPdfhkdgae+c8HQmGQ0LEWFIu4v/t1vbjr+ZWkxnoZW0kW5A EwMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b="f+Gzb/O9"; 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 Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e7-20020aa798c7000000b006630be2db05si2080315pfm.182.2023.06.09.00.22.46; Fri, 09 Jun 2023 00:22:57 -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=20221208 header.b="f+Gzb/O9"; 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 S230344AbjFIHPO (ORCPT + 99 others); Fri, 9 Jun 2023 03:15:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236735AbjFIHO7 (ORCPT ); Fri, 9 Jun 2023 03:14:59 -0400 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5FEE8272A; Fri, 9 Jun 2023 00:14:58 -0700 (PDT) Received: by mail-pf1-x42e.google.com with SMTP id d2e1a72fcca58-652328c18d5so1114555b3a.1; Fri, 09 Jun 2023 00:14:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1686294898; x=1688886898; 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=KT0A5bV8ZYXawSlOJrCHBHsTa040z+BQD92gFxV4MLs=; b=f+Gzb/O9ONy4V3craqn1xqfoBmwxFm/9/D8pFW113pDkD7+cFd2oYAxzmAupiz1qdz DTGPcOgLTq/Z5YLHjFiNWjeMwz9HLYuG3Bo5+N3zxJhbEXKwmAvz3bhFI4Qfi1BrvzKP gzjqWSCMyQ1PC2vjjYhKlqmJaDnH3JifqBPXAPmzu/ZBzLgr5JiNAiAHfxXTExM+Uelz B62I//NCXnyKlZcKQhwM+bsxp37yB9BX6uIk/n6af1oNBHoN+7CTj8rtnci5hoNLjYW/ XzkyueDiasEz+Os0EPkN2dVHIUhNmEhm78n160/mvjatDWdX9VY2h+ob85ERF3Pt+S83 6cYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686294898; x=1688886898; 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=KT0A5bV8ZYXawSlOJrCHBHsTa040z+BQD92gFxV4MLs=; b=dtNl1UfKCgRFNEchPvkICs1bEKyVD7ge0JG8kzeWIqrMe2GHpu86Iswv+iv/MYYqYm rCPPb22fNNF6syEnsAabqq3n8S9tEreHroSIl+6qmEOJE/43U8Ve4A/oJ3gmOF7OtQeN 4PiSbhx8xjwLrHAXOT64VUmCEfJsXngDECe13zf6G6T5GDfp3W2tQMyk4ceqwTAF2jxA cVRZ87+imhhCgZiZ3zYoUKULwcDEfmnXDJ/YNn6AmEnNt5S9vwTVMWBY8mSs7T1+bfme fS+DcCG/BNnVxCAfXoDUQtoXE2KpLZOb22n4Kr7Ai+DPso3bF/8hkgLD7AKKjMGL2yc3 k0qQ== X-Gm-Message-State: AC+VfDw9m/OeuIsiS6/BCpZPkjHmiLPo5JFpNFUIkDXB2EImv4gdchYL YX40/aXfBKtXsK9YQ2RbhyM= X-Received: by 2002:a05:6a21:170e:b0:112:bdd3:9b81 with SMTP id nv14-20020a056a21170e00b00112bdd39b81mr329825pzb.15.1686294897666; Fri, 09 Jun 2023 00:14:57 -0700 (PDT) Received: from localhost.localdomain (2001-b400-e282-07a7-2523-0b40-49e4-7cbb.emome-ip6.hinet.net. [2001:b400:e282:7a7:2523:b40:49e4:7cbb]) by smtp.gmail.com with ESMTPSA id f3-20020a656283000000b005308b255502sm2085196pgv.68.2023.06.09.00.14.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Jun 2023 00:14:57 -0700 (PDT) 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, Victor Shih , Ben Chuang , Victor Shih Subject: [PATCH V6 4/4] mmc: sdhci-pci-gli: Add support SD Express card for GL9767 Date: Fri, 9 Jun 2023 15:14:41 +0800 Message-Id: <20230609071441.451464-5-victorshihgli@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230609071441.451464-1-victorshihgli@gmail.com> References: <20230609071441.451464-1-victorshihgli@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Victor Shih Add support SD Express card for GL9767. The workflow of the SD Express card in GL9767 is as below. 1. GL9767 operates in SD mode and set MMC_CAP2_SD_EXP flag. 2. If card is inserted, Host send CMD8 to ask the capabilities of the card. 3. If the card has PCIe capability, then init_sd_express() will be invoked. 4. If the card has been put in write protect state then the SD features supported by SD mode but not supported by PCIe mode, therefore GL9767 switch to SD mode. 5. If the card has not been put in write protect state then GL9767 switch from SD mode to PCIe/NVMe mode and mmc driver handover control to NVMe driver. 6. If card is removed, GL9767 will return to SD mode. Signed-off-by: Ben Chuang Signed-off-by: Victor Shih Acked-by: Adrian Hunter --- drivers/mmc/host/sdhci-pci-gli.c | 113 +++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index 7a5ebd0fefe7..ae8c307b7aa7 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -164,6 +164,10 @@ #define PCIE_GLI_9767_CFG 0x8A0 #define PCIE_GLI_9767_CFG_LOW_PWR_OFF BIT(12) +#define PCIE_GLI_9767_COMBO_MUX_CTL 0x8C8 +#define PCIE_GLI_9767_COMBO_MUX_CTL_RST_EN BIT(6) +#define PCIE_GLI_9767_COMBO_MUX_CTL_WAIT_PERST_EN BIT(10) + #define PCIE_GLI_9767_PWR_MACRO_CTL 0x8D0 #define PCIE_GLI_9767_PWR_MACRO_CTL_LOW_VOLTAGE GENMASK(3, 0) #define PCIE_GLI_9767_PWR_MACRO_CTL_LD0_LOW_OUTPUT_VOLTAGE GENMASK(15, 12) @@ -181,6 +185,9 @@ #define PCIE_GLI_9767_SCR_CORE_PWR_D3_OFF BIT(21) #define PCIE_GLI_9767_SCR_CFG_RST_DATA_LINK_DOWN BIT(30) +#define PCIE_GLI_9767_SDHC_CAP 0x91C +#define PCIE_GLI_9767_SDHC_CAP_SDEI_RESULT BIT(5) + #define PCIE_GLI_9767_SD_PLL_CTL 0x938 #define PCIE_GLI_9767_SD_PLL_CTL_PLL_LDIV GENMASK(9, 0) #define PCIE_GLI_9767_SD_PLL_CTL_PLL_PDIV GENMASK(15, 12) @@ -191,6 +198,23 @@ #define PCIE_GLI_9767_SD_PLL_CTL2 0x93C #define PCIE_GLI_9767_SD_PLL_CTL2_PLLSSC_PPM GENMASK(31, 16) +#define PCIE_GLI_9767_SD_EXPRESS_CTL 0x940 +#define PCIE_GLI_9767_SD_EXPRESS_CTL_SDEI_EXE BIT(0) +#define PCIE_GLI_9767_SD_EXPRESS_CTL_SD_EXPRESS_MODE BIT(1) + +#define PCIE_GLI_9767_SD_DATA_MULTI_CTL 0x944 +#define PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME GENMASK(23, 16) +#define PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME_VALUE 0x64 + +#define PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2 0x950 +#define PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2_SDEI_COMPLETE BIT(0) + +#define PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2 0x954 +#define PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2_SDEI_COMPLETE_STATUS_EN BIT(0) + +#define PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2 0x958 +#define PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2_SDEI_COMPLETE_SIGNAL_EN BIT(0) + #define GLI_MAX_TUNING_LOOP 40 /* Genesys Logic chipset */ @@ -935,6 +959,93 @@ static void sdhci_gl9767_reset(struct sdhci_host *host, u8 mask) gli_set_9767(host); } +static int gl9767_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + struct sdhci_pci_slot *slot = sdhci_priv(host); + struct pci_dev *pdev; + u32 value; + int i; + + pdev = slot->chip->pdev; + + if (mmc->ops->get_ro(mmc)) { + mmc->ios.timing &= ~(MMC_TIMING_SD_EXP | MMC_TIMING_SD_EXP_1_2V); + return 0; + } + + gl9767_vhs_write(pdev); + + pci_read_config_dword(pdev, PCIE_GLI_9767_COMBO_MUX_CTL, &value); + value &= ~(PCIE_GLI_9767_COMBO_MUX_CTL_RST_EN | PCIE_GLI_9767_COMBO_MUX_CTL_WAIT_PERST_EN); + pci_write_config_dword(pdev, PCIE_GLI_9767_COMBO_MUX_CTL, value); + + pci_read_config_dword(pdev, PCIE_GLI_9767_SD_DATA_MULTI_CTL, &value); + value &= ~PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME; + value |= FIELD_PREP(PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME, + PCIE_GLI_9767_SD_DATA_MULTI_CTL_DISCONNECT_TIME_VALUE); + pci_write_config_dword(pdev, PCIE_GLI_9767_SD_DATA_MULTI_CTL, value); + + pci_read_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2, &value); + value |= PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2_SDEI_COMPLETE; + pci_write_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2, value); + + pci_read_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2, &value); + value |= PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2_SDEI_COMPLETE_STATUS_EN; + pci_write_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_EN_REG2, value); + + pci_read_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2, &value); + value |= PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2_SDEI_COMPLETE_SIGNAL_EN; + pci_write_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_SIGNAL_EN_REG2, value); + + pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value); + value |= PCIE_GLI_9767_CFG_LOW_PWR_OFF; + pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value); + + value = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + value &= ~(SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_PLL_EN); + sdhci_writew(host, value, SDHCI_CLOCK_CONTROL); + + value = sdhci_readb(host, SDHCI_POWER_CONTROL); + value |= (SDHCI_VDD2_POWER_180 | SDHCI_VDD2_POWER_ON); + sdhci_writeb(host, value, SDHCI_POWER_CONTROL); + + pci_read_config_dword(pdev, PCIE_GLI_9767_SD_EXPRESS_CTL, &value); + value |= PCIE_GLI_9767_SD_EXPRESS_CTL_SDEI_EXE; + pci_write_config_dword(pdev, PCIE_GLI_9767_SD_EXPRESS_CTL, value); + + for (i = 0; i < 2; i++) { + usleep_range(10000, 10100); + pci_read_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2, &value); + if (value & PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2_SDEI_COMPLETE) { + pci_write_config_dword(pdev, PCIE_GLI_9767_NORMAL_ERR_INT_STATUS_REG2, + value); + break; + } + } + + pci_read_config_dword(pdev, PCIE_GLI_9767_SDHC_CAP, &value); + if (value & PCIE_GLI_9767_SDHC_CAP_SDEI_RESULT) { + pci_read_config_dword(pdev, PCIE_GLI_9767_SD_EXPRESS_CTL, &value); + value |= PCIE_GLI_9767_SD_EXPRESS_CTL_SD_EXPRESS_MODE; + pci_write_config_dword(pdev, PCIE_GLI_9767_SD_EXPRESS_CTL, value); + } else { + mmc->ios.timing &= ~(MMC_TIMING_SD_EXP | MMC_TIMING_SD_EXP_1_2V); + + value = sdhci_readb(host, SDHCI_POWER_CONTROL); + value &= ~(SDHCI_VDD2_POWER_180 | SDHCI_VDD2_POWER_ON); + sdhci_writeb(host, value, SDHCI_POWER_CONTROL); + + value = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + value |= (SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_PLL_EN); + sdhci_writew(host, value, SDHCI_CLOCK_CONTROL); + } + + gl9767_vhs_read(pdev); + + return 0; +} + static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot) { struct sdhci_host *host = slot->host; @@ -967,6 +1078,8 @@ static int gli_probe_slot_gl9767(struct sdhci_pci_slot *slot) gl9767_hw_setting(slot); gli_pcie_enable_msi(slot); slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; + host->mmc->caps2 |= MMC_CAP2_SD_EXP; + host->mmc_host_ops.init_sd_express = gl9767_init_sd_express; sdhci_enable_v4_mode(host); return 0; -- 2.25.1