Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752635AbbLVJBV (ORCPT ); Tue, 22 Dec 2015 04:01:21 -0500 Received: from mail-by2on0091.outbound.protection.outlook.com ([207.46.100.91]:49472 "EHLO na01-by2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750705AbbLVJBT (ORCPT ); Tue, 22 Dec 2015 04:01:19 -0500 Authentication-Results: spf=none (sender IP is 165.204.84.221) smtp.mailfrom=amd.com; gmail.com; dkim=none (message not signed) header.d=none;gmail.com; dmarc=permerror action=none header.from=amd.com; X-WSS-ID: 0NZR523-07-4C6-02 X-M-MSG: From: Wan Zongshun To: Ulf Hansson , CC: Wan Zongshun , Borislav Petkov , , Huang Rui , Wan Zongshun Subject: [PATCH 1/3] mmc: sdhci-pci: Add AMD HS200 mode tuning function Date: Tue, 22 Dec 2015 11:40:06 -0500 Message-ID: <1450802408-16354-1-git-send-email-vincent.wan@amd.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 Content-Type: text/plain X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:165.204.84.221;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(428002)(189002)(199003)(229853001)(92566002)(19580405001)(19580395003)(47776003)(5008740100001)(86362001)(33646002)(53416004)(50986999)(77096005)(575784001)(105586002)(97736004)(50466002)(189998001)(5001770100001)(5003940100001)(101416001)(5003600100002)(48376002)(36756003)(1096002)(586003)(50226001)(106466001)(1220700001)(87936001);DIR:OUT;SFP:1101;SCL:1;SRVR:BY2PR12MB0712;H:atltwp01.amd.com;FPR:;SPF:None;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BY2PR12MB0712;2:OjrGHGYwa7zzfCxTkVDqOceb5XMm0UscFyTzpvAAjxZGBLYjxNYjMd6npbmWtkpxhl88VH8xr4yI+TkiYWjEGr6im1eO1lrUlRqi/49NF07iwQ/3PDbPNC72iaDhqn1o109PzphXTvnP9msBYLjedQ==;3:izpQ6O15xnZIcrm61z3UUMFiIG4gn5wI11kaxapXsgtvn+wiLI6lI0XaXFXJ2GsemJTf8RcwZPcFfKcmyZd8JP7y/Oqqbl31bAuTpTYVoPn/XMAT9mYyEFZ6FQCEEbLFKayhZR1bN/XI40UwzDZIPJKJ3B66AhMMsB8n8pqa2ynhbKapdpRX2G0Pe7mGdUGnmvY/rnUIYb42/vZ25Orln9sIrM7JLW0UajJqRyqthw4=;25:+PgmI/rmx9Oz34C38OM2RE4UTZ2VYnqHEkxkZhAu50U9VeGCVaf83F6t/UlJfXn/dFm0BeXfy2ZCUUmn067hJ25b0uBmpcJxPLZwNByxNRo6MALccgzDD874T0Ur8NxV7iZ+rxYJM90CT0fExm9NF48wyNRBd4a5/nvJ+y+/lGw/6DxF3cx+Vq4lXypQ1vtFzxITFgandVzzeSjJ/UdevPl5v9/vS8LolsbhAW9bTQyDCGO/jsiO7rX1+SlBGVdQyx59/oCxP5OeQCxJi5QLmQ== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2PR12MB0712; X-Microsoft-Exchange-Diagnostics: 1;BY2PR12MB0712;20:zspPUSikxzXbtXr5gUXU1dS/PxOhQ5cBdoTvDQQ3ZVtlMWcfIWfYbhIu/f5DhA0W9lyS7laZC4aTQCp6dzps7Vy8p6D4mKN4TpLy8NysFl4M2ge4FmtXk3ClLmmlM5+VPbuAc5f5BIGGzZUQW5VpAFqJ+mJNpwGWhcEfmOl2iAmCc4L9jVpfkumA8tnrRaMXIp+cRhlI5+SrGQZZoM4LgpanYMosRwQqKXP2f/tAGjwt6uGWT6EFh661dXJfC8Zo3UPGRZiSin+EyPp0x+ejAbwaMsRZA+vTIrkEFGd1ywjPP+gLWLM/ctLgY0nOMWTXvGvV3AbKQVEohc0EBFRkWw8tQ+EZFL2x9hF9krqdtK/cTKSLpLKRSkUr656Y7TljcRd6P4RuCHsA9MMQzK57UfW920momupcq9TY83D6dtOzOepiqQTdX/9+UoNwrF0/grJ5+8lbT4cIiyfaXyYP/QbQo0XQmZXdfqPcS2a/uRCvMuxNg86Rm3omPKSYmFiy;4:W9B1ZFg1B6EE/l/N963rhkQokNKVJ2o5Qmtmc/vawYGuzO3mAtl30qomKhqqzvY8RmNBtGxXUkj8JMCb0OY44KIf3NFQnas/JI8Vii7UG2+02cA56NBwwSPGEIdP5wVdN7IOSmjHkLjrmmx33y5Rji4MoNDgoQLOePujct3Yj8L3Gq/8YZbeieANBnOBIW9RjxBGt1crP84X0bwMGJaK2a+0x3d62yJK9ayk0YI2qONZ/QB2F3q3YXnKP86fbsQUybHyB8uzLylGfdUHxvS4fn23BXnX8UcxfpWIMxm9yDXnAsMbS3wv5BAeXAPnEVhDAKC1WhKsJhEhp5QJtE5e1vwtTReFNWnKFXHkBowN8318M6xiunvvpvX1nhrwgBUQumb9UbLHkuZi/oKSU9BCj/cTLMJ9G/0FBM47vMVx7mU= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(520078)(5005006)(3002001)(10201501046);SRVR:BY2PR12MB0712;BCL:0;PCL:0;RULEID:;SRVR:BY2PR12MB0712; X-Forefront-PRVS: 0798146F16 X-Microsoft-Exchange-Diagnostics: 1;BY2PR12MB0712;23:epsiS40hwKtjc0LtpIYljST+ZOdoGOUBd4g6ZtpCZsqugTdtX5BBz7eA1J0fott9cnZiiPI8qrrWjat54YrIGuPNH0Ih4060izHEc1SFGF8tOKyUBGi6CrcDR1LhgCUoUK+DeNMuce8GW42FJ5JHsN7T3Xtpb0Dhh2jasYC9urRI6Rhn1tNVasLjpYbYGlCkCE4O0NKjrJjod8qVjmLSiqcNZanT2oRQB+9ZfolBZqZ2p6kS32AlNq+24AvFpsUFr06fICCcyd2QME57RByypVBpwmyqvkE4D7/TSWUGWgWgjcgmrtatsOqoVNnF2HAKUmrIBOX9qOU6RKql+/pZTEDT9LeyS5h5ulJO9YNt/zpxPfetoBLZvf6lm1Wp0zuwKxtLe6nxqLUx/Q+V5oJWBeLNTri+trW2KPKR8rXVAkXpmP7qyQq9efeu1r5ZZ8e4w4IwX85KuzIjAHy257K8EGVv7KYYcLM799/HRXYN0YetjK8l3EddPMZL//Zqm4EAaLzAhSklnM7qktIMDH/6r6XengnMhgskcHfzvOqDfKmhydcqLiMS/vGbp7mf27NeSGvFLZKG9koGVAc6gQ0UIvM7v2qaZxwEKpNooLEYmw9KBWB8WjoqKWMGrlkrI54TAL2uquvsU1YaaBt7wrzxgK6dwo4Yz/+foMvWaVdyeBqGNvt7gnUtiJfytIGtPWBeedVok5bCpK76Tf1FCMg8vpYscKI2vN4bQzkImPIdKCl+tSLqukYZkDlGHNxnsX+qc1HmwrfZCbq4TYI6B6ZJ6c/fqd/iQ4Z3/cAjIvLJFW8knqS6rsSh2iIrnV7CTHwMZjDprZH6tsqXPYvSEyU3hOcA4v6nYdy3BY3MyBikF6GykLu799FwlyNaLNKmShnF7OYnkojXdHyaqS44SUfddPI0yIkkybHK9HA/I2mcXck= X-Microsoft-Exchange-Diagnostics: 1;BY2PR12MB0712;5:D+OAD9bW0B51q4rENZ+J1ZtuyRMeg0RShS1OT7TJLth/hjdqe9wj3uttLk7w3J8EmCynTc1+e/9U6Oj/mNXpSPMRFL6km80d77CItzm0WSdFaVnNTJHnu6cgxWGU3flmZOKdocMimfoDwd99SBwPjA==;24:h6Y+mxDP1NxH8BJG6NJBf+5ADH6C9gm7n4kBjhayYXRUKaSGtWlPl+J12TfbefFGjMMBofVnx1ePGt1qTchJjIx0ZermSQJPVzYEqN9DSXE=;20:6xX41M9pme6rmwS/Fmo5s0rdXe1LLFfJpqMDqs5Co0vS96HD/5auHH5ixp6SgHs+rLRKxHHAwKiCv+gxan8DX90QFDv7VcV11P5t8D9xFWmaY7bRxxjZ+WSBtDAb+zZIALQ+iRotOfIHv92iU2rRGGFIg1SUUNPCl/Y49gEviOHO9UHIq5b3qPWjuNxWVDHKwkzrK0QSKxFS3YV/MDgR6qunjmpplk2t1QKPnR9RS0nXAtfQ+HMcCPr/6jz4IVZX SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Dec 2015 09:01:16.3418 (UTC) X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.221];Helo=[atltwp01.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR12MB0712 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4452 Lines: 175 From: Wan Zongshun This patch is to add software tuning functions for AMD hs200 mode. Signed-off-by: Wan Zongshun --- drivers/mmc/host/sdhci-pci-core.c | 146 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 08f4a9f..01c5723 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -729,6 +729,152 @@ enum amd_chipset_gen { AMD_CHIPSET_UNKNOWN, }; +struct tuning_descriptor { + unsigned char tune_around; + bool this_tune_ok; + bool last_tune_ok; + bool valid_front_end; + unsigned char valid_front; + unsigned char valid_window_max; + unsigned char tune_low_max; + unsigned char tune_low; + unsigned char valid_window; + unsigned char tune_result; +}; + +#define AMD_EMMC_TUNE_REG 0xb8 +static struct tuning_descriptor tdescriptor; + +static int tuning_reset(struct sdhci_host *host) +{ + unsigned int val; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + + val = sdhci_readw(host, SDHCI_HOST_CONTROL2); + val |= SDHCI_CTRL_PRESET_VAL_ENABLE | SDHCI_CTRL_EXEC_TUNING; + sdhci_writew(host, val, SDHCI_HOST_CONTROL2); + + val = sdhci_readw(host, SDHCI_HOST_CONTROL2); + val &= ~SDHCI_CTRL_EXEC_TUNING; + sdhci_writew(host, val, SDHCI_HOST_CONTROL2); + + spin_unlock_irqrestore(&host->lock, flags); + + return 0; +} + +static int config_tuning_phase(struct sdhci_host *host, unsigned char phase) +{ + struct sdhci_pci_slot *slot = sdhci_priv(host); + struct pci_dev *pdev = slot->chip->pdev; + unsigned int val; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + + pci_read_config_dword(pdev, AMD_EMMC_TUNE_REG, &val); + val &= ~0xf; + val |= (0x10800 | phase); + pci_write_config_dword(pdev, AMD_EMMC_TUNE_REG, val); + + spin_unlock_irqrestore(&host->lock, flags); + + return 0; +} + +static int find_good_phase(struct sdhci_host *host) +{ + struct tuning_descriptor *td = &tdescriptor; + struct sdhci_pci_slot *slot = sdhci_priv(host); + struct pci_dev *pdev = slot->chip->pdev; + unsigned int val; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + + if (td->this_tune_ok == false) + td->valid_front_end = 1; + + if (td->valid_front_end) + td->valid_front = td->valid_front; + else if (td->this_tune_ok) + td->valid_front = td->valid_front + 1; + + if ((!td->this_tune_ok && td->last_tune_ok) || + (td->tune_around == 11)) { + if (td->valid_window > td->valid_window_max) { + td->valid_window_max = td->valid_window; + td->tune_low_max = td->tune_low; + } + } + + if (td->this_tune_ok) { + if (!td->last_tune_ok) + td->tune_low = td->tune_around; + td->valid_window = td->valid_window + 1; + } else { + if (td->last_tune_ok) + td->valid_window = 0x0; + } + + td->last_tune_ok = td->this_tune_ok; + + if (td->tune_around == 11) { + if ((td->valid_front + td->valid_window) > + td->valid_window_max) { + if (td->valid_front > td->valid_window) + td->tune_result = + ((td->valid_front - td->valid_window) >> 1); + else + td->tune_result = td->tune_low + + ((td->valid_window + td->valid_front) >> 1); + } else { + td->tune_result = + td->tune_low_max + (td->valid_window_max >> 1); + } + + if (td->tune_result > 0x0b) + td->tune_result = 0x0b; + + pci_read_config_dword(pdev, AMD_EMMC_TUNE_REG, &val); + val &= ~0xf; + val |= (0x10800 | td->tune_result); + pci_write_config_dword(pdev, AMD_EMMC_TUNE_REG, val); + } + + spin_unlock_irqrestore(&host->lock, flags); + + return 0; +} + +static int amd_execute_tuning(struct sdhci_host *host, u32 opcode) +{ + struct tuning_descriptor *td = &tdescriptor; + + tuning_reset(host); + + for (td->tune_around = 0; td->tune_around < 12; td->tune_around++) { + + config_tuning_phase(host, td->tune_around); + + if (mmc_send_tuning(host->mmc, opcode, NULL)) { + td->this_tune_ok = false; + host->mmc->need_retune = 0; + mdelay(4); + } else { + td->this_tune_ok = true; + } + + find_good_phase(host); + } + + host->mmc->retune_period = 0; + + return 0; +} + static int amd_probe(struct sdhci_pci_chip *chip) { struct pci_dev *smbus_dev; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/