From patchwork Mon Mar 13 13:26:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 9620859 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 63F6860414 for ; Mon, 13 Mar 2017 13:28:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 56DDF1FF8E for ; Mon, 13 Mar 2017 13:28:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4B9DD28498; Mon, 13 Mar 2017 13:28:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D58AD1FF8E for ; Mon, 13 Mar 2017 13:28:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752999AbdCMN2H (ORCPT ); Mon, 13 Mar 2017 09:28:07 -0400 Received: from mail-wr0-f171.google.com ([209.85.128.171]:35444 "EHLO mail-wr0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751223AbdCMN04 (ORCPT ); Mon, 13 Mar 2017 09:26:56 -0400 Received: by mail-wr0-f171.google.com with SMTP id g10so103605589wrg.2 for ; Mon, 13 Mar 2017 06:26:55 -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=HXl336VRVtXZ3JkXJP2ZdrtuFoGMbg0Z59zFo+dHIY0=; b=C8ylSpyhyZgANmVLrwDfcWzwGDAvBmBhVm3h+H3qKDmdPG2TlMtnNCNJLTodOJevAd iM5C3/rbhzbyMTXHHInnApZJZQJPuDfIrN4JJVYdyFmT5fPoQLXuTtdqZ4scFjF9OuS+ WeUOGPwsXHnp37hxxpoh/OhqJbBkl79tjSl2avpX94COX/QrGjSjwrJDSSVY2wnIDUTe 4Ke0nwSP0An1N0LaiUB0gUFtIY+ijLwqvB8PaoQH9WeKBcqfwgsQX1/DYXZgqHFprANH J00QZIQ0aDa7/pP8G00MhZoEDKI0mljQaBETrHrv6AEJcCAy1l86paz2ej79wMlx78d8 BCVA== 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=HXl336VRVtXZ3JkXJP2ZdrtuFoGMbg0Z59zFo+dHIY0=; b=s+rQYfiT8JOKwpX1P9i9mEtrRcT3MvbmpdWUd9q9+W5ybXE4zGYSjNf5S+7gijtO/W /hk3Yau286ZmtYERwvpuFsyPtTwZOt+Qp4ENFjVfNQsAVdK6isKg0C3u25x+hcz8d84O GAlRXxDU1fa+n96sPfqFZ7vFWQhUsVsUXUlQ2bsvuljALCVYKfSNg8xsUBvoLbq6AqAF kDDUVTBrVE0bfwl22jMp/msNnThh0oSB6eNfGP5CAIk5BItG/vut8GlNmzNuV3s4nzwr 4rE9MD3pdOY7kTtqtBHrwHwESIDgkNiX1mWR+jnGaGxv9e0QclmR2HwHVT1YkNE92B49 T36w== X-Gm-Message-State: AMke39mUCWiHlJqm/ogtBJK3YRJ9cLZXz9qebcPM/OFUqYROkGjo168xQQ8j/n9OR+tQFbwk X-Received: by 10.223.163.7 with SMTP id c7mr27557466wrb.17.1489411613949; Mon, 13 Mar 2017 06:26:53 -0700 (PDT) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id 5sm24968931wrd.58.2017.03.13.06.26.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 13 Mar 2017 06:26:53 -0700 (PDT) From: Neil Armstrong To: mturquette@baylibre.com, sboyd@codeaurora.org, carlo@caione.org, khilman@baylibre.com Cc: Neil Armstrong , linux-clk@vger.kernel.org, linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/5] clk: meson: Add support for parameters for specific PLLs Date: Mon, 13 Mar 2017 14:26:40 +0100 Message-Id: <1489411604-18700-2-git-send-email-narmstrong@baylibre.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1489411604-18700-1-git-send-email-narmstrong@baylibre.com> References: <1489411604-18700-1-git-send-email-narmstrong@baylibre.com> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In recent Amlogic GXBB, GXL and GXM SoCs, the GP0 PLL needs some specific parameters in order to initialize and lock correctly. This patch adds an optional PARAM table used to initialize the PLL to a default value with it's parameters in order to achieve to desired frequency. The GP0 PLL in GXBB, GXL/GXM also needs some tweaks in the initialization steps, and these are exposed along the PARAM table. Signed-off-by: Neil Armstrong --- drivers/clk/meson/clk-pll.c | 52 +++++++++++++++++++++++++++++++++++++++++++-- drivers/clk/meson/clkc.h | 23 ++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 4adc1e8..aff223b 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -116,6 +116,29 @@ static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_ return NULL; } +/* Specific wait loop for GXL/GXM GP0 PLL */ +static int meson_clk_pll_wait_lock_reset(struct meson_clk_pll *pll, + struct parm *p_n) +{ + int delay = 100; + u32 reg; + + while (delay > 0) { + reg = readl(pll->base + p_n->reg_off); + writel(reg | MESON_PLL_RESET, pll->base + p_n->reg_off); + udelay(10); + writel(reg & ~MESON_PLL_RESET, pll->base + p_n->reg_off); + + mdelay(1); + + reg = readl(pll->base + p_n->reg_off); + if (reg & MESON_PLL_LOCK) + return 0; + delay--; + } + return -ETIMEDOUT; +} + static int meson_clk_pll_wait_lock(struct meson_clk_pll *pll, struct parm *p_n) { @@ -132,6 +155,15 @@ static int meson_clk_pll_wait_lock(struct meson_clk_pll *pll, return -ETIMEDOUT; } +static void meson_clk_pll_init_params(struct meson_clk_pll *pll) +{ + int i; + + for (i = 0 ; i < pll->params.params_count ; ++i) + writel(pll->params.params_table[i].value, + pll->base + pll->params.params_table[i].reg_off); +} + static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -151,10 +183,16 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, if (!rate_set) return -EINVAL; + /* Initialize the PLL in a clean state if specified */ + if (pll->params.params_count) + meson_clk_pll_init_params(pll); + /* PLL reset */ p = &pll->n; reg = readl(pll->base + p->reg_off); - writel(reg | MESON_PLL_RESET, pll->base + p->reg_off); + /* If no_init_reset is provided, avoid resetting at this point */ + if (!pll->params.no_init_reset) + writel(reg | MESON_PLL_RESET, pll->base + p->reg_off); reg = PARM_SET(p->width, p->shift, reg, rate_set->n); writel(reg, pll->base + p->reg_off); @@ -184,7 +222,17 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, } p = &pll->n; - ret = meson_clk_pll_wait_lock(pll, p); + /* If unreset_for_lock is provided, remove the reset bit here */ + if (pll->params.unreset_for_lock) { + reg = readl(pll->base + p->reg_off); + writel(reg & ~MESON_PLL_RESET, pll->base + p->reg_off); + } + + /* If reset_lock_loop, use a special loop including resetting */ + if (pll->params.reset_lock_loop) + ret = meson_clk_pll_wait_lock_reset(pll, p); + else + ret = meson_clk_pll_wait_lock(pll, p); if (ret) { pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", __func__, old_rate); diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 9bb70e7..5f1c12d 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -62,6 +62,28 @@ struct pll_rate_table { .frac = (_frac), \ } \ +struct pll_params_table { + unsigned int reg_off; + unsigned int value; +}; + +#define PLL_PARAM(_reg, _val) \ + { \ + .reg_off = (_reg), \ + .value = (_val), \ + } + +struct pll_setup_params { + struct pll_params_table *params_table; + unsigned int params_count; + /* Workaround for GP0, do not reset before configuring */ + bool no_init_reset; + /* Workaround for GP0, unreset right before checking for lock */ + bool unreset_for_lock; + /* Workaround for GXL GP0, reset in the lock checking loop */ + bool reset_lock_loop; +}; + struct meson_clk_pll { struct clk_hw hw; void __iomem *base; @@ -70,6 +92,7 @@ struct meson_clk_pll { struct parm frac; struct parm od; struct parm od2; + const struct pll_setup_params params; const struct pll_rate_table *rate_table; unsigned int rate_count; spinlock_t *lock;