From patchwork Tue Aug 20 02:06:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Chuang X-Patchwork-Id: 11102599 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CF90D13A0 for ; Tue, 20 Aug 2019 02:06:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AE73120644 for ; Tue, 20 Aug 2019 02:06:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OC/eQ7/d" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728975AbfHTCGO (ORCPT ); Mon, 19 Aug 2019 22:06:14 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:36236 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728615AbfHTCGN (ORCPT ); Mon, 19 Aug 2019 22:06:13 -0400 Received: by mail-pg1-f194.google.com with SMTP id l21so2258911pgm.3; Mon, 19 Aug 2019 19:06:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=1o9lF1pZgVHiLgtSbSIAOz8s4TWZAVFJmsuylkZmIys=; b=OC/eQ7/dbTmz3BtsWPFojIj5Wf/sTMjmzwg66TGiPcP0AAH8kdRZzff2jaszNT6Pwj 6ohqUXscE/Mw/emlYVQZtwe3BzPDNPqXidoG26mbVci9NfS8ux29dGpRLDV5kOXS1v3Y EUojKDRWeqm0QX8ZveeVoMw4ShXb+Jk1zKBgzbqYGv4G5prbbLYeXnls2+SJxA5bql/0 6HlzcKHcnH5EGKjVHcc0s2aRC0fEttukhfzuteD6nliJ8X/yIfo7vYr1SyPWOqgpjqOA TTjPaRkjqUkS9z88iXTfc+p4ToU/8Gh17S5rUtNUezE1uirAnMBFeSP7xAhghQPoUUge z+Rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=1o9lF1pZgVHiLgtSbSIAOz8s4TWZAVFJmsuylkZmIys=; b=oJYCAKMtkEsO00ehpwSkQ2AF5ThXwWWJy71wTh8g0Brp29Ia22D0eB+wOVTbR2C6nz j2gsGjETkBYp/9FEs29zDsz9IFziy4TPopZ3baK3y9s8Wz1HpkmIpfikQMDBP9EBowBa CIt+/OOX30R2t2sCkVHbEWkhiNRVMurWogMkj3AiI/S7y5E332/exnsjczgjEm/UgCa3 /5eOrCI/IXFfKpNxJj98YIkr33tFHNSJCmnYh6kuWUhFV0QmTXxXPBVFpWa2DDTVECtk YJje0x+T/QdswEoHxwO+jRNX2E7wJ5oVssdjiOBM6uvDxSsb76+w83fPk2gZabRT9Aoq wIQg== X-Gm-Message-State: APjAAAXIaal9QOKCNPgKY8urfFofj0qBNVHuXhQXOg3VoDYuP1dulR5q TEYxNdXPzofLV6bvErwolwA= X-Google-Smtp-Source: APXvYqyykwzgbtYITvsNiwihk/cs7KMBXEnWh3nQqqaON4gG9KbVfHrbynhg6lI6HessGHtkd/3TcQ== X-Received: by 2002:a17:90a:bc4b:: with SMTP id t11mr24221494pjv.87.1566266773272; Mon, 19 Aug 2019 19:06:13 -0700 (PDT) Received: from gli-arch.genesyslogic.com.tw (60-251-58-169.HINET-IP.hinet.net. [60.251.58.169]) by smtp.gmail.com with ESMTPSA id b136sm21570693pfb.73.2019.08.19.19.06.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2019 19:06:12 -0700 (PDT) From: Ben Chuang To: adrian.hunter@intel.com, ulf.hansson@linaro.org Cc: linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, johnsonm@danlj.org, ben.chuang@genesyslogic.com.tw, Ben Chuang Subject: [PATCH V5 1/4] mmc: sdhci: Change timeout of loop for checking internal clock stable Date: Tue, 20 Aug 2019 10:06:25 +0800 Message-Id: <20190820020625.8230-1-benchuanggli@gmail.com> X-Mailer: git-send-email 2.22.1 MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Ben Chuang According to section 3.2.1 internal clock setup in SD Host Controller Simplified Specifications 4.20, the timeout of loop for checking internal clock stable is defined as 150ms. Signed-off-by: Ben Chuang Co-developed-by: Michael K Johnson Signed-off-by: Michael K Johnson Acked-by: Adrian Hunter --- drivers/mmc/host/sdhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 59acf8e3331e..bed0760a6c2a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1636,8 +1636,8 @@ void sdhci_enable_clk(struct sdhci_host *host, u16 clk) clk |= SDHCI_CLOCK_INT_EN; sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); - /* Wait max 20 ms */ - timeout = ktime_add_ms(ktime_get(), 20); + /* Wait max 150 ms */ + timeout = ktime_add_ms(ktime_get(), 150); while (1) { bool timedout = ktime_after(ktime_get(), timeout); From patchwork Tue Aug 20 02:06:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Chuang X-Patchwork-Id: 11102601 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CFA5D112C for ; Tue, 20 Aug 2019 02:06:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AD89F22CEC for ; Tue, 20 Aug 2019 02:06:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="q2mF/Qkz" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728999AbfHTCG1 (ORCPT ); Mon, 19 Aug 2019 22:06:27 -0400 Received: from mail-pl1-f194.google.com ([209.85.214.194]:35156 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728615AbfHTCG0 (ORCPT ); Mon, 19 Aug 2019 22:06:26 -0400 Received: by mail-pl1-f194.google.com with SMTP id gn20so1892384plb.2; Mon, 19 Aug 2019 19:06:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=yVYu9hmEdA0HGmWZ5vmto49b1VgMTPaD/kMUSIHjxzo=; b=q2mF/Qkz0j9/DhdmrAsPYXps1ET9UZ0HRCaz/e1ehZWkt1yimeXTHTZMW/JvDsomkg hBNwMIG15fkyNpzTNxICvKekLlbujUjDpa/tEJoLKykQ8N9s+C9JSz1fM3MIBmB9PRwQ t+E/GTCRlM04Ggq3o0udwfS1cJL7S6LlP6FRbe75Qi+Wfb/VzVcmRnONUJj7LMWorUTi eQamt0PgCWO9LUrlEsn4x56Sx0n64vb3e0pT7SBM3efWj/8YBY/l75Vg9Vqx20ndXDQX euHf9qVZxT3v30yRkipEckFUQB/JVVRDL43dOYfS1JWD6HGHi8QlAkuSMLuUKCX9R8AO GLQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=yVYu9hmEdA0HGmWZ5vmto49b1VgMTPaD/kMUSIHjxzo=; b=uFBNqQkb15ao/0mSOOyCTX40kY7hdoXxVrSOMIRHO3nTZbBgihzCLd9+OxeZ+iwYTl qzE6Jad2b1xf3KMhIkNXkLvBUz5v8+/yR7YxQfiXXoQQ0a2RVB8g0fgpIpm3wjEERMu2 T+bGktOUJQS61mpByp/ld4t0BOJ/kdQaBOuzmz7TVnMv7QmIvKvyRBhw1ZcNLpdb3qi4 wd5C17UjeYX9UIpkH143oD1ry3LR3gRD9pOI6EuwV+S3DiKY7mEgX8Ic1xOYzvEJa1YF 1U02XpQDIq5ShfO+5Ls8CsL7BvqWCq/N7M1wQ/9WkU2jmoFNYRF9ndbcnreHzN+ohFtZ HILQ== X-Gm-Message-State: APjAAAXUiLVZewr5HDpvrR336dDvN8ya7qsztWolWDD2tmGxGMJhqRCy 7d0jtelmpWV0TSzC6UajJjs= X-Google-Smtp-Source: APXvYqy0Vi/I3kVS6yTtR5WbhIHGAZWn4pLYpBmipdo/UUlxnWlwHp7czXSEqWeeMvvpnPEEcsbIdw== X-Received: by 2002:a17:902:1c7:: with SMTP id b65mr20001249plb.313.1566266786276; Mon, 19 Aug 2019 19:06:26 -0700 (PDT) Received: from gli-arch.genesyslogic.com.tw (60-251-58-169.HINET-IP.hinet.net. [60.251.58.169]) by smtp.gmail.com with ESMTPSA id h195sm24166137pfe.20.2019.08.19.19.06.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2019 19:06:25 -0700 (PDT) From: Ben Chuang To: adrian.hunter@intel.com, ulf.hansson@linaro.org Cc: linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, johnsonm@danlj.org, ben.chuang@genesyslogic.com.tw, Ben Chuang Subject: [PATCH V5 2/4] mmc: sdhci: Add PLL Enable support to internal clock setup Date: Tue, 20 Aug 2019 10:06:36 +0800 Message-Id: <20190820020636.8279-1-benchuanggli@gmail.com> X-Mailer: git-send-email 2.22.1 MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Ben Chuang The GL9750 and GL9755 chipsets, and possibly others, require PLL Enable setup as part of the internal clock setup as described in 3.2.1 Internal Clock Setup Sequence of SD Host Controller Simplified Specification Version 4.20. Signed-off-by: Ben Chuang Co-developed-by: Michael K Johnson Signed-off-by: Michael K Johnson Acked-by: Adrian Hunter --- drivers/mmc/host/sdhci.c | 23 +++++++++++++++++++++++ drivers/mmc/host/sdhci.h | 1 + 2 files changed, 24 insertions(+) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index bed0760a6c2a..9106ebc7a422 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1653,6 +1653,29 @@ void sdhci_enable_clk(struct sdhci_host *host, u16 clk) udelay(10); } + if (host->version >= SDHCI_SPEC_410 && host->v4_mode) { + clk |= SDHCI_CLOCK_PLL_EN; + clk &= ~SDHCI_CLOCK_INT_STABLE; + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + + /* Wait max 150 ms */ + timeout = ktime_add_ms(ktime_get(), 150); + 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: PLL clock never stabilised.\n", + mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + return; + } + udelay(10); + } + } + clk |= SDHCI_CLOCK_CARD_EN; sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 199712e7adbb..72601a4d2e95 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -114,6 +114,7 @@ #define SDHCI_DIV_HI_MASK 0x300 #define SDHCI_PROG_CLOCK_MODE 0x0020 #define SDHCI_CLOCK_CARD_EN 0x0004 +#define SDHCI_CLOCK_PLL_EN 0x0008 #define SDHCI_CLOCK_INT_STABLE 0x0002 #define SDHCI_CLOCK_INT_EN 0x0001 From patchwork Tue Aug 20 02:06:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Chuang X-Patchwork-Id: 11102603 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE7F613A0 for ; Tue, 20 Aug 2019 02:06:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AD79A214DA for ; Tue, 20 Aug 2019 02:06:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="r8QiVoBH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728627AbfHTCGz (ORCPT ); Mon, 19 Aug 2019 22:06:55 -0400 Received: from mail-pg1-f193.google.com ([209.85.215.193]:46304 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728615AbfHTCGy (ORCPT ); Mon, 19 Aug 2019 22:06:54 -0400 Received: by mail-pg1-f193.google.com with SMTP id m3so2241254pgv.13; Mon, 19 Aug 2019 19:06:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Gb4MN7frN2DQp05jBufAle0GF3E07hH+QYiE3G5P4OY=; b=r8QiVoBHXwhQTbODuclPFhZFepgsrvEkLetpZftMq0499yrWHA2di7DfMz4Nfqg308 zbP0qfQD46Q1Vsjq/piuESya0/gUnykSMHZ9qOg0Cx6saAUHlWBT1u6A3mM0omHoUfaU Tr19s+dkHUJe6x1vi6z8dxoat2qCd88r9weeMCO7u4CyGaUnie6s524wtOinYgtih37U Eh5prRmhFGg827hy9X54TqPc86SsQwcB1P5tpVRVdk8pC9ayVTpxJKT7j+D4ZJ1a1W2h Y2Gbs8teS/Bqss02fVUJKnMGR5eTh4QXv/lYfUYUD8Zqs+VnOLSjNiy12Ys3JRBv6dBo DZ9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Gb4MN7frN2DQp05jBufAle0GF3E07hH+QYiE3G5P4OY=; b=LkaqlkChsuQdhjOCD15G1Co49U81MWS2ilZf2TnsuO+RaCUKdflDvrfpJA8g+vyDID /W5Mjmo8yJjYN98bZAaG6mTNOLvYF/WLLTq7KL58SAuuLKWFqJY3VwSGbq4JD3rhJoAA SWZLTgHAlYV5MhuZtbKxdLTXEJNVENvcKnN2ICcP3Xolg0Ot3GEoWIExzBBQ+b3l1lZe YmnugOgnqcwRvb76qVYDn9Vx0w8AGhLG0nPrYHq/0xd6XtUV9AQLloZufatVs62ftwt/ 61Pa2/UE4TBxUdlc2HkD97ejUynLIO1v2DTJGiapbJMlU/YCpCv+oLSLU8K4CUJ0aY6W yELQ== X-Gm-Message-State: APjAAAULbStPc+64ZeSJKkifiWVrNNzTPLjHJuFgm3IILfq8Ks0S2GqB EuJpFahbjggg7jhkj8/e7Eg= X-Google-Smtp-Source: APXvYqwxhXwoCjQtiTGscKrLHWs+YJ8m2dCq7BSnFMzAIXIDoBJNk36iUImwwmY+NLYF/Th8g5BAJg== X-Received: by 2002:a63:7b4d:: with SMTP id k13mr22102292pgn.182.1566266814096; Mon, 19 Aug 2019 19:06:54 -0700 (PDT) Received: from gli-arch.genesyslogic.com.tw (60-251-58-169.HINET-IP.hinet.net. [60.251.58.169]) by smtp.gmail.com with ESMTPSA id y14sm32343959pfq.85.2019.08.19.19.06.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2019 19:06:53 -0700 (PDT) From: Ben Chuang To: adrian.hunter@intel.com, ulf.hansson@linaro.org Cc: linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, johnsonm@danlj.org, ben.chuang@genesyslogic.com.tw, Ben Chuang Subject: [PATCH V5 3/4] PCI: Add Genesys Logic, Inc. Vendor ID Date: Tue, 20 Aug 2019 10:06:50 +0800 Message-Id: <20190820020650.8334-1-benchuanggli@gmail.com> X-Mailer: git-send-email 2.22.1 MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Ben Chuang Add the Genesys Logic, Inc. vendor ID to pci_ids.h. Signed-off-by: Ben Chuang Co-developed-by: Michael K Johnson Signed-off-by: Michael K Johnson Acked-by: Adrian Hunter --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 70e86148cb1e..4f7e12772a14 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2403,6 +2403,8 @@ #define PCI_DEVICE_ID_RDC_R6061 0x6061 #define PCI_DEVICE_ID_RDC_D1010 0x1010 +#define PCI_VENDOR_ID_GLI 0x17a0 + #define PCI_VENDOR_ID_LENOVO 0x17aa #define PCI_VENDOR_ID_QCOM 0x17cb From patchwork Tue Aug 20 02:07:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Chuang X-Patchwork-Id: 11102605 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2CB3913A0 for ; Tue, 20 Aug 2019 02:07:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EACEA20644 for ; Tue, 20 Aug 2019 02:07:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="P2vMBsQQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728903AbfHTCH3 (ORCPT ); Mon, 19 Aug 2019 22:07:29 -0400 Received: from mail-pf1-f195.google.com ([209.85.210.195]:33831 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728615AbfHTCH3 (ORCPT ); Mon, 19 Aug 2019 22:07:29 -0400 Received: by mail-pf1-f195.google.com with SMTP id b24so2345832pfp.1; Mon, 19 Aug 2019 19:07:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=fQ0Y8QfdpzR5cvekAZdNcWpYyFhTcekiyfzOH1gHAEE=; b=P2vMBsQQhUvF1lN0huWofoGH7vsm7F1s8+W63iJ8ASYNT/6Tguzi/E8JXoj5SEKJEz zxIrSFmHAFrNpJy1LpL7eWey+xqsRch8ikretP6RkSfCRMbqLhCE5oleiLBpHCpJHxP+ NMA0i2LhZOUHOkMMUTaB2Jtmwd/Cmd3cFvXP+vCBjD9ROQWTugEHxmmX9Q/IKssblh+3 5byDsjMl+bOX8eEx/q9YVJudlckEInuUl+ujdVc8zS6HywAc2eL79BDWeONwq2IuQS8q VaG/Z+wnbNVgXo4ns+gUhgjzxMuasQFmKpjTmrtOrciEsBLQ/4ZSjtUPBaD2QNsVXyo1 /n9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=fQ0Y8QfdpzR5cvekAZdNcWpYyFhTcekiyfzOH1gHAEE=; b=D47J7L2k124yviCLjdqhpGGji4it6VxMQm6pd2oRnPCDfpjvfHRbvaoLNOfHBN8u+m JJboqm9n2+pCmnyIAagcqQJR3/9ta/FmM3qiTzaSUDBx5OAhufQ4jsp8ttxZUlSz6E8i tXIEv8Mp8WINhQlqrzjEikra4P3SP4CdGr8Zk+IFdgNVkFLMgSSLZdITClJTCDCpW5UM upKrHcQZH7gKUA0qjh3LXG42EHCK2cjzOY963aDZBOL5h/MzTdFqqVKP0ExH/PVIn67N 3AhHk+Z+79kEyAjNskvWM5GhrI92pHSpz1SYsIO18sjvR7ffmqD+0MneIpKqnBm7njkH LUFw== X-Gm-Message-State: APjAAAWaRQ1azzR4cs6M1KPXh8M3GMibDUC4OspiO/u2R1qDYYqrd23e CeaySCXbZavAffwJ1osnUsk= X-Google-Smtp-Source: APXvYqxRy2eHHs6ZRT4UXCS+33t14JlEqkSF9IfcRNIYGE77mz178SCkpaszlZdT5ZVTOInGeIqfhA== X-Received: by 2002:a65:6547:: with SMTP id a7mr22291454pgw.65.1566266847911; Mon, 19 Aug 2019 19:07:27 -0700 (PDT) Received: from gli-arch.genesyslogic.com.tw (60-251-58-169.HINET-IP.hinet.net. [60.251.58.169]) by smtp.gmail.com with ESMTPSA id s16sm12785699pjp.10.2019.08.19.19.07.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2019 19:07:27 -0700 (PDT) From: Ben Chuang To: adrian.hunter@intel.com, ulf.hansson@linaro.org Cc: linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, johnsonm@danlj.org, ben.chuang@genesyslogic.com.tw, Ben Chuang Subject: [PATCH V5 4/4] mmc: host: sdhci-pci: Add Genesys Logic GL975x support Date: Tue, 20 Aug 2019 10:07:39 +0800 Message-Id: <20190820020739.8396-1-benchuanggli@gmail.com> X-Mailer: git-send-email 2.22.1 MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Ben Chuang Add support for the GL9750 and GL9755 chipsets. The patches enable v4 mode and wait 5ms after set 1.8V signal enable for GL9750/GL9755. It fixed the value of SDHCI_MAX_CURRENT register and uses the vendor tuning flow for GL9750. Signed-off-by: Ben Chuang Co-developed-by: Michael K Johnson Signed-off-by: Michael K Johnson --- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/sdhci-pci-core.c | 2 + drivers/mmc/host/sdhci-pci-gli.c | 381 ++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-pci.h | 5 + 4 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 drivers/mmc/host/sdhci-pci-gli.c diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 73578718f119..661445415090 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -13,7 +13,7 @@ obj-$(CONFIG_MMC_MXS) += mxs-mmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.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-dwc-mshc.o sdhci-pci-gli.o obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 4154ee11b47d..e5835fbf73bc 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -1682,6 +1682,8 @@ static const struct pci_device_id pci_ids[] = { SDHCI_PCI_DEVICE(O2, SEABIRD1, o2), SDHCI_PCI_DEVICE(ARASAN, PHY_EMMC, arasan), SDHCI_PCI_DEVICE(SYNOPSYS, DWC_MSHC, snps), + SDHCI_PCI_DEVICE(GLI, 9750, gl9750), + SDHCI_PCI_DEVICE(GLI, 9755, gl9755), SDHCI_PCI_DEVICE_CLASS(AMD, SYSTEM_SDHCI, PCI_CLASS_MASK, amd), /* Generic SD host controller */ {PCI_DEVICE_CLASS(SYSTEM_SDHCI, PCI_CLASS_MASK)}, diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c new file mode 100644 index 000000000000..99abb7830e62 --- /dev/null +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Genesys Logic, Inc. + * + * Authors: Ben Chuang + * + * Version: v0.9.0 (2019-08-08) + */ + +#include +#include +#include +#include "sdhci.h" +#include "sdhci-pci.h" + +/* Genesys Logic extra registers */ +#define SDHCI_GLI_9750_WT 0x800 +#define SDHCI_GLI_9750_DRIVING 0x860 +#define SDHCI_GLI_9750_PLL 0x864 +#define SDHCI_GLI_9750_SW_CTRL 0x874 +#define SDHCI_GLI_9750_MISC 0x878 + +#define SDHCI_GLI_9750_TUNING_CONTROL 0x540 +#define SDHCI_GLI_9750_TUNING_PARAMETERS 0x544 + +#define GLI_MAX_TUNING_LOOP 40 + +/* Genesys Logic chipset */ +static void gli_set_9750(struct sdhci_host *host) +{ + u32 wt_value = 0; + u32 driving_value = 0; + u32 pll_value = 0; + u32 sw_ctrl_value = 0; + u32 misc_value = 0; + u32 parameter_value = 0; + u32 control_value = 0; + + u16 ctrl2 = 0; + + wt_value = sdhci_readl(host, SDHCI_GLI_9750_WT); + if ((wt_value & 0x1) == 0) { + wt_value |= 0x1; + sdhci_writel(host, wt_value, SDHCI_GLI_9750_WT); + } + + driving_value = sdhci_readl(host, SDHCI_GLI_9750_DRIVING); + pll_value = sdhci_readl(host, SDHCI_GLI_9750_PLL); + sw_ctrl_value = sdhci_readl(host, SDHCI_GLI_9750_SW_CTRL); + misc_value = sdhci_readl(host, SDHCI_GLI_9750_MISC); + parameter_value = sdhci_readl(host, SDHCI_GLI_9750_TUNING_PARAMETERS); + control_value = sdhci_readl(host, SDHCI_GLI_9750_TUNING_CONTROL); + + driving_value &= ~(0x0C000FFF); + driving_value |= 0x0C000FFF; + sdhci_writel(host, driving_value, SDHCI_GLI_9750_DRIVING); + + sw_ctrl_value |= 0xc0; + sdhci_writel(host, sw_ctrl_value, SDHCI_GLI_9750_SW_CTRL); + + // reset the tuning flow after reinit and before starting tuning + pll_value |= 0x800000; // bit23-1 + pll_value &= ~(0x00700000); // bit22:20-0 + + misc_value &= ~(0x8); // bit3-0 + misc_value &= ~(0x4); // bit2-0 + + misc_value &= ~(0x70); // bit6:4-0 + misc_value |= 0x50; // bit6:4-5 + + parameter_value &= ~(0x7); // bit2:0-0 + parameter_value |= 0x1; // bit2:0-1 + + control_value &= ~(0x190000); // bit20:19-0, bit16-0 + control_value |= 0x110000; // bit20:19-b10, bit16-1 + + sdhci_writel(host, pll_value, SDHCI_GLI_9750_PLL); + sdhci_writel(host, misc_value, SDHCI_GLI_9750_MISC); + + // disable tuned clk + ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); + ctrl2 &= ~SDHCI_CTRL_TUNED_CLK; + sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2); + + // 540 enable tuning parameters control + control_value |= 0x10; + sdhci_writel(host, control_value, SDHCI_GLI_9750_TUNING_CONTROL); + + // write 544 tuning parameters + sdhci_writel(host, parameter_value, SDHCI_GLI_9750_TUNING_PARAMETERS); + + // 540 disable tuning parameters control + control_value &= ~0x10; + sdhci_writel(host, control_value, SDHCI_GLI_9750_TUNING_CONTROL); + + // clear tuned clk + ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); + ctrl2 &= ~SDHCI_CTRL_TUNED_CLK; + sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2); + + udelay(1); + wt_value = sdhci_readl(host, SDHCI_GLI_9750_WT); + wt_value &= ~0x1; + sdhci_writel(host, wt_value, SDHCI_GLI_9750_WT); +} + +static void sdhci_gli_do_reset(struct sdhci_host *host, u8 mask) +{ + host->ops->reset(host, mask); + + if (mask & SDHCI_RESET_ALL) { + if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { + if (host->ops->enable_dma) + host->ops->enable_dma(host); + } + + /* Resetting the controller clears many */ + host->preset_enabled = false; + } +} + +static void sdhci_gli_abort_tuning(struct sdhci_host *host, u32 opcode) +{ + sdhci_reset_tuning(host); + + sdhci_gli_do_reset(host, SDHCI_RESET_CMD); + sdhci_gli_do_reset(host, SDHCI_RESET_DATA); + + sdhci_end_tuning(host); + + mmc_abort_tuning(host->mmc, opcode); +} + +static void gli_set_9750_rx_inv(struct sdhci_host *host, bool b) +{ + u32 wt_value = sdhci_readl(host, SDHCI_GLI_9750_WT); + u32 misc_value = sdhci_readl(host, SDHCI_GLI_9750_MISC); + + if ((wt_value & 0x1) == 0) { + wt_value |= 0x1; + sdhci_writel(host, wt_value, SDHCI_GLI_9750_WT); + } + + misc_value = sdhci_readl(host, SDHCI_GLI_9750_MISC); + if (b) { + misc_value |= 0x8; + sdhci_writel(host, misc_value, SDHCI_GLI_9750_MISC); + } else { + misc_value &= ~0x8; + sdhci_writel(host, misc_value, SDHCI_GLI_9750_MISC); + } + + wt_value = sdhci_readl(host, SDHCI_GLI_9750_WT); + wt_value &= ~0x1; + sdhci_writel(host, wt_value, SDHCI_GLI_9750_WT); +} + +static int __sdhci_execute_tuning_9750(struct sdhci_host *host, u32 opcode) +{ + int i; + int rx_inv = 0; + + for (rx_inv = 0; rx_inv < 2; rx_inv++) { + if (rx_inv & 0x1) + gli_set_9750_rx_inv(host, true); + else + gli_set_9750_rx_inv(host, false); + + sdhci_start_tuning(host); + + for (i = 0; i < GLI_MAX_TUNING_LOOP; i++) { + u16 ctrl; + + sdhci_send_tuning(host, opcode); + + if (!host->tuning_done) { + if (rx_inv == 1) { + pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n", + mmc_hostname(host->mmc)); + sdhci_gli_abort_tuning(host, opcode); + return -ETIMEDOUT; + } + pr_info("%s: Tuning timeout, try next tuning\n", + mmc_hostname(host->mmc)); + sdhci_gli_abort_tuning(host, opcode); + break; + } + + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) { + if (ctrl & SDHCI_CTRL_TUNED_CLK) + return 0; /* Success! */ + break; + } + } + } + + pr_info("%s: Tuning failed, falling back to fixed sampling clock\n", + mmc_hostname(host->mmc)); + sdhci_reset_tuning(host); + return -EAGAIN; +} + +static int gl9750_execute_tuning(struct mmc_host *mmc, u32 opcode) +{ + struct sdhci_host *host = mmc_priv(mmc); + int err = 0; + unsigned int tuning_count = 0; + bool hs400_tuning; + + hs400_tuning = host->flags & SDHCI_HS400_TUNING; + + if (host->tuning_mode == SDHCI_TUNING_MODE_1) + tuning_count = host->tuning_count; + + /* + * The Host Controller needs tuning in case of SDR104 and DDR50 + * mode, and for SDR50 mode when Use Tuning for SDR50 is set in + * the Capabilities register. + * If the Host Controller supports the HS200 mode then the + * tuning function has to be executed. + */ + switch (host->timing) { + /* HS400 tuning is done in HS200 mode */ + case MMC_TIMING_MMC_HS400: + err = -EINVAL; + goto out; + + case MMC_TIMING_MMC_HS200: + /* + * Periodic re-tuning for HS400 is not expected to be needed, so + * disable it here. + */ + if (hs400_tuning) + tuning_count = 0; + break; + + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_UHS_DDR50: + break; + case MMC_TIMING_UHS_SDR50: + if (host->flags & SDHCI_SDR50_NEEDS_TUNING) + break; + /* FALLTHROUGH */ + + default: + goto out; + } + + if (host->ops->platform_execute_tuning) { + err = host->ops->platform_execute_tuning(host, opcode); + goto out; + } + + host->mmc->retune_period = tuning_count; + + if (host->tuning_delay < 0) + host->tuning_delay = opcode == MMC_SEND_TUNING_BLOCK; + + gli_set_9750(host); + host->tuning_err = __sdhci_execute_tuning_9750(host, opcode); + + sdhci_end_tuning(host); +out: + host->flags &= ~SDHCI_HS400_TUNING; + + return err; +} + +static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot) +{ + struct sdhci_host *host = slot->host; + struct mmc_host_ops *ops = &host->mmc_host_ops; + + slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; + sdhci_enable_v4_mode(host); + + ops->execute_tuning = gl9750_execute_tuning; + + return 0; +} + +static int gli_probe_slot_gl9755(struct sdhci_pci_slot *slot) +{ + struct sdhci_host *host = slot->host; + + slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; + sdhci_enable_v4_mode(host); + + return 0; +} + +static void sdhci_gli_voltage_switch(struct sdhci_host *host) +{ + usleep_range(5000, 5500); +} + +static void sdhci_gli_pci_hw_reset(struct sdhci_host *host) +{ + struct sdhci_pci_slot *slot = sdhci_priv(host); + + if (slot->hw_reset) + slot->hw_reset(host); +} + +static void sdhci_gl9750_reset(struct sdhci_host *host, u8 mask) +{ + ktime_t timeout; + + sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); + + 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); + return; + } + udelay(10); + } + gli_set_9750(host); +} + +static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg) +{ + u32 value; + + value = readl(host->ioaddr + reg); + if (unlikely(reg == SDHCI_MAX_CURRENT)) { + if (!(value & 0xff)) + value |= 0xc8; + } + return value; +} + +static const struct sdhci_ops sdhci_gl9755_ops = { + .set_clock = sdhci_set_clock, + .enable_dma = sdhci_pci_enable_dma, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_reset, + .set_uhs_signaling = sdhci_set_uhs_signaling, + .hw_reset = sdhci_gli_pci_hw_reset, + .voltage_switch = sdhci_gli_voltage_switch, +}; + +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, + .ops = &sdhci_gl9755_ops, +}; + +static const struct sdhci_ops sdhci_gl9750_ops = { + .read_l = sdhci_gl9750_readl, + .set_clock = sdhci_set_clock, + .enable_dma = sdhci_pci_enable_dma, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_gl9750_reset, + .set_uhs_signaling = sdhci_set_uhs_signaling, + .hw_reset = sdhci_gli_pci_hw_reset, + .voltage_switch = sdhci_gli_voltage_switch, +}; + +const struct sdhci_pci_fixes sdhci_gl9750 = { + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, + .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50, + .probe_slot = gli_probe_slot_gl9750, + .ops = &sdhci_gl9750_ops, +}; + diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index e5dc6e44c7a4..738ba5afcc20 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h @@ -65,6 +65,9 @@ #define PCI_DEVICE_ID_SYNOPSYS_DWC_MSHC 0xc202 +#define PCI_DEVICE_ID_GLI_9755 0x9755 +#define PCI_DEVICE_ID_GLI_9750 0x9750 + /* * PCI device class and mask */ @@ -185,5 +188,7 @@ int sdhci_pci_enable_dma(struct sdhci_host *host); extern const struct sdhci_pci_fixes sdhci_arasan; extern const struct sdhci_pci_fixes sdhci_snps; extern const struct sdhci_pci_fixes sdhci_o2; +extern const struct sdhci_pci_fixes sdhci_gl9750; +extern const struct sdhci_pci_fixes sdhci_gl9755; #endif /* __SDHCI_PCI_H */