All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: Peter De Schrijver
	<pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH v3 3/4] clk: tegra: MBIST work around for Tegra210
Date: Thu, 25 Jan 2018 10:19:08 +0000	[thread overview]
Message-ID: <a161a11c-1794-ebc4-3ff0-7624c23cabdb@nvidia.com> (raw)
In-Reply-To: <20180125090255.GK7031-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>


On 25/01/18 09:02, Peter De Schrijver wrote:
> On Wed, Jan 24, 2018 at 09:59:56PM +0000, Jon Hunter wrote:

...

>>> +void tegra210_clk_handle_mbist_war(unsigned int id)
>>> +{
>>> +	int err;
>>> +	struct tegra210_domain_mbist_war *mbist_war;
>>> +
>>> +	if (id >= ARRAY_SIZE(tegra210_pg_mbist_war)) {
>>> +		WARN(1, "unknown domain id in MBIST WAR handler\n");
>>> +		return;
>>> +	}
>>> +
>>> +	mbist_war = &tegra210_pg_mbist_war[id];
>>> +	if (!mbist_war->handle_lvl2_ovr)
>>> +		return;
>>> +
>>> +	err = mbist_war->handle_lvl2_ovr(mbist_war);
>>
>> Why not move the clk_bulk_prepare_enable/disable_unprepare and
>> mutex_lock/unlock functions into this function around the call to
>> ->handle_lvl2_ovr to save the duplication of that code in each of the
>> war functions?
>>
> 
> This could be done yes.
> 
>>> +	WARN(err < 0, "error handling MBIST WAR for domain: %d\n", id);
>>> +}
>>
>> I think that the above function should return an error and we should let
>> the power-domain power-on fail.
>>
> 
> This would only be useful if the user (tegra_powergate_power_up) would do
> rollback. I don't think that's done correctly today.

It does and so I think that we should return an error.

