From patchwork Fri Aug 4 17:43:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 109446 Delivered-To: patch@linaro.org Received: by 10.140.101.6 with SMTP id t6csp2475336qge; Fri, 4 Aug 2017 10:45:15 -0700 (PDT) X-Received: by 10.99.45.194 with SMTP id t185mr3067564pgt.388.1501868715837; Fri, 04 Aug 2017 10:45:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501868715; cv=none; d=google.com; s=arc-20160816; b=bcRtgpRYklb4NoqndoaiXD8ni8GHp8I7HDd+YcGkBx8KJQd3dD5+1LGIqG67d+h6C5 LwB8MtkV+6J4yTlNX9DnHrq1WLZlSLPCkFqDplhkuYxvhD2DuNYxSEw2ZdUIewE0El87 VaCQA1ZV5q0adl2JlDqOko7i4/t35Gw0YYif5P4orAwWDzbMbORuZ8wrQm1/5Z2UwKuY rJQNEbbRurutfNkXHIm/d6gtPAO0TLXOdndJJpaJte0yOgedTD8Li+U+RjCXaLWbW+Jl AMIcn2wE+RUOvLXt6KgPBtQPtdMSb+lm4ME3/eQEORUnzO7OuHD33ADWE8eQCKaVfSWc cFZA== 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:arc-authentication-results; bh=uTYHLU5iY9QtbsQMz4remriT2S7R6YDD5LjCd16hSME=; b=n1uRMpJ2E7KA/AAPBR5yZW1zIFP3x5ed3QDuFVwKKaxOnk4aRA2/UUsCGq6bAkqKdb PjRINHnGON3YGbKlckut90z6Vh9d1vWd9DdSXR8xpyinX3JaHhPy8FytrnYJxJFf6sHz P+uOSRTGZjN75gSK49qU35C70+StB++uYxK05q5zrZ62juwvkW0Jy/6chXciYEfMcSgh fSKRD/0l/Bla39nowEDe1K3UJgusovApla7vwaMV/b4U4F1lwfYurPI971T6U75Z/z77 hgJxNyWYd2LMvN12l2NgE4m96A2gx5EBO0Yw+QlkmZsSAqZSx1sbAgeh83sK6ES85qv1 fydA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20150623.gappssmtp.com header.b=fRnYPDw3; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-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 70si1260042pgh.395.2017.08.04.10.45.15; Fri, 04 Aug 2017 10:45:15 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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=@baylibre-com.20150623.gappssmtp.com header.b=fRnYPDw3; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753217AbdHDRoT (ORCPT + 25 others); Fri, 4 Aug 2017 13:44:19 -0400 Received: from mail-wm0-f47.google.com ([74.125.82.47]:35527 "EHLO mail-wm0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753185AbdHDRoM (ORCPT ); Fri, 4 Aug 2017 13:44:12 -0400 Received: by mail-wm0-f47.google.com with SMTP id m85so25329946wma.0 for ; Fri, 04 Aug 2017 10:44:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uTYHLU5iY9QtbsQMz4remriT2S7R6YDD5LjCd16hSME=; b=fRnYPDw3Yv8Y6f5KjrwM1ANAKh/63lP5QvtImNxTtMxdpTm/y5EZARKdptM3lTSt75 vXd1rrWuAA9mhWBgmh137Vjw23BrYcmeMYIHlKAQ+kBodGaUh7etq/D5HsdJv9Q+Irmx rdV2GKAsq7/uew0iRXv1kELWiJlH5fT9ykCYaeHySu9ShtwYxjMS2JwHNuD/4RYFh0PS DhomUqyx7wmz57DOly7k+pk935F5O2MhKYlCawvjk3UGA1V0r1Hp6KMux1ZV4sUNsGot WNvOHTlye36MaEyKxagQNz0+B502tMKyhnwvCRecHduwKEzD4SaHzoGDdN3/3385GAN4 CrAA== 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:in-reply-to :references; bh=uTYHLU5iY9QtbsQMz4remriT2S7R6YDD5LjCd16hSME=; b=ROM/VtYsrZo/31iMtC1z3sjjNApFTQe0JJa2zlbcBpDlKVjgGKt+ECALNnPux0F32D oAvN7cOjxa5ej35vWi6rR1ZfzWggCCdO5WujfNjNURu3GVDv9PCBLHSMF7EkQTwooqxx LsQ5aLltqgNeU8kpXJh4vCluHy1RNWI9Up3OgtB1V8EB9zvsCQv2F5+UK/DHnCzZDzAz 3sWkojYQntQmg3XmvFMNIF9OemO/qXW8V3iGfPbHyPMFMX5+xvbXjw5V5rnCgAcjpcx+ Ea2+DH1I8SSCTG9YEz3PMCmEsnKX04IQ0IHKT7lSywTedKOMPx5oxQGpeaUYHcZ3agYe kSKg== X-Gm-Message-State: AHYfb5i8kOyy8FfGq97y5r2rWOalrht7lvLJaI/Y4SMcEMq6U1uL9+OP Ve5Zm+Dj1VktLeXE X-Received: by 10.28.109.146 with SMTP id b18mr1787006wmi.34.1501868651343; Fri, 04 Aug 2017 10:44:11 -0700 (PDT) Received: from localhost.localdomain (cag06-3-82-243-161-21.fbx.proxad.net. [82.243.161.21]) by smtp.googlemail.com with ESMTPSA id p17sm996082wma.45.2017.08.04.10.44.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Aug 2017 10:44:10 -0700 (PDT) From: Jerome Brunet To: Ulf Hansson , Kevin Hilman , Carlo Caione Cc: Jerome Brunet , linux-mmc@vger.kernel.org, linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 08/14] mmc: meson-gx: rework clock init function Date: Fri, 4 Aug 2017 19:43:47 +0200 Message-Id: <20170804174353.16486-9-jbrunet@baylibre.com> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170804174353.16486-1-jbrunet@baylibre.com> References: <20170804174353.16486-1-jbrunet@baylibre.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Perform basic initialisation of the clk register before providing it to the CCF. Thanks to devm, carrying the clock structure around after init is not necessary. Rework the function to remove these from the controller host data. Finally, set initial mmc clock rate before enabling it, simplifying the exit condition. Signed-off-by: Jerome Brunet --- drivers/mmc/host/meson-gx-mmc.c | 101 +++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 52 deletions(-) -- 2.9.4 diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 8f9ba5190c18..4cc7d6530536 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -42,10 +42,7 @@ #define SD_EMMC_CLOCK 0x0 #define CLK_DIV_MASK GENMASK(5, 0) -#define CLK_DIV_MAX 63 #define CLK_SRC_MASK GENMASK(7, 6) -#define CLK_SRC_XTAL 0 /* external crystal */ -#define CLK_SRC_PLL 1 /* FCLK_DIV2 */ #define CLK_CORE_PHASE_MASK GENMASK(9, 8) #define CLK_TX_PHASE_MASK GENMASK(11, 10) #define CLK_RX_PHASE_MASK GENMASK(13, 12) @@ -137,13 +134,9 @@ struct meson_host { spinlock_t lock; void __iomem *regs; struct clk *core_clk; - struct clk_mux mux; - struct clk *mux_clk; + struct clk *signal_clk; unsigned long req_rate; - struct clk_divider cfg_div; - struct clk *cfg_div_clk; - unsigned int bounce_buf_size; void *bounce_buf; dma_addr_t bounce_dma_addr; @@ -291,7 +284,7 @@ static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate) return 0; } - ret = clk_set_rate(host->cfg_div_clk, clk_rate); + ret = clk_set_rate(host->signal_clk, clk_rate); if (ret) { dev_err(host->dev, "Unable to set cfg_div_clk to %lu. ret=%d\n", clk_rate, ret); @@ -299,7 +292,7 @@ static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate) } host->req_rate = clk_rate; - mmc->actual_clock = clk_get_rate(host->cfg_div_clk); + mmc->actual_clock = clk_get_rate(host->signal_clk); dev_dbg(host->dev, "clk rate: %u Hz\n", mmc->actual_clock); if (clk_rate != mmc->actual_clock) @@ -321,10 +314,13 @@ static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate) static int meson_mmc_clk_init(struct meson_host *host) { struct clk_init_data init; + struct clk_mux *mux; + struct clk_divider *div; + struct clk *clk; char clk_name[32]; int i, ret = 0; const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; - const char *clk_div_parents[1]; + const char *clk_parent[1]; u32 clk_reg; /* get the mux parents */ @@ -343,6 +339,19 @@ static int meson_mmc_clk_init(struct meson_host *host) mux_parent_names[i] = __clk_get_name(clk); } + /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ + clk_reg = 0; + clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, host->tp.core_phase); + clk_reg |= FIELD_PREP(CLK_TX_PHASE_MASK, host->tp.tx_phase); + clk_reg |= FIELD_PREP(CLK_RX_PHASE_MASK, host->tp.rx_phase); + clk_reg |= CLK_DIV_MASK; + clk_reg |= CLK_ALWAYS_ON; + writel(clk_reg, host->regs + SD_EMMC_CLOCK); + + /* create the mux */ + mux = devm_kzalloc(host->dev, sizeof(mux), GFP_KERNEL); + if (!mux) + return -ENOMEM; /* create the mux */ snprintf(clk_name, sizeof(clk_name), "%s#mux", dev_name(host->dev)); init.name = clk_name; @@ -350,59 +359,47 @@ static int meson_mmc_clk_init(struct meson_host *host) init.flags = 0; init.parent_names = mux_parent_names; init.num_parents = MUX_CLK_NUM_PARENTS; - host->mux.reg = host->regs + SD_EMMC_CLOCK; - host->mux.shift = __bf_shf(CLK_SRC_MASK); - host->mux.mask = CLK_SRC_MASK >> host->mux.shift; - host->mux.flags = 0; - host->mux.table = NULL; - host->mux.hw.init = &init; - host->mux_clk = devm_clk_register(host->dev, &host->mux.hw); - if (WARN_ON(IS_ERR(host->mux_clk))) - return PTR_ERR(host->mux_clk); + mux->reg = host->regs + SD_EMMC_CLOCK; + mux->shift = __bf_shf(CLK_SRC_MASK); + mux->mask = CLK_SRC_MASK >> mux->shift; + mux->hw.init = &init; + + clk = devm_clk_register(host->dev, &mux->hw); + if (WARN_ON(IS_ERR(clk))) + return PTR_ERR(clk); /* create the divider */ + div = devm_kzalloc(host->dev, sizeof(div), GFP_KERNEL); + if (!div) + return -ENOMEM; + snprintf(clk_name, sizeof(clk_name), "%s#div", dev_name(host->dev)); init.name = clk_name; init.ops = &clk_divider_ops; init.flags = CLK_SET_RATE_PARENT; - clk_div_parents[0] = __clk_get_name(host->mux_clk); - init.parent_names = clk_div_parents; - init.num_parents = ARRAY_SIZE(clk_div_parents); + clk_parent[0] = __clk_get_name(clk); + init.parent_names = clk_parent; + init.num_parents = 1; - host->cfg_div.reg = host->regs + SD_EMMC_CLOCK; - host->cfg_div.shift = __bf_shf(CLK_DIV_MASK); - host->cfg_div.width = __builtin_popcountl(CLK_DIV_MASK); - host->cfg_div.hw.init = &init; - host->cfg_div.flags = CLK_DIVIDER_ONE_BASED | - CLK_DIVIDER_ROUND_CLOSEST; + div->reg = host->regs + SD_EMMC_CLOCK; + div->shift = __bf_shf(CLK_DIV_MASK); + div->width = __builtin_popcountl(CLK_DIV_MASK); + div->hw.init = &init; + div->flags = (CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ROUND_CLOSEST); - host->cfg_div_clk = devm_clk_register(host->dev, &host->cfg_div.hw); - if (WARN_ON(PTR_ERR_OR_ZERO(host->cfg_div_clk))) - return PTR_ERR(host->cfg_div_clk); + host->signal_clk = devm_clk_register(host->dev, &div->hw); + if (WARN_ON(PTR_ERR_OR_ZERO(host->signal_clk))) + return PTR_ERR(host->signal_clk); /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ - clk_reg = 0; - clk_reg |= FIELD_PREP(CLK_CORE_PHASE_MASK, host->tp.core_phase); - clk_reg |= FIELD_PREP(CLK_TX_PHASE_MASK, host->tp.tx_phase); - clk_reg |= FIELD_PREP(CLK_RX_PHASE_MASK, host->tp.rx_phase); - clk_reg |= FIELD_PREP(CLK_SRC_MASK, CLK_SRC_XTAL); - clk_reg |= FIELD_PREP(CLK_DIV_MASK, CLK_DIV_MAX); - clk_reg &= ~CLK_ALWAYS_ON; - writel(clk_reg, host->regs + SD_EMMC_CLOCK); - - ret = clk_prepare_enable(host->cfg_div_clk); + host->mmc->f_min = clk_round_rate(host->signal_clk, 400000); + ret = clk_set_rate(host->signal_clk, host->mmc->f_min); if (ret) return ret; - /* Get the nearest minimum clock to 400KHz */ - host->mmc->f_min = clk_round_rate(host->cfg_div_clk, 400000); - - ret = meson_mmc_clk_set(host, host->mmc->f_min); - if (ret) - clk_disable_unprepare(host->cfg_div_clk); - - return ret; + return clk_prepare_enable(host->signal_clk); } static void meson_mmc_set_tuning_params(struct mmc_host *mmc) @@ -987,7 +984,7 @@ static int meson_mmc_probe(struct platform_device *pdev) dma_free_coherent(host->dev, host->bounce_buf_size, host->bounce_buf, host->bounce_dma_addr); err_div_clk: - clk_disable_unprepare(host->cfg_div_clk); + clk_disable_unprepare(host->signal_clk); err_core_clk: clk_disable_unprepare(host->core_clk); free_host: @@ -1009,7 +1006,7 @@ static int meson_mmc_remove(struct platform_device *pdev) dma_free_coherent(host->dev, host->bounce_buf_size, host->bounce_buf, host->bounce_dma_addr); - clk_disable_unprepare(host->cfg_div_clk); + clk_disable_unprepare(host->signal_clk); clk_disable_unprepare(host->core_clk); mmc_free_host(host->mmc);