From patchwork Fri Nov 21 14:46:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Barry Song <21cnbao@gmail.com> X-Patchwork-Id: 5355381 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 28CCB9F2F1 for ; Fri, 21 Nov 2014 14:47:16 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1F2E320145 for ; Fri, 21 Nov 2014 14:47:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 057452013D for ; Fri, 21 Nov 2014 14:47:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755377AbaKUOrM (ORCPT ); Fri, 21 Nov 2014 09:47:12 -0500 Received: from mail-pa0-f46.google.com ([209.85.220.46]:43068 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754269AbaKUOrL (ORCPT ); Fri, 21 Nov 2014 09:47:11 -0500 Received: by mail-pa0-f46.google.com with SMTP id lj1so5016019pab.33 for ; Fri, 21 Nov 2014 06:47:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=0mU8LY7gFRZ/OdzgzDXvRcNlGTeicRTH/PTezbZ9iIQ=; b=OmSKuAPTDmq1cKzXGFD9YRDSZgs91hDulMpXpen3VuNiIF0X+0z30YeeWmgqCVcFos GOjcvIOgMT3CruVfusBRF5F+Thg1i4NU+W45xMtq8MGLpMYcm5GQwNL64Wvv0sWYUZVM gNVg1rqJnq8g+OGNh66mRec2cHOlL05KXDf3EP3fVvXES7T58b8MIq1Y0L307AfhA5sx +iP9K5ZrtWPSmafqR1TjFT/POmOTl7G/teFZaKrwA/AIosvApSWJCaWsHYsrUwGV3/BP /vhZ2mW4GYKNvZQFNj55KQETlVkP/8nbwz74DuXiJxEnjH0iaJ1CcjVukfi5kd3mpsrT 93ig== X-Received: by 10.68.204.8 with SMTP id ku8mr7590832pbc.103.1416581230971; Fri, 21 Nov 2014 06:47:10 -0800 (PST) Received: from localhost.localdomain ([140.207.223.180]) by mx.google.com with ESMTPSA id f12sm5091970pat.46.2014.11.21.06.47.04 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 21 Nov 2014 06:47:10 -0800 (PST) From: Barry Song <21cnbao@gmail.com> To: ulf.hansson@linaro.org, chris@printf.net, linux-mmc@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, workgroup.linux@csr.com, Minda Chen , Barry Song Subject: [PATCH] mmc: core: add core-level function for sending tuning commands Date: Fri, 21 Nov 2014 22:46:41 +0800 Message-Id: <1416581201-9851-1-git-send-email-21cnbao@gmail.com> X-Mailer: git-send-email 1.9.1 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Minda Chen According to the SD card spec, Add a manual tuning command function for SDR104/HS200 by sending command 19 or command 21 to read data and compare with the tuning block pattern. this patch will help to decrease some platform private codes in SDHCI platform_execute_tuning() callbacks. Signed-off-by: Minda Chen Signed-off-by: Barry Song --- drivers/mmc/core/mmc_ops.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/core.h | 1 + 2 files changed, 66 insertions(+) diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 7911e05..ecc7789 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -543,6 +543,71 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, } EXPORT_SYMBOL_GPL(mmc_switch); +int mmc_send_tuning(struct mmc_card *card, u32 opcode) +{ + struct mmc_request mrq = {NULL}; + struct mmc_command cmd = {0}; + struct mmc_data data = {0}; + struct scatterlist sg; + struct mmc_host *mmc = card->host; + struct mmc_ios *ios = &mmc->ios; + const u8 *tuning_block_pattern; + int size, err = 0; + u8 *data_buf; + + if (opcode == MMC_SEND_TUNING_BLOCK_HS200) { + if (ios->bus_width == MMC_BUS_WIDTH_8) { + tuning_block_pattern = tuning_blk_pattern_8bit; + size = sizeof(tuning_blk_pattern_8bit); + } else if (ios->bus_width == MMC_BUS_WIDTH_4) { + tuning_block_pattern = tuning_blk_pattern_4bit; + size = sizeof(tuning_blk_pattern_4bit); + } else + return -EINVAL; + } else if (opcode == MMC_SEND_TUNING_BLOCK) { + tuning_block_pattern = tuning_blk_pattern_4bit; + size = sizeof(tuning_blk_pattern_4bit); + } else + return -EINVAL; + + data_buf = kmalloc(size, GFP_KERNEL); + if (!data_buf) + return -ENOMEM; + + mrq.cmd = &cmd; + mrq.data = &data; + + cmd.opcode = opcode; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + data.blksz = size; + data.blocks = 1; + data.flags = MMC_DATA_READ; + + mmc_set_data_timeout(&data, card); + sg_init_one(&sg, data_buf, size); + memset(data_buf, 0, size); + mmc_wait_for_req(mmc, &mrq); + + if (cmd.error) { + err = cmd.error; + goto out; + } + + if (data.error) { + err = data.error; + goto out; + } + + if (memcmp(data_buf, tuning_block_pattern, size)) + err = -EIO; + +out: + kfree(data_buf); + return err; +} +EXPORT_SYMBOL_GPL(mmc_send_tuning); + static int mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, u8 len) diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index f206e29..82a0119 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -154,6 +154,7 @@ extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool, bool, bool); extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); +extern int mmc_send_tuning(struct mmc_card *, u32); extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); #define MMC_ERASE_ARG 0x00000000