>>> +
>>> +
>>>  void tegra210_put_utmipll_in_iddq(void)
>>>  {
>>>  	u32 reg;
>>> @@ -3163,6 +3500,40 @@ static int tegra210_reset_deassert(unsigned long id)
>>>  	return 0;
>>>  }
>>>  
>>> +static void tegra210_mbist_clk_init(void)
>>> +{
>>> +	int i, j;
>>> +
>>> +	for (i = 0; i < ARRAY_SIZE(tegra210_pg_mbist_war); i++) {
>>> +		int num_clks = tegra210_pg_mbist_war[i].num_clks;
>>> +		struct clk_bulk_data *clk_data;
>>> +
>>> +		if (!num_clks)
>>> +			continue;
>>> +
>>> +		clk_data = kmalloc_array(num_clks, sizeof(*clk_data),
>>> +					 GFP_KERNEL);
>>> +		if (WARN(!clk_data,
>>> +			"no space for MBIST WAR clk array for %d\n", i)) {
>>> +			tegra210_pg_mbist_war[i].handle_lvl2_ovr = NULL;
>>> +			continue;
>>> +		}
>>
>> Printing error messages on memory allocation failures are not needed and
>> have been removed from various drivers. So lets no add any error
>> messages or warnings here.
>>
>> Also I think that we should just return an error here and not bother
>> continuing as there is no point.

So maybe here just ...

		if (WARN_ON(!clk_data))
			return -ENOMEM;

>>> +
>>> +		tegra210_pg_mbist_war[i].clks = clk_data;
>>
>> I think that you should only populate this when all the clocks have been
>> initialised correctly. You could then use this to check the clocks have
>> been setup correctly when executing the war.
>>
> 
> For some domains no extra clocks are needed (ie the clocks enabled by the
> power domain driver are enough). So an extra flag would be needed then.

Yes but you have num_clks to detect if a domain has extra clocks. So you
can use both of these to detect if the clocks are setup correctly. Right?

>>> +		for (j = 0; j < num_clks; j++) {
>>> +			int clk_id = tegra210_pg_mbist_war[i].clk_init_data[j];
>>> +			struct clk *clk = clks[clk_id];
>>> +
>>> +			if (IS_ERR(clk)) {
>>> +				clk_data[j].clk = NULL;
>>> +				WARN(1, "clk_id: %d\n", clk_id);
>>
>> I think that we should return an error here.
>>
> 
> I don't think letting clock init fail because of this, is a good idea. Too
> many things rely on working clocks.

It should never fail and if it does something is badly broken.

Maybe what we could do ...

			if (WARN_ON(IS_ERR(clk))) {
				tegra210_pg_mbist_war[i].clks = NULL;
				break;
			}

			clk_data[j].clk = clk;

Then we can check in tegra210_clk_handle_mbist_war() ...

	if (mbist_war->num_clks && !mbist_war.clks)
		return -ENODEV;

Does that work?

>>> +			} else {
>>> +				clk_data[j].clk = clk;
>>> +			}
>>> +		}
>>> +	}
>>> +}
>>> +
>>>  /**
>>>   * tegra210_clock_init - Tegra210-specific clock initialization
>>>   * @np: struct device_node * of the DT node for the SoC CAR IP block
>>> @@ -3197,6 +3568,24 @@ static void __init tegra210_clock_init(struct device_node *np)
>>>  		return;
>>>  	}
>>>  
>>> +	ape_base = ioremap(TEGRA210_APE_BASE, 256*1024);
>>> +	if (!ape_base) {
>>> +		pr_err("ioremap tegra210 APE failed\n");
>>> +		return;
>>> +	}
>>> +
>>> +	dispa_base = ioremap(TEGRA210_DISPA_BASE, 256*1024);
>>> +	if (!dispa_base) {
>>> +		pr_err("ioremap tegra210 DISPA failed\n");
>>> +		return;
>>> +	}
>>> +
>>> +	vic_base = ioremap(TEGRA210_VIC_BASE, 256*1024);
>>> +	if (!vic_base) {
>>> +		pr_err("ioremap tegra210 VIC failed\n");
>>> +		return;
>>> +	}
>>> +
>>>  	clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX,
>>>  			      TEGRA210_CAR_BANK_COUNT);
>>>  	if (!clks)
>>> @@ -3233,6 +3622,8 @@ static void __init tegra210_clock_init(struct device_node *np)
>>>  	tegra_add_of_provider(np);
>>>  	tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
>>>  
>>> +	tegra210_mbist_clk_init();
>>> +
>>
>> Maybe add a print here if the mbist init fails and return. I understand
>> it may not be a critical failure but it should never fail.
>>
> 
> You mean have the entire clock init fail and undo all the clock registrations?
> That seems overkill to me. Returning early would only prevent some sleep states
> from working because tegra_cpu_car_ops will not be initialized then. So I would
> do a warning then.

I don't think it is necessary to undo it. Ok, don't worry about
returning an error here, the warnings should be sufficient.

Cheers
Jon

-- 
nvpublic

WARNING: multiple messages have this Message-ID (diff)
From: Jon Hunter <jonathanh@nvidia.com>
To: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: <linux-tegra@vger.kernel.org>, <linux-clk@vger.kernel.org>
Subject: Re: [PATCH v3 3/4] clk: tegra: MBIST work around for Tegra210
Date: Thu, 25 Jan 2018 10:19:08 +0000	[thread overview]
Message-ID: <a161a11c-1794-ebc4-3ff0-7624c23cabdb@nvidia.com> (raw)
In-Reply-To: <20180125090255.GK7031@tbergstrom-lnx.Nvidia.com>


On 25/01/18 09:02, Peter De Schrijver wrote:
> On Wed, Jan 24, 2018 at 09:59:56PM +0000, Jon Hunter wrote:

...

>>> +void tegra210_clk_handle_mbist_war(unsigned int id)
>>> +{
>>> +	int err;
>>> +	struct tegra210_domain_mbist_war *mbist_war;
>>> +
>>> +	if (id >= ARRAY_SIZE(tegra210_pg_mbist_war)) {
>>> +		WARN(1, "unknown domain id in MBIST WAR handler\n");
>>> +		return;
>>> +	}
>>> +
>>> +	mbist_war = &tegra210_pg_mbist_war[id];
>>> +	if (!mbist_war->handle_lvl2_ovr)
>>> +		return;
>>> +
>>> +	err = mbist_war->handle_lvl2_ovr(mbist_war);
>>
>> Why not move the clk_bulk_prepare_enable/disable_unprepare and
>> mutex_lock/unlock functions into this function around the call to
>> ->handle_lvl2_ovr to save the duplication of that code in each of the
>> war functions?
>>
> 
> This could be done yes.
> 
>>> +	WARN(err < 0, "error handling MBIST WAR for domain: %d\n", id);
>>> +}
>>
>> I think that the above function should return an error and we should let
>> the power-domain power-on fail.
>>
> 
> This would only be useful if the user (tegra_powergate_power_up) would do
> rollback. I don't think that's done correctly today.

It does and so I think that we should return an error.

>>> +
>>> +
>>>  void tegra210_put_utmipll_in_iddq(void)
>>>  {
>>>  	u32 reg;
>>> @@ -3163,6 +3500,40 @@ static int tegra210_reset_deassert(unsigned long id)
>>>  	return 0;
>>>  }
>>>  
>>> +static void tegra210_mbist_clk_init(void)
>>> +{
>>> +	int i, j;
>>> +
>>> +	for (i = 0; i < ARRAY_SIZE(tegra210_pg_mbist_war); i++) {
>>> +		int num_clks = tegra210_pg_mbist_war[i].num_clks;
>>> +		struct clk_bulk_data *clk_data;
>>> +
>>> +		if (!num_clks)
>>> +			continue;
>>> +
>>> +		clk_data = kmalloc_array(num_clks, sizeof(*clk_data),
>>> +					 GFP_KERNEL);
>>> +		if (WARN(!clk_data,
>>> +			"no space for MBIST WAR clk array for %d\n", i)) {
>>> +			tegra210_pg_mbist_war[i].handle_lvl2_ovr = NULL;
>>> +			continue;
>>> +		}
>>
>> Printing error messages on memory allocation failures are not needed and
>> have been removed from various drivers. So lets no add any error
>> messages or warnings here.
>>
>> Also I think that we should just return an error here and not bother
>> continuing as there is no point.

So maybe here just ...

		if (WARN_ON(!clk_data))
			return -ENOMEM;

>>> +
>>> +		tegra210_pg_mbist_war[i].clks = clk_data;
>>
>> I think that you should only populate this when all the clocks have been
>> initialised correctly. You could then use this to check the clocks have
>> been setup correctly when executing the war.
>>
> 
> For some domains no extra clocks are needed (ie the clocks enabled by the
> power domain driver are enough). So an extra flag would be needed then.

Yes but you have num_clks to detect if a domain has extra clocks. So you
can use both of these to detect if the clocks are setup correctly. Right?

>>> +		for (j = 0; j < num_clks; j++) {
>>> +			int clk_id = tegra210_pg_mbist_war[i].clk_init_data[j];
>>> +			struct clk *clk = clks[clk_id];
>>> +
>>> +			if (IS_ERR(clk)) {
>>> +				clk_data[j].clk = NULL;
>>> +				WARN(1, "clk_id: %d\n", clk_id);
>>
>> I think that we should return an error here.
>>
> 
> I don't think letting clock init fail because of this, is a good idea. Too
> many things rely on working clocks.

It should never fail and if it does something is badly broken.

Maybe what we could do ...

			if (WARN_ON(IS_ERR(clk))) {
				tegra210_pg_mbist_war[i].clks = NULL;
				break;
			}

			clk_data[j].clk = clk;

Then we can check in tegra210_clk_handle_mbist_war() ...

	if (mbist_war->num_clks && !mbist_war.clks)
		return -ENODEV;

Does that work?

>>> +			} else {
>>> +				clk_data[j].clk = clk;
>>> +			}
>>> +		}
>>> +	}
>>> +}
>>> +
>>>  /**
>>>   * tegra210_clock_init - Tegra210-specific clock initialization
>>>   * @np: struct device_node * of the DT node for the SoC CAR IP block
>>> @@ -3197,6 +3568,24 @@ static void __init tegra210_clock_init(struct device_node *np)
>>>  		return;
>>>  	}
>>>  
>>> +	ape_base = ioremap(TEGRA210_APE_BASE, 256*1024);
>>> +	if (!ape_base) {
>>> +		pr_err("ioremap tegra210 APE failed\n");
>>> +		return;
>>> +	}
>>> +
>>> +	dispa_base = ioremap(TEGRA210_DISPA_BASE, 256*1024);
>>> +	if (!dispa_base) {
>>> +		pr_err("ioremap tegra210 DISPA failed\n");
>>> +		return;
>>> +	}
>>> +
>>> +	vic_base = ioremap(TEGRA210_VIC_BASE, 256*1024);
>>> +	if (!vic_base) {
>>> +		pr_err("ioremap tegra210 VIC failed\n");
>>> +		return;
>>> +	}
>>> +
>>>  	clks = tegra_clk_init(clk_base, TEGRA210_CLK_CLK_MAX,
>>>  			      TEGRA210_CAR_BANK_COUNT);
>>>  	if (!clks)
>>> @@ -3233,6 +3622,8 @@ static void __init tegra210_clock_init(struct device_node *np)
>>>  	tegra_add_of_provider(np);
>>>  	tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
>>>  
>>> +	tegra210_mbist_clk_init();
>>> +
>>
>> Maybe add a print here if the mbist init fails and return. I understand
>> it may not be a critical failure but it should never fail.
>>
> 
> You mean have the entire clock init fail and undo all the clock registrations?
> That seems overkill to me. Returning early would only prevent some sleep states
> from working because tegra_cpu_car_ops will not be initialized then. So I would
> do a warning then.

I don't think it is necessary to undo it. Ok, don't worry about
returning an error here, the warnings should be sufficient.

Cheers
Jon

-- 
nvpublic

  parent reply	other threads:[~2018-01-25 10:19 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-23  9:22 [PATCH v3 0/4] MBIST work around (WAR) for Tegra210 Peter De Schrijver
2018-01-23  9:22 ` Peter De Schrijver
2018-01-23  9:22 ` [PATCH v3 1/4] clk: tegra: Add la clock " Peter De Schrijver
2018-01-23  9:22   ` Peter De Schrijver
     [not found]   ` <1516699369-3513-2-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2018-01-24 10:03     ` Jon Hunter
2018-01-24 10:03       ` Jon Hunter
     [not found]       ` <31118e4b-80bd-1db2-0a82-9359b99deccf-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2018-01-24 11:23         ` Peter De Schrijver
2018-01-24 11:23           ` Peter De Schrijver
2018-01-23  9:22 ` [PATCH v3 2/4] clk: tegra: add fence_delay for clock registers Peter De Schrijver
2018-01-23  9:22   ` Peter De Schrijver
2018-01-24 10:20   ` Jon Hunter
2018-01-24 10:20     ` Jon Hunter
2018-01-23  9:22 ` [PATCH v3 3/4] clk: tegra: MBIST work around for Tegra210 Peter De Schrijver
2018-01-23  9:22   ` Peter De Schrijver
2018-01-24 21:59   ` Jon Hunter
2018-01-24 21:59     ` Jon Hunter
     [not found]     ` <637b3bb4-1ac0-5612-ec2e-5740e611b11a-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2018-01-25  9:02       ` Peter De Schrijver
2018-01-25  9:02         ` Peter De Schrijver
     [not found]         ` <20180125090255.GK7031-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>
2018-01-25 10:19           ` Jon Hunter [this message]
2018-01-25 10:19             ` Jon Hunter
     [not found]             ` <a161a11c-1794-ebc4-3ff0-7624c23cabdb-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2018-01-25 12:41               ` Peter De Schrijver
2018-01-25 12:41                 ` Peter De Schrijver
     [not found]                 ` <20180125124157.GN7031-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>
2018-01-25 13:04                   ` Jon Hunter
2018-01-25 13:04                     ` Jon Hunter
2018-01-23  9:22 ` [PATCH v3 4/4] soc/tegra: pmc: apply MBIST work around fo Tegra210 Peter De Schrijver
2018-01-23  9:22   ` Peter De Schrijver
2018-01-24 22:43   ` Jon Hunter
2018-01-24 22:43     ` Jon Hunter
     [not found]     ` <cf919367-4521-25b1-1f80-16e2b660045e-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2018-01-25 10:06       ` Peter De Schrijver
2018-01-25 10:06         ` Peter De Schrijver
2018-01-25 10:57         ` Jon Hunter
2018-01-25 10:57           ` Jon Hunter
     [not found]           ` <fe422430-cb85-c28d-404b-98e7b87c15e0-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2018-01-25 12:26             ` Peter De Schrijver
2018-01-25 12:26               ` Peter De Schrijver
     [not found]               ` <20180125122613.GM7031-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>
2018-01-25 13:07                 ` Jon Hunter
2018-01-25 13:07                   ` Jon Hunter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a161a11c-1794-ebc4-3ff0-7624c23cabdb@nvidia.com \
    --to=jonathanh-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
    --cc=linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.