From patchwork Wed Nov 23 01:09:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy McNicoll X-Patchwork-Id: 9442449 X-Patchwork-Delegate: agross@codeaurora.org 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 6B0CB6075D for ; Wed, 23 Nov 2016 01:18:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5BDB420499 for ; Wed, 23 Nov 2016 01:18:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 50990206AC; Wed, 23 Nov 2016 01:18:45 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable 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 D4B7620564 for ; Wed, 23 Nov 2016 01:18:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753586AbcKWBSn (ORCPT ); Tue, 22 Nov 2016 20:18:43 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44288 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751506AbcKWBSm (ORCPT ); Tue, 22 Nov 2016 20:18:42 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8BCC261BB0; Wed, 23 Nov 2016 01:10:01 +0000 (UTC) Received: from mini-rhel.redhat.com (ovpn-116-17.phx2.redhat.com [10.3.116.17]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uAN19s7e008042; Tue, 22 Nov 2016 20:10:00 -0500 From: Jeremy McNicoll To: linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, devicetree@vger.kernel.org, linux-mmc@vger.kernel.org Cc: andy.gross@linaro.org, sboyd@codeaurora.org, robh@kernel.org, arnd@arndb.de, bjorn.andersson@linaro.org, riteshh@codeaurora.org, jeremymc@redhat.com Subject: [PATCH 4/5] sdhci: dump vendor state and regs Date: Tue, 22 Nov 2016 17:09:47 -0800 Message-Id: <1479863388-23678-5-git-send-email-jeremymc@redhat.com> In-Reply-To: <1479863388-23678-1-git-send-email-jeremymc@redhat.com> References: <1479863388-23678-1-git-send-email-jeremymc@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 23 Nov 2016 01:10:01 +0000 (UTC) Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This has proven very useful in debugging SDHCI RPM interaction issues. Signed-off-by: Jeremy McNicoll --- drivers/mmc/host/sdhci-msm.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c | 25 ++++++++++++++ drivers/mmc/host/sdhci.h | 1 + 3 files changed, 105 insertions(+) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index ee01d95..1fcda96 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -678,6 +678,84 @@ static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host) return ret; } + + +#define MAX_TEST_BUS 20 +#define CORE_MCI_DATA_CNT 0x30 +#define CORE_MCI_FIFO_CNT 0x44 +#define CORE_MCI_STATUS 0x34 +#define CORE_VENDOR_SPEC_ADMA_ERR_ADDR0 0x114 +#define CORE_VENDOR_SPEC_ADMA_ERR_ADDR1 0x118 +#define CORE_TESTBUS_SEL2_BIT 4 +#define CORE_TESTBUS_SEL2 (1 << CORE_TESTBUS_SEL2_BIT) + +#define CORE_TESTBUS_ENA (1 << 3) + +#define CORE_TESTBUS_CONFIG 0x0CC + +#define CORE_SDCC_DEBUG_REG 0x124 + +void sdhci_msm_dump_vendor_regs(struct sdhci_host *host) +{ + + int tbsel, tbsel2; + int i, index = 0; + u32 test_bus_val = 0; + u32 debug_reg[MAX_TEST_BUS] = {0}; + struct sdhci_pltfm_host *pltfm_host; + struct sdhci_msm_host *msm_host; + + pltfm_host = sdhci_priv(host); + msm_host = sdhci_pltfm_priv(pltfm_host); + + pr_info("----------- VENDOR REGISTER DUMP -----------\n"); + pr_info("Data cnt: 0x%08x | Fifo cnt: 0x%08x | Int sts: 0x%08x\n", + readl_relaxed(msm_host->core_mem + CORE_MCI_DATA_CNT), + readl_relaxed(msm_host->core_mem + CORE_MCI_FIFO_CNT), + readl_relaxed(msm_host->core_mem + CORE_MCI_STATUS)); + pr_info("DLL cfg: 0x%08x | DLL sts: 0x%08x | SDCC ver: 0x%08x\n", + readl_relaxed(host->ioaddr + CORE_DLL_CONFIG), + readl_relaxed(host->ioaddr + CORE_DLL_STATUS), + readl_relaxed(msm_host->core_mem + CORE_MCI_VERSION)); + pr_info("Vndr func: 0x%08x | Vndr adma err : addr0: 0x%08x addr1: 0x%08x\n", + readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC), + readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_ADMA_ERR_ADDR0), + readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_ADMA_ERR_ADDR1)); + + /* + * tbsel indicates [2:0] bits and tbsel2 indicates [7:4] bits + * of CORE_TESTBUS_CONFIG register. + * + * To select test bus 0 to 7 use tbsel and to select any test bus + * above 7 use (tbsel2 | tbsel) to get the test bus number. For eg, + * to select test bus 14, write 0x1E to CORE_TESTBUS_CONFIG register + * i.e., tbsel2[7:4] = 0001, tbsel[2:0] = 110. + */ + for (tbsel2 = 0; tbsel2 < 3; tbsel2++) { + for (tbsel = 0; tbsel < 8; tbsel++) { + if (index >= MAX_TEST_BUS) + break; + test_bus_val = (tbsel2 << CORE_TESTBUS_SEL2_BIT) | + tbsel | CORE_TESTBUS_ENA; + writel_relaxed(test_bus_val, + msm_host->core_mem + CORE_TESTBUS_CONFIG); + debug_reg[index++] = readl_relaxed(msm_host->core_mem + + CORE_SDCC_DEBUG_REG); + } + } + + for (i = 0; i < MAX_TEST_BUS; i = i + 4) + pr_info(" Test bus[%d to %d]: 0x%08x 0x%08x 0x%08x 0x%08x\n", + i, i + 3, debug_reg[i], debug_reg[i+1], + debug_reg[i+2], debug_reg[i+3]); + /* Disable test bus */ + writel_relaxed(~CORE_TESTBUS_ENA, msm_host->core_mem + + CORE_TESTBUS_CONFIG); +} + + + + static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode) { int tuning_seq_cnt = 3; @@ -1081,6 +1159,7 @@ static const struct sdhci_ops sdhci_msm_ops = { .set_bus_width = sdhci_set_bus_width, .set_uhs_signaling = sdhci_msm_set_uhs_signaling, .voltage_switch = sdhci_msm_voltage_switch, + .dump_vendor_regs = sdhci_msm_dump_vendor_regs, }; static const struct sdhci_pltfm_data sdhci_msm_pdata = { diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 71654b9..5911f98 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -47,6 +47,27 @@ static void sdhci_finish_data(struct sdhci_host *); static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); +static void sdhci_dump_rpm_info(struct sdhci_host *host) +{ + struct mmc_host *mmc = host->mmc; + + pr_info("%s: rpmstatus[pltfm](runtime-suspend:usage_count:disable_depth)(%d:%d:%d)\n", + mmc_hostname(mmc), mmc->parent->power.runtime_status, + atomic_read(&mmc->parent->power.usage_count), + mmc->parent->power.disable_depth); +} + + +static void sdhci_dump_state(struct sdhci_host *host) +{ + struct mmc_host *mmc = host->mmc; + + pr_info("%s: clk: %d claimer: %s pwr: %d\n", + mmc_hostname(mmc), host->clock, + mmc->claimer->comm, host->pwr); + sdhci_dump_rpm_info(host); +} + static void sdhci_dumpregs(struct sdhci_host *host) { pr_err(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", @@ -100,6 +121,10 @@ static void sdhci_dumpregs(struct sdhci_host *host) readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); } + if (host->ops->dump_vendor_regs) + host->ops->dump_vendor_regs(host); + + sdhci_dump_state(host); pr_err(DRIVER_NAME ": ===========================================\n"); } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 766df17..c055e24 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -563,6 +563,7 @@ struct sdhci_ops { struct mmc_card *card, unsigned int max_dtr, int host_drv, int card_drv, int *drv_type); + void (*dump_vendor_regs)(struct sdhci_host *host); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS