From patchwork Thu Aug 16 07:16:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 144320 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp1729340ljj; Thu, 16 Aug 2018 00:17:36 -0700 (PDT) X-Google-Smtp-Source: AA+uWPxeuebXf02b7BZtcgqCptrdni/1FSq7cevX/IDgcjkMqQ9KTIibXErC7+nMDL25fumkdrYV X-Received: by 2002:a17:902:e005:: with SMTP id ca5-v6mr27550421plb.224.1534403856775; Thu, 16 Aug 2018 00:17:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534403856; cv=none; d=google.com; s=arc-20160816; b=jYWUdOfrYdzFbrzRwCAwrMLvNlCuFfKHm45VmdcbUbEV3UipVj9QTbisKto/KgOYu4 TCd6QLp88PiMNN8TQBKNAJPbkzPqr3cg+VZWZVu1h7gvSJjO4tsb/XgyRH1yMU4PIQUf +is/ojby5HgTuq7LVGFZWhmRBQH/VvCB84IipIxHviNa5NNg10xtNq2Ih3FhATTbz7+6 y2pTCj9SAd3dBwukIJiPvur78mOvITsrS5USuGXnf+5+p2/+EwTuRDgJdr0Khe6ROljE 6rHqs5xCTLbSUo6/dnlU4C4w2kxw8oJzQEBwnphMpl0ukWVbpjrkvI9NDPnSEZAII0MS erLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-filter :arc-authentication-results; bh=tzun5EuwErborZ1t9+/tHU8skqOmSC5qct9W8SZQT40=; b=S7KR5XQDQaFe/chko+zWq05bJ7NGjUvq58GE4S1nRVDblAVXtaVS/BLTHUv/xbawHc D7/TwQUe5GVRiMYARfu3W0+m2Lyg9G07wyVVASvADiF+KBpWjHEa0HKmx1qZiJOFWZ5D dZWmT9evy9iU0BJP71+NcVp9ULx3LQvCQjHgl1pCnpDxq/NiJrrbCfhFJojM/6sJ16HR thfhrjcBCg0rdpUguKIuj9uCDlRI2OeLdOer6yeQWG8y/YoXPMGuApopBIRw6KSr89nb eFew/1YIKeiWUnRVhj+kDuAqlFjAFkLSdbSopP0Ylyu1KGHl5ZZryDFb9A641HRhS4KB gBCw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=MSaqss2B; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f12-v6si24878828pgm.601.2018.08.16.00.17.36; Thu, 16 Aug 2018 00:17:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nifty.com header.s=dec2015msa header.b=MSaqss2B; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389123AbeHPKOC (ORCPT + 5 others); Thu, 16 Aug 2018 06:14:02 -0400 Received: from conuserg-09.nifty.com ([210.131.2.76]:17049 "EHLO conuserg-09.nifty.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389265AbeHPKOB (ORCPT ); Thu, 16 Aug 2018 06:14:01 -0400 Received: from grover.tkatk1.zaq.ne.jp (zaqdadce369.zaq.ne.jp [218.220.227.105]) (authenticated) by conuserg-09.nifty.com with ESMTP id w7G7Gu2I008336; Thu, 16 Aug 2018 16:16:58 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com w7G7Gu2I008336 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1534403818; bh=tzun5EuwErborZ1t9+/tHU8skqOmSC5qct9W8SZQT40=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MSaqss2BjWkSDIVG+DzUBB/w5QiA+oE7xuZJSGaDw/ytlosRr6f8ZG2iLvAkzGgng 3WvzQHd69e1KZMLKiH5cooY/LnFw2rGUo+wCvQA+pq/E6zlHrGXOze96wzhzOrqC7o lSR84w/ZOOQAmqKJUFPqO4StL/89oNzPVr9qQ67h0LL9B6PBdZuC47xz7Ben9GI2nf J8sfsb5UQhND/5N54BOLyvPCM8KLAbZW0m80bNp4rYli1afceyPcEz1dNmZGFURHgn kVMmVKdkbJmDnn1ACheFSeSYy0ajfBPNypwPLl296PT1C0BVJi4MN0V2F8y5gC+PO3 fzf4V0dHz4hgg== X-Nifty-SrcIP: [218.220.227.105] From: Masahiro Yamada To: linux-mmc@vger.kernel.org, Wolfram Sang Cc: Masami Hiramatsu , Jassi Brar , Ulf Hansson , linux-renesas-soc@vger.kernel.org, Masahiro Yamada Subject: [PATCH v2 2/7] mmc: tmio: move tmio_mmc_set_clock() to platform hook Date: Thu, 16 Aug 2018 16:16:34 +0900 Message-Id: <1534403799-10594-3-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1534403799-10594-1-git-send-email-yamada.masahiro@socionext.com> References: <1534403799-10594-1-git-send-email-yamada.masahiro@socionext.com> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org tmio_mmc_set_clock() is full of quirks because different SoC vendors extended this in different ways. The original IP defines the divisor range 1/2 ... 1/512. bit 7 is set: 1/512 bit 6 is set: 1/256 ... bit 0 is set: 1/4 all bits clear: 1/2 It is platform-dependent how to achieve the 1/1 clock. I guess the TMIO-MFD variant uses the clock selector outside of this IP, as far as I see tmio_core_mmc_clk_div() in drivers/mfd/tmio_core.c I guess bit[7:0]=0xff is Renesas-specific extension. Socionext (and Panasonic) uses bit 10 (CLKSEL) for 1/1. Also, newer versions of UniPhier SoC variants use bit 16 for 1/1024. host->clk_update() is only used by the Renesas variants, whereas host->set_clk_div() is only used by the TMIO-MFD variants. To cope with this mess, promote tmio_mmc_set_clock() to a new platform hook ->set_clock(), and melt the old two hooks into it. Signed-off-by: Masahiro Yamada --- Changes in v2: None drivers/mmc/host/renesas_sdhi_core.c | 50 ++++++++++++++++++++++- drivers/mmc/host/tmio_mmc.c | 48 ++++++++++++++++++++++ drivers/mmc/host/tmio_mmc.h | 4 +- drivers/mmc/host/tmio_mmc_core.c | 79 ++++-------------------------------- 4 files changed, 105 insertions(+), 76 deletions(-) -- 2.7.4 Reviewed-by: Wolfram Sang diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 45c015da..1f4c82e 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -155,6 +155,54 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host, return ret == 0 ? best_freq : clk_get_rate(priv->clk); } +static void renesas_sdhi_clk_start(struct tmio_mmc_host *host) +{ + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | + sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); + + /* HW engineers overrode docs: no sleep needed on R-Car2+ */ + if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) + usleep_range(10000, 11000); +} + +static void renesas_sdhi_clk_stop(struct tmio_mmc_host *host) +{ + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & + sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); + + /* HW engineers overrode docs: no sleep needed on R-Car2+ */ + if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) + usleep_range(10000, 11000); +} + +static void renesas_sdhi_set_clock(struct tmio_mmc_host *host, + unsigned int new_clock) +{ + u32 clk = 0, clock; + + if (new_clock == 0) { + renesas_sdhi_clk_stop(host); + return; + } + + clock = renesas_sdhi_clk_update(host, new_clock) / 512; + + for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) + clock <<= 1; + + /* 1/1 clock is option */ + if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1)) + clk |= 0xff; + + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & + sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); + if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) + usleep_range(10000, 11000); + + renesas_sdhi_clk_start(host); +} + static void renesas_sdhi_clk_disable(struct tmio_mmc_host *host) { struct renesas_sdhi *priv = host_to_priv(host); @@ -530,8 +578,8 @@ int renesas_sdhi_probe(struct platform_device *pdev, host->write16_hook = renesas_sdhi_write16_hook; host->clk_enable = renesas_sdhi_clk_enable; - host->clk_update = renesas_sdhi_clk_update; host->clk_disable = renesas_sdhi_clk_disable; + host->set_clock = renesas_sdhi_set_clock; host->multi_io_quirk = renesas_sdhi_multi_io_quirk; host->dma_ops = dma_ops; diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 43a2ea5..b031a77 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -13,6 +13,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -23,6 +24,52 @@ #include "tmio_mmc.h" +static void tmio_mmc_clk_start(struct tmio_mmc_host *host) +{ + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | + sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); + + usleep_range(10000, 11000); + sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); + usleep_range(10000, 11000); +} + +static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) +{ + sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); + usleep_range(10000, 11000); + + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & + sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); + + usleep_range(10000, 11000); +} + +static void tmio_mmc_set_clock(struct tmio_mmc_host *host, + unsigned int new_clock) +{ + u32 clk = 0, clock; + + if (new_clock == 0) { + tmio_mmc_clk_stop(host); + return; + } + + clock = host->mmc->f_min; + + for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) + clock <<= 1; + + host->pdata->set_clk_div(host->pdev, (clk >> 22) & 1); + + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & + sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); + usleep_range(10000, 11000); + + tmio_mmc_clk_start(host); +} + #ifdef CONFIG_PM_SLEEP static int tmio_mmc_suspend(struct device *dev) { @@ -100,6 +147,7 @@ static int tmio_mmc_probe(struct platform_device *pdev) /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ host->bus_shift = resource_size(res) >> 10; + host->set_clock = tmio_mmc_set_clock; host->mmc->f_max = pdata->hclk; host->mmc->f_min = pdata->hclk / 512; diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index e7d6513..e0aa3f9 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -132,7 +132,6 @@ struct tmio_mmc_host { /* Callbacks for clock / power control */ void (*set_pwr)(struct platform_device *host, int state); - void (*set_clk_div)(struct platform_device *host, int state); /* pio related stuff */ struct scatterlist *sg_ptr; @@ -169,10 +168,9 @@ struct tmio_mmc_host { /* Mandatory callback */ int (*clk_enable)(struct tmio_mmc_host *host); + void (*set_clock)(struct tmio_mmc_host *host, unsigned int clock); /* Optional callbacks */ - unsigned int (*clk_update)(struct tmio_mmc_host *host, - unsigned int new_clock); void (*clk_disable)(struct tmio_mmc_host *host); int (*multi_io_quirk)(struct mmc_card *card, unsigned int direction, int blk_size); diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index 991b340..74b8972 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c @@ -160,70 +160,6 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) } } -static void tmio_mmc_clk_start(struct tmio_mmc_host *host) -{ - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | - sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); - - /* HW engineers overrode docs: no sleep needed on R-Car2+ */ - if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) - usleep_range(10000, 11000); - - if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { - sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); - usleep_range(10000, 11000); - } -} - -static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) -{ - if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { - sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); - usleep_range(10000, 11000); - } - - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & - sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); - - /* HW engineers overrode docs: no sleep needed on R-Car2+ */ - if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) - usleep_range(10000, 11000); -} - -static void tmio_mmc_set_clock(struct tmio_mmc_host *host, - unsigned int new_clock) -{ - u32 clk = 0, clock; - - if (new_clock == 0) { - tmio_mmc_clk_stop(host); - return; - } - - if (host->clk_update) - clock = host->clk_update(host, new_clock) / 512; - else - clock = host->mmc->f_min; - - for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) - clock <<= 1; - - /* 1/1 clock is option */ - if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1)) - clk |= 0xff; - - if (host->set_clk_div) - host->set_clk_div(host->pdev, (clk >> 22) & 1); - - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & - sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); - if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) - usleep_range(10000, 11000); - - tmio_mmc_clk_start(host); -} - static void tmio_mmc_reset(struct tmio_mmc_host *host) { /* FIXME - should we set stop clock reg here */ @@ -1032,15 +968,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) switch (ios->power_mode) { case MMC_POWER_OFF: tmio_mmc_power_off(host); - tmio_mmc_set_clock(host, 0); + host->set_clock(host, 0); break; case MMC_POWER_UP: tmio_mmc_power_on(host, ios->vdd); - tmio_mmc_set_clock(host, ios->clock); + host->set_clock(host, ios->clock); tmio_mmc_set_bus_width(host, ios->bus_width); break; case MMC_POWER_ON: - tmio_mmc_set_clock(host, ios->clock); + host->set_clock(host, ios->clock); tmio_mmc_set_bus_width(host, ios->bus_width); break; } @@ -1196,7 +1132,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) int ret; /* - * Check the sanity of mmc->f_min to prevent tmio_mmc_set_clock() from + * Check the sanity of mmc->f_min to prevent host->set_clock() from * looping forever... */ if (mmc->f_min == 0) @@ -1206,7 +1142,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) _host->write16_hook = NULL; _host->set_pwr = pdata->set_pwr; - _host->set_clk_div = pdata->set_clk_div; ret = tmio_mmc_init_ocr(_host); if (ret < 0) @@ -1269,7 +1204,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) if (pdata->flags & TMIO_MMC_SDIO_IRQ) _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; - tmio_mmc_set_clock(_host, 0); + _host->set_clock(_host, 0); tmio_mmc_reset(_host); _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK); @@ -1353,7 +1288,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev) tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); if (host->clk_cache) - tmio_mmc_set_clock(host, 0); + host->set_clock(host, 0); tmio_mmc_clk_disable(host); @@ -1374,7 +1309,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev) tmio_mmc_clk_enable(host); if (host->clk_cache) - tmio_mmc_set_clock(host, host->clk_cache); + host->set_clock(host, host->clk_cache); if (host->native_hotplug) tmio_mmc_enable_mmc_irqs(host,