Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp3380274ybv; Sun, 9 Feb 2020 22:11:18 -0800 (PST) X-Google-Smtp-Source: APXvYqynimNu28oyXRRwZdkI0gnORI0ap6mbtEd22gml63+aWoasnV8SyareUWlUtEqAcWNjPo0B X-Received: by 2002:aca:c7ca:: with SMTP id x193mr9768791oif.70.1581315077878; Sun, 09 Feb 2020 22:11:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581315077; cv=none; d=google.com; s=arc-20160816; b=eqjtEb8O6OragSLY1aWatwgn7cdFQo+07MaakHiZbpLq34FQyI5smkFrVGZ46IvPCD DMiWB/lt9Ou9neHZNKB3w6C101FxvjvZACI7FfIvsmT5+MEgqv5cM0dsD2pfOK0ALuxS gI5YFmRnMi3XKYwctd7RrT8Y+nCoL+oG3ayLF5IE2vcH+VY51/tqNJN1hUQ/ID2DQ+O6 Bltac3gEJHZr3XjTH7Ss5zY78Pb4fcTzFgwoqC1dR0PD8/PpbagIN8nEV2DQH5JVwUqe 4bqOf08agF/FaByYEioOGRud4Uip4KRYgQyn4UQ6zR3U8yWptSUsj6VWqsdWSWBF3wBH LVOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:references:cc:to:subject:from; bh=ShzTprx+z+TqFlpbVcdnEsbU5RvNkReHdPO+eMI4Qjs=; b=E2zWaqQZ+Q+PbfHd6ZvHWVChmzznLOCDSQI/teQyXukw2Lwu15ecLJORJpC3YsrJ8n VJcWsfCGQn23ZOU9zJ2dCJWcOcdAvK8mq0zleXU5ARJ18LRTzNJ7DmqUYRzwBkUOkbId 1Bk3e3Q/yvlGnU6y+8kMd/kgAP2mDOjMtyYXGtQ4rU39lAZtK/10pHGcyw4F/BSeOWp8 TLMZ9XnjDgQVq326jvlgdH9zPEAj6DCCyKUFm12d7Y1xkpK/M338skifOKcstBHOln1O 3E2FiTrhX983UnjAcRAsktcMG8mc6BU1FHpDW5+H7a9KkQXRkVhEghCxYEMjpZVarOZy pZvA== ARC-Authentication-Results: i=1; mx.google.com; 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 v17si4321148otp.244.2020.02.09.22.11.04; Sun, 09 Feb 2020 22:11:17 -0800 (PST) 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; 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 S1727121AbgBJGKy (ORCPT + 99 others); Mon, 10 Feb 2020 01:10:54 -0500 Received: from mail-sz.amlogic.com ([211.162.65.117]:49295 "EHLO mail-sz.amlogic.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726188AbgBJGKy (ORCPT ); Mon, 10 Feb 2020 01:10:54 -0500 Received: from [10.7.0.4] (10.28.11.250) by mail-sz.amlogic.com (10.28.11.5) with Microsoft SMTP Server id 15.1.1591.10; Mon, 10 Feb 2020 14:11:25 +0800 From: Jian Hu Subject: Re: [PATCH v7 2/5] clk: meson: add support for A1 PLL clock ops To: Jerome Brunet , Neil Armstrong CC: Martin Blumenstingl , Kevin Hilman , Rob Herring , Michael Turquette , Stephen Boyd , Qiufang Dai , Jianxin Pan , Victor Wan , Chandle Zou , , , , , References: <20200120034937.128600-1-jian.hu@amlogic.com> <20200120034937.128600-3-jian.hu@amlogic.com> <1jftfq7ir8.fsf@starbuckisacylon.baylibre.com> Message-ID: Date: Mon, 10 Feb 2020 14:11:21 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.4.2 MIME-Version: 1.0 In-Reply-To: <1jftfq7ir8.fsf@starbuckisacylon.baylibre.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.28.11.250] Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Jerome Thanks for your suggestions. On 2020/2/4 18:24, Jerome Brunet wrote: > > On Mon 20 Jan 2020 at 04:49, Jian Hu wrote: > >> Compared with the previous SoCs, self-adaption current module >> is newly added for A1, and there is no reset parm except the >> fixed pll. In A1 PLL, the PLL enable sequence is different, using >> the new power-on sequence to enable the PLL. > > Things are getting clearer thanks to Martin's suggestions and I can > understand what your driver is doing now > > However, I still have a problem with the fact that 2 different pll types > are getting intertwined in this driver. Parameters mandatory to one is > made optional to the other. Nothing clearly shows which needs what and > the combinatorial are quickly growing. > > Apparently the only real difference is in enable/disable, So I would > prefer if the a1 had dedicated function for these ops. > > I suppose you'll have to submit clk_hw_enable() and clk_hw_disable() > to the framework to call the appropriate ops dependind on the SoC. > I am confused here. What does clk_hw_is_enabled/clk_hw_enable/clk_hw_disable use here? clk_hw_is_enabled is intend to check a parm's existence? But clk_hw_is_enabled which is existed in CCF to check a PLL is locked or not. Maybe I understand wrong about your suggestions. Could you list a example for clk_hw_enable and clk_hw_disable function implementation? >> >> Signed-off-by: Jian Hu >> Acked-by: Martin Blumenstingl >> --- >> drivers/clk/meson/clk-pll.c | 47 +++++++++++++++++++++++++++++++------ >> drivers/clk/meson/clk-pll.h | 2 ++ >> 2 files changed, 42 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c >> index ddb1e5634739..10926291440f 100644 >> --- a/drivers/clk/meson/clk-pll.c >> +++ b/drivers/clk/meson/clk-pll.c >> @@ -283,10 +283,14 @@ static void meson_clk_pll_init(struct clk_hw *hw) >> struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); >> >> if (pll->init_count) { >> - meson_parm_write(clk->map, &pll->rst, 1); >> + if (MESON_PARM_APPLICABLE(&pll->rst)) >> + meson_parm_write(clk->map, &pll->rst, 1); >> + > > replace by > enabled = clk_hw_is_enabled(hw) > if (enabled) > clk_hw_disable(hw) > clk_hw_is_enabled here is used to check 'pll->rst'? >> regmap_multi_reg_write(clk->map, pll->init_regs, >> pll->init_count); >> - meson_parm_write(clk->map, &pll->rst, 0); >> + >> + if (MESON_PARM_APPLICABLE(&pll->rst)) >> + meson_parm_write(clk->map, &pll->rst, 0); > > /* restore if necessary */ > if (enabled) > clk_hw_enable(hw) > >> } >> } >> >> @@ -295,8 +299,11 @@ static int meson_clk_pll_is_enabled(struct clk_hw *hw) >> struct clk_regmap *clk = to_clk_regmap(hw); >> struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); >> >> - if (meson_parm_read(clk->map, &pll->rst) || >> - !meson_parm_read(clk->map, &pll->en) || >> + if (MESON_PARM_APPLICABLE(&pll->rst) && >> + meson_parm_read(clk->map, &pll->rst)) >> + return 0; >> + >> + if (!meson_parm_read(clk->map, &pll->en) || >> !meson_parm_read(clk->map, &pll->l)) >> return 0; > > I suppose the pll can't be locked if it was in reset, so we could drop > the check on `rst` entirely to simplify the function > OK, I will drop 'rst' check. >> >> @@ -323,13 +330,34 @@ static int meson_clk_pll_enable(struct clk_hw *hw) >> return 0; >> >> /* Make sure the pll is in reset */ >> - meson_parm_write(clk->map, &pll->rst, 1); >> + if (MESON_PARM_APPLICABLE(&pll->rst)) >> + meson_parm_write(clk->map, &pll->rst, 1); >> >> /* Enable the pll */ >> meson_parm_write(clk->map, &pll->en, 1); >> >> /* Take the pll out reset */ >> - meson_parm_write(clk->map, &pll->rst, 0); >> + if (MESON_PARM_APPLICABLE(&pll->rst)) >> + meson_parm_write(clk->map, &pll->rst, 0); >> + >> + /* >> + * Compared with the previous SoCs, self-adaption current module >> + * is newly added for A1, keep the new power-on sequence to enable the >> + * PLL. The sequence is: >> + * 1. enable the pll, delay for 10us >> + * 2. enable the pll self-adaption current module, delay for 40us >> + * 3. enable the lock detect module >> + */ >> + if (MESON_PARM_APPLICABLE(&pll->current_en)) { >> + udelay(10); >> + meson_parm_write(clk->map, &pll->current_en, 1); >> + udelay(40); >> + }; >> + >> + if (MESON_PARM_APPLICABLE(&pll->l_detect)) { >> + meson_parm_write(clk->map, &pll->l_detect, 1); >> + meson_parm_write(clk->map, &pll->l_detect, 0); >> + } >> >> if (meson_clk_pll_wait_lock(hw)) >> return -EIO; >> @@ -343,10 +371,15 @@ static void meson_clk_pll_disable(struct clk_hw *hw) >> struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); >> >> /* Put the pll is in reset */ >> - meson_parm_write(clk->map, &pll->rst, 1); >> + if (MESON_PARM_APPLICABLE(&pll->rst)) >> + meson_parm_write(clk->map, &pll->rst, 1); >> >> /* Disable the pll */ >> meson_parm_write(clk->map, &pll->en, 0); >> + >> + /* Disable PLL internal self-adaption current module */ >> + if (MESON_PARM_APPLICABLE(&pll->current_en)) >> + meson_parm_write(clk->map, &pll->current_en, 0); >> } > > With the above clarified, it should be easy to properly split the > functions between the legacy type and the a1 type. > > You'll need to update meson_clk_pll_set_rate() to call > - clk_hw_is_enabled() > - clk_hw_enable() and clk_hw_disable() (again, you'll need to add > those in the framework first) > >> >> static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, >> diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h >> index 367efd0f6410..a2228c0fdce5 100644 >> --- a/drivers/clk/meson/clk-pll.h >> +++ b/drivers/clk/meson/clk-pll.h >> @@ -36,6 +36,8 @@ struct meson_clk_pll_data { >> struct parm frac; >> struct parm l; >> struct parm rst; >> + struct parm current_en; >> + struct parm l_detect; >> const struct reg_sequence *init_regs; >> unsigned int init_count; >> const struct pll_params_table *table; > > . >