From patchwork Mon Aug 5 14:11:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 2838713 Return-Path: X-Original-To: patchwork-linux-sh@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 7960F9F485 for ; Mon, 5 Aug 2013 14:11:23 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F3F45201D5 for ; Mon, 5 Aug 2013 14:11:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E0703201C7 for ; Mon, 5 Aug 2013 14:11:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753319Ab3HEOLQ (ORCPT ); Mon, 5 Aug 2013 10:11:16 -0400 Received: from moutng.kundenserver.de ([212.227.126.187]:54730 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751055Ab3HEOLP (ORCPT ); Mon, 5 Aug 2013 10:11:15 -0400 Received: from axis700.grange (dslb-178-001-229-248.pools.arcor-ip.net [178.1.229.248]) by mrelayeu.kundenserver.de (node=mrbap2) with ESMTP (Nemesis) id 0LkjTw-1UVuol1ej6-00anxG; Mon, 05 Aug 2013 16:11:03 +0200 Received: by axis700.grange (Postfix, from userid 1000) id 1039340BB4; Mon, 5 Aug 2013 16:11:03 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by axis700.grange (Postfix) with ESMTP id 0D18340BB3; Mon, 5 Aug 2013 16:11:03 +0200 (CEST) Date: Mon, 5 Aug 2013 16:11:02 +0200 (CEST) From: Guennadi Liakhovetski X-X-Sender: lyakh@axis700.grange To: linux-mmc@vger.kernel.org cc: Chris Ball , linux-sh@vger.kernel.org, Magnus Damm , devicetree@vger.kernel.org Subject: [PATCH/RFC] mmc: sh_mmcif: revision-specific configuration from Device Tree Message-ID: MIME-Version: 1.0 X-Provags-ID: V02:K0:nVprRpRyeD2gA8bmxXQTrTITOR4IANHP1U28H4daQNp fryelZVOv1kk07WlcFNnLrw8G0E8Ldflea7XeM1vlnM5aPu6WL o21xfCVvIHv487cry5pn1hQ1DYUp1zt7+aojJVk+GK0LSmG47T m4TEXJO6YbTVTsPUBwmP0NUh53MggBVJkbsueedvdn4Rpf4k8W Z6Z9fLBez5UpHy9YF5QWVEBlysNUF1Tx/KgqIlbsLfEavjGnR9 gsXorAYbgp7NQPBcS5jzvRdNQJHv2sIGQNLH6TI38+utn0taWN VVbCRxIiwhjsNlf9dFTEp0XUGsLN2QQw8ZdeN5cT9LkKHgrra6 dYhGQ3K0YPbLyyUnqgeJICHDE9XYMctjQBGsAEc8QpcPZBMWX6 vIyt9LhnIP3Rg== Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI, 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 Add compatibility strings to configure MMCIF revision-specific features. MMCIF blocks are always integrated into SoCs, so, we use SoC model to distinguish between MMCIF versions. Signed-off-by: Guennadi Liakhovetski --- Hi Chris, I marked this as RFC, because having no access to the MMC standard I'm not certain about VccQ requirements for MMC DDR. On the one hand a comment in mmc.c says * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. which suggests, that DDR (DDR50?) can be used with VccQ = 3.3V, 1.8V and 1.2V at least. But in mmc_init_card() DDR50 is only requested from the driver if either MMC_CAP_1_8V_DDR or MMC_CAP_1_2V_DDR is specified in host's capabilities. So, I'm actually not sure whether MMC_CAP_UHS_DDR50 alone without 1_8V or 1_2V makes sense. That's also what I implemented in this patch - DDR50 is only enabled in combination with either 1.2 or 1.8V capability. Is this correct? Documentation/devicetree/bindings/mmc/sh_mmcif.txt | 15 ++++ drivers/mmc/host/sh_mmcif.c | 68 +++++++++++++++++-- 2 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/sh_mmcif.txt diff --git a/Documentation/devicetree/bindings/mmc/sh_mmcif.txt b/Documentation/devicetree/bindings/mmc/sh_mmcif.txt new file mode 100644 index 0000000..a0e7fee --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sh_mmcif.txt @@ -0,0 +1,15 @@ +* Renesas MMCIF MMC controller + +The MMCIF driver uses the standard mmc DT parser to evaluate all standard MMC DT +properties. Additionally the following properties must or can be used: + +Compulsory properties: +- compatible: must be one of + "renesas,sh-mmcif" for generic MMCIF blocks + "renesas,sh-mmcif-r8a73a4" for MMCIF on R8A73A4 (APE6) + "renesas,sh-mmcif-r8a7740" for MMCIF on R8A7740 (A1) + "renesas,sh-mmcif-r8a7790" for MMCIF on R8A7790 (H2) + "renesas,sh-mmcif-sh73a0" for MMCIF on SH73A0 (AG5) + "renesas,sh-mmcif-sh7372" for MMCIF on SH7372 (AP4) + +Further, any standard MMC DT properties from mmc.txt can be used. diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 444f83b..a4bd784 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -257,6 +258,39 @@ struct sh_mmcif_host { bool dma_active; }; +struct sh_mmcif_of_data { + unsigned int ccs_enable : 1; + unsigned int clk_ctrl2_enable : 1; + unsigned int uhs_ddr_1v8 : 1; + unsigned int uhs_ddr_1v2 : 1; +}; + +enum { + R8A73A4, + R8A7740, + R8A7790, + SH7372, + SH73A0, +}; + +static const struct sh_mmcif_of_data sh_mmcif_of_cfg[] = { + [R8A73A4] = { + .uhs_ddr_1v8 = 1, + }, + [R8A7740] = { + /* all disabled */ + }, + [R8A7790] = { + .clk_ctrl2_enable = 1, + }, + [SH73A0] = { + .uhs_ddr_1v8 = 1, + }, + [SH7372] = { + .ccs_enable = 1, + }, +}; + static inline void sh_mmcif_bitset(struct sh_mmcif_host *host, unsigned int reg, u32 val) { @@ -1362,8 +1396,21 @@ static void sh_mmcif_init_ocr(struct sh_mmcif_host *host) dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); } +static const struct of_device_id mmcif_of_match[] = { + {.compatible = "renesas,sh-mmcif"}, + {.compatible = "renesas,sh-mmcif-r8a73a4", .data = &sh_mmcif_of_cfg[R8A73A4]}, + {.compatible = "renesas,sh-mmcif-r8a7740", .data = &sh_mmcif_of_cfg[R8A7740]}, + {.compatible = "renesas,sh-mmcif-r8a7790", .data = &sh_mmcif_of_cfg[R8A7790]}, + {.compatible = "renesas,sh-mmcif-sh73a0", .data = &sh_mmcif_of_cfg[SH73A0]}, + {.compatible = "renesas,sh-mmcif-sh7372", .data = &sh_mmcif_of_cfg[SH7372]}, + {} +}; +MODULE_DEVICE_TABLE(of, mmcif_of_match); + static int sh_mmcif_probe(struct platform_device *pdev) { + const struct of_device_id *of_id = + of_match_device(mmcif_of_match, &pdev->dev); int ret = 0, irq[2]; struct mmc_host *mmc; struct sh_mmcif_host *host; @@ -1403,8 +1450,19 @@ static int sh_mmcif_probe(struct platform_device *pdev) host->mmc = mmc; host->addr = reg; host->timeout = msecs_to_jiffies(1000); - host->ccs_enable = !pd || !pd->ccs_unsupported; - host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; + + if (of_id && of_id->data) { + const struct sh_mmcif_of_data *of_data = of_id->data; + host->ccs_enable = of_data->ccs_enable; + host->clk_ctrl2_enable = of_data->clk_ctrl2_enable; + if (of_data->uhs_ddr_1v8) + mmc->caps |= MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR; + if (of_data->uhs_ddr_1v2) + mmc->caps |= MMC_CAP_UHS_DDR50 | MMC_CAP_1_2V_DDR; + } else { + host->ccs_enable = !pd || !pd->ccs_unsupported; + host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; + } host->pd = pdev; @@ -1564,12 +1622,6 @@ static int sh_mmcif_resume(struct device *dev) #define sh_mmcif_resume NULL #endif /* CONFIG_PM */ -static const struct of_device_id mmcif_of_match[] = { - { .compatible = "renesas,sh-mmcif" }, - { } -}; -MODULE_DEVICE_TABLE(of, mmcif_of_match); - static const struct dev_pm_ops sh_mmcif_dev_pm_ops = { .suspend = sh_mmcif_suspend, .resume = sh_mmcif_resume,