From patchwork Mon Mar 20 17:50:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Hunter X-Patchwork-Id: 9635145 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 02D506020B for ; Mon, 20 Mar 2017 18:38:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ED00325D99 for ; Mon, 20 Mar 2017 18:38:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E17BB26530; Mon, 20 Mar 2017 18:38:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 734EC25D99 for ; Mon, 20 Mar 2017 18:38:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932317AbdCTSfG (ORCPT ); Mon, 20 Mar 2017 14:35:06 -0400 Received: from mga01.intel.com ([192.55.52.88]:29206 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756042AbdCTR6N (ORCPT ); Mon, 20 Mar 2017 13:58:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=intel.com; i=@intel.com; q=dns/txt; s=intel; t=1490032692; x=1521568692; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=evQHJxwc5pAcqyN7BmgS1lUVqLbjYhpnpFMV2vl9eIM=; b=p/YpXI5GmoNbuGIeD7R65dC+HegVX0O+Dr3LrvydmbAdL2/KBsnNbnHH 5n42Mbv8Q4QeVoNIexi/Q8NNf4GHsQ==; Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Mar 2017 10:56:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,195,1486454400"; d="scan'208";a="1124975170" Received: from ahunter-desktop.fi.intel.com ([10.237.72.168]) by fmsmga001.fm.intel.com with ESMTP; 20 Mar 2017 10:56:54 -0700 From: Adrian Hunter To: Ulf Hansson Cc: linux-mmc , Al Cooper , Jaedon Shin , Haibo Chen , Dong Aisheng , Shawn Lin , Douglas Anderson , Zach Brown , Ludovic Desroches , Jisheng Zhang , Yangbo Lu , Jaehoon Chung , Weijun Yang , Barry Song , Peter Griffin , Lee Jones , Jon Hunter , Harjani Ritesh Subject: [PATCH 06/25] mmc: sdhci-pci: Don't re-tune with runtime pm for some Intel devices Date: Mon, 20 Mar 2017 19:50:34 +0200 Message-Id: <1490032253-6030-7-git-send-email-adrian.hunter@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490032253-6030-1-git-send-email-adrian.hunter@intel.com> References: <1490032253-6030-1-git-send-email-adrian.hunter@intel.com> Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Make use of an Intel ACPI _DSM that indicates if re-tuning is needed after D3. Signed-off-by: Adrian Hunter --- drivers/mmc/host/sdhci-pci-core.c | 90 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 84b73cb22940..3564327c9c7b 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -259,6 +259,77 @@ static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot) .probe_slot = pch_hc_probe_slot, }; +enum { + INTEL_DSM_FNS = 0, + INTEL_DSM_D3_RETUNE = 10, +}; + +struct intel_host { + u32 dsm_fns; + bool d3_retune; +}; + +const u8 intel_dsm_uuid[] = { + 0xA5, 0x3E, 0xC1, 0xF6, 0xCD, 0x65, 0x1F, 0x46, + 0xAB, 0x7A, 0x29, 0xF7, 0xE8, 0xD5, 0xBD, 0x61, +}; + +static int __intel_dsm(struct intel_host *intel_host, struct device *dev, + unsigned int fn, u32 *result) +{ + union acpi_object *obj; + int err = 0; + + obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), intel_dsm_uuid, 0, fn, NULL); + if (!obj) + return -EOPNOTSUPP; + + if (obj->type != ACPI_TYPE_BUFFER || obj->buffer.length < 1) { + err = -EINVAL; + goto out; + } + + if (obj->buffer.length >= 4) + *result = *(u32 *)obj->buffer.pointer; + else if (obj->buffer.length >= 2) + *result = *(u16 *)obj->buffer.pointer; + else + *result = *(u8 *)obj->buffer.pointer; +out: + ACPI_FREE(obj); + + return err; +} + +static int intel_dsm(struct intel_host *intel_host, struct device *dev, + unsigned int fn, u32 *result) +{ + if (fn > 31 || !(intel_host->dsm_fns & (1 << fn))) + return -EOPNOTSUPP; + + return __intel_dsm(intel_host, dev, fn, result); +} + +static void intel_dsm_init(struct intel_host *intel_host, struct device *dev, + struct mmc_host *mmc) +{ + int err; + u32 val; + + err = __intel_dsm(intel_host, dev, INTEL_DSM_FNS, &intel_host->dsm_fns); + if (err) { + pr_debug("%s: DSM not supported, error %d\n", + mmc_hostname(mmc), err); + return; + } + + pr_debug("%s: DSM function mask %#x\n", + mmc_hostname(mmc), intel_host->dsm_fns); + + err = intel_dsm(intel_host, dev, INTEL_DSM_D3_RETUNE, &val); + intel_host->d3_retune = err ? true : !!val; +} + static void sdhci_pci_int_hw_reset(struct sdhci_host *host) { u8 reg; @@ -359,8 +430,19 @@ static int bxt_get_cd(struct mmc_host *mmc) return ret; } +static void byt_read_dsm(struct sdhci_pci_slot *slot) +{ + struct intel_host *intel_host = sdhci_pci_priv(slot); + struct device *dev = &slot->chip->pdev->dev; + struct mmc_host *mmc = slot->host->mmc; + + intel_dsm_init(intel_host, dev, mmc); + slot->chip->rpm_retune = intel_host->d3_retune; +} + static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) { + byt_read_dsm(slot); slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR | MMC_CAP_CMD_DURING_TFR | @@ -405,6 +487,8 @@ static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot) { int err; + byt_read_dsm(slot); + err = ni_set_max_freq(slot); if (err) return err; @@ -416,6 +500,7 @@ static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot) static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot) { + byt_read_dsm(slot); slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE | MMC_CAP_WAIT_WHILE_BUSY; return 0; @@ -423,6 +508,7 @@ static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot) static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) { + byt_read_dsm(slot); slot->host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; slot->cd_idx = 0; slot->cd_override_level = true; @@ -488,6 +574,7 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode, SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 | SDHCI_QUIRK2_STOP_WITH_TC, .ops = &sdhci_intel_byt_ops, + .priv_size = sizeof(struct intel_host), }; static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = { @@ -497,6 +584,7 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode, .allow_runtime_pm = true, .probe_slot = ni_byt_sdio_probe_slot, .ops = &sdhci_intel_byt_ops, + .priv_size = sizeof(struct intel_host), }; static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { @@ -506,6 +594,7 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode, .allow_runtime_pm = true, .probe_slot = byt_sdio_probe_slot, .ops = &sdhci_intel_byt_ops, + .priv_size = sizeof(struct intel_host), }; static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { @@ -517,6 +606,7 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode, .own_cd_for_runtime_pm = true, .probe_slot = byt_sd_probe_slot, .ops = &sdhci_intel_byt_ops, + .priv_size = sizeof(struct intel_host), }; /* Define Host controllers for Intel Merrifield platform */