lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <cb54bd3f-f887-3923-4ac9-224c643afe17@codeaurora.org>
Date:   Tue, 22 Nov 2016 00:59:11 +0530
From:   Avaneesh Kumar Dwivedi <akdwived@...eaurora.org>
To:     Bjorn Andersson <bjorn.andersson@...aro.org>
Cc:     linux-kernel@...r.kernel.org, linux-remoteproc@...r.kernel.org,
        linux-arm-msm@...r.kernel.org
Subject: Re: [PATCH v3 2/3] remoteproc: qcom: Hexagon resource handling



On 11/19/2016 1:00 AM, Bjorn Andersson wrote:
> On Wed 16 Nov 07:17 PST 2016, Avaneesh Kumar Dwivedi wrote:
>
>>
>> On 11/8/2016 12:19 PM, Bjorn Andersson wrote:
>>> On Mon 07 Nov 04:37 PST 2016, Avaneesh Kumar Dwivedi wrote:
>>>
>>>> Handling of clock and regulator resources as well as reset
>>>> register programing differ according to version of hexagon
>>>> dsp hardware. Different version require different resources
>>>> and different parameters for same resource. Hence it is
>>>> needed that resource handling is generic and independent of
>>>> hexagon dsp version.
>>>>
>>> It would be much easier to review this if you didn't do all three
>>> changes in the same patch, and at the same time changed the function
>>> names. There's large parts of this patch where it's not obvious what the
>>> actual changes are.
>> OK, have broken patches in very small set of function now.
>> but patches has increased from 3 to 9.
>> sorry for inconvenience caused.
> I will have a look once we have agreed on below issues.
>
> [..]
>>>> +	struct regulator **active_regs;
>>> Keeping these as statically sized arrays, potentially with unused
>>> elements at the end removes the need for allocating the storage and the
>>> double pointers.
>> since i do not know how many resource of a particular type will be needed on
>> new version of new class of hexagon that is why i am working with pointers.
>> have removed many entries from above resource struct, it will lok much
>> cleaner in next patchset.
> Just pick the largest number we support right now and then if future
> versions need more we increment that number.
OK
>
>>>>   	struct completion start_done;
>>>>   	struct completion stop_done;
>>>> @@ -147,67 +150,245 @@ struct q6v5 {
>>>>   	phys_addr_t mpss_reloc;
>>>>   	void *mpss_region;
>>>>   	size_t mpss_size;
>>>> +	struct mutex q6_lock;
>>>> +	bool proxy_unvote_reg;
>>>> +	bool proxy_unvote_clk;
>>> I still don't see the need for these 3 attributes.
>> I agree, Have removed them.
>>>>   };
>>>> -enum {
>>>> -	Q6V5_SUPPLY_CX,
>>>> -	Q6V5_SUPPLY_MX,
>>>> -	Q6V5_SUPPLY_MSS,
>>>> -	Q6V5_SUPPLY_PLL,
>>>> -};
>>>> +static int q6_regulator_init(struct q6v5 *qproc)
>>>> +{
>>>> +	struct regulator **reg_arr;
>>>> +	int i;
>>>> +
>>>> +	if (qproc->q6_rproc_res->proxy_reg_cnt) {
>>> If you keep proxy_regs and active_regs as arrays you don't need this
>>> check.
>> Agree, have removed check.
>>>> +		reg_arr = devm_kzalloc(qproc->dev,
>>>> +		sizeof(reg_arr) * qproc->q6_rproc_res->proxy_reg_cnt,
>>>> +		GFP_KERNEL);
>>>> +
>>>> +		for (i = 0; i < qproc->q6_rproc_res->proxy_reg_cnt; i++) {
>>>> +			reg_arr[i] = devm_regulator_get(qproc->dev,
>>>> +			qproc->q6_rproc_res->proxy_regs[i]);
>>>> +			if (IS_ERR(reg_arr[i]))
>>>> +				return PTR_ERR(reg_arr[i]);
>>>> +			qproc->proxy_regs = reg_arr;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	if (qproc->q6_rproc_res->active_reg_cnt) {
>>>> +		reg_arr = devm_kzalloc(qproc->dev,
>>>> +		sizeof(reg_arr) * qproc->q6_rproc_res->active_reg_cnt,
>>>> +		GFP_KERNEL);
>>>> +
>>>> +		for (i = 0; i < qproc->q6_rproc_res->active_reg_cnt; i++) {
>>>> +			reg_arr[i] = devm_regulator_get(qproc->dev,
>>>> +			qproc->q6_rproc_res->active_regs[i]);
>>>> +
>>>> +			if (IS_ERR(reg_arr[i]))
>>>> +				return PTR_ERR(reg_arr[i]);
>>>> +			qproc->active_regs = reg_arr;
>>>> +		}
>>>> +	}
>>> Please keep active_regs and proxy_regs as regulator_bulk_data and
>>> continue to use devm_regulator_bulk_get(), it should make this code
>>> cleaner.
>> the way i have reorganized code in next patchset i found using
>> devm_regulator_get() more convenient, can i keep using them? as i am reading
>> string one by one and based on read string filling a regulator struct with
>> its voltage and load and handle info.
> If it's cleaner, then sure
OK
>
>>>> +
>>>> +	return 0;
>>>> +}
>>>> -static int q6v5_regulator_init(struct q6v5 *qproc)
>>>> +static int q6_proxy_regulator_enable(struct q6v5 *qproc)
>>>>   {
>>>> -	int ret;
>>>> +	int i, j, ret = 0;
>>>> +	int **reg_loadnvoltsetflag;
>>>> +	int *reg_load;
>>>> +	int *reg_voltage;
>>>> +
>>>> +	reg_loadnvoltsetflag = qproc->q6_rproc_res->proxy_reg_action;
>>>> +	reg_load = qproc->q6_rproc_res->proxy_reg_load;
>>>> +	reg_voltage = qproc->q6_rproc_res->proxy_reg_voltage;
>>> Rather then keeping these properties on int-arrays I strongly prefer
>>> that you would have a struct { uV, uA } for each regulator.
>> Have modified as per suggestion.
>>>> +
>>>> +	for (i = 0; i < qproc->q6_rproc_res->proxy_reg_cnt; i++) {
>>>> +		for (j = 0; j <= 1; j++) {
>>>> +			if (j == 0 && *(reg_loadnvoltsetflag + i*j + j))
>>> I'm sorry, but this is not clean. Please use the fact that we're not
>>> writing assembly code and use the language to your advantage.
>> Sorry for mess, have simplified and cleaned.
>>>> +				regulator_set_load(qproc->proxy_regs[i],
>>>> +				reg_load[i]);
>>>> +			if (j == 1 && *(reg_loadnvoltsetflag + i*j + j))
>>>> +				regulator_set_voltage(qproc->proxy_regs[i],
>>>> +				reg_voltage[i], INT_MAX);
>>>> +		}
>>>> +	}
>>>> -	qproc->supply[Q6V5_SUPPLY_CX].supply = "cx";
>>>> -	qproc->supply[Q6V5_SUPPLY_MX].supply = "mx";
>>>> -	qproc->supply[Q6V5_SUPPLY_MSS].supply = "mss";
>>>> -	qproc->supply[Q6V5_SUPPLY_PLL].supply = "pll";
>>>> +	for (i = 0; i < qproc->q6_rproc_res->proxy_reg_cnt; i++) {
>>>> +		ret = regulator_enable(qproc->proxy_regs[i]);
>>>> +		if (ret) {
>>>> +			for (; i > 0; --i) {
>>>> +				regulator_disable(qproc->proxy_regs[i]);
>>>> +				return ret;
>>>> +			}
>>>> +		}
>>>> +	}
>>> If you just keep your regulators in a regulator_bulk_data array then you
>>> can replace this with regulator_bulk_enable(proxy_reg_cnt, proxy_regs);
>> As replied above i am going with getting sigle regulator handle one time.
>> let me know if i can continue or need to change?
>>
> The reason for using the bulk operations is that the error path becomes
> cleaner, however now that I look at this again; in the event of an error
> you leave the regulators with voltage and load specified. You need to
> unroll this too.
if regulator enabled failed, i am unrolling the programmed load and 
voltage setting.
but i will try to incorporate your suggestion.
>
> But I would still prefer that you specify the loads & voltages, then
> call bulk_enable() and if that fail remove all load and voltage
> requests.
OK, will try to incorporate.
>
>>>> -	ret = devm_regulator_bulk_get(qproc->dev,
>>>> -				      ARRAY_SIZE(qproc->supply), qproc->supply);
>>>> -	if (ret < 0) {
>>>> -		dev_err(qproc->dev, "failed to get supplies\n");
>>>> -		return ret;
> [..]
>>>> +	if (!strcmp(qproc->q6_rproc_res->q6_version, "v56")) {
>>> This would be much better as an enum than a string. But I keep wonder if
>>> this is only for v5.6 of the Hexagon - perhaps should we clamp different
>>> things on the various versions?.
>> As replied elsewhere, we need a DT entry to know which version is running,
>> or else many compatible string will be required. for "v56" there are
>> following version, so as and when we need to support a new version we will
>> require
>> a new DT entry which when defined will help to take deviation where
>> required.
>> 1.10.0
>> 1.3.0
>> 1.4.0
>> 1.5.0
>> 1.6.0
>> 1.8.0
>>
> Sorry for not seeing this before I answered in the two other places,
> perhaps we should just discuss this to end in one place...
>
> But regarding my specific comment, if you want class based handling then
> introduce:
>
> enum {
> 	Q6V5_CLASS5,
> 	Q6V5_CLASS55,
> 	Q5V5_CLASS56
> };
>
> Then you don't have to use strcmp() to check which class you have.
OK, may i change enum strings as per HPG?

enum {
	Q6V5_5_0_0,--->8916
	Q6V5_5_1_1,---->8974
	Q5V56_1_5_0---->8996
};



>
>>>> +		/*
>>>> +		 * Assert QDSP6 I/O clamp, memory wordline clamp, and compiler
>>>> +		 * memory clamp as a software workaround to avoid high MX
>>>> +		 * current during LPASS/MSS restart.
>>>> +		 */
>>>> +
>>>> +		val = readl_relaxed(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
>>>> +		val |= (Q6SS_CLAMP_IO | QDSP6v56_CLAMP_WL |
>>>> +				QDSP6v56_CLAMP_QMC_MEM);
>>>> +		writel_relaxed(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
>>>> +		pil_mss_restart_reg(qproc, 1);
>>> And by using the reset framework for mss_restart this will fall out of
>>> the conditional segment and the else is gone.
>> As i informed MSS RESET REGISTER was never a block control reset or BCR (a
>> term used to define those reset register which control a clock or pll ) so
>> clock control reset framework can not be used to do reset programming for
>> MSS
> But MSS RESET is a "reset" and far as this driver is concerned it should
> be abstracted by the help of the reset framework. I don't want this
> driver to care about the workings of the reset control.
>
> The peripheral resets are part of the GCC block and as such I do not see
> the problem with having the driver for the GCC block expose these
> resets, even if though it's not a BCR - and this is how we have done it
> on 8960, 8974 and 8084 so far.
I was under impression that clock code will be up streamed by clock 
team, and they will go by downstream way.
i discussed again they said i can use GCC reset framework in upstream.
Will change patch accordingly.
>
>> that is why i have adopted IOREMAP based mss reset programming. it is like
>> any other register, may i know if any serious objection on using reset
>> controller framework only? i will have to add another dummy driver just to
>> do reset register programming.
>> let me know please if it is mandatory?
> I want this driver to consume a reset from a reset-controller, I do not
> see the technical reason why we cannot just add this to the driver for
> the GCC block.
Sure, will do.
>
> Regards,
> Bjorn

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