mbox series

[PATCHv5,0/2] soc: qcom: llcc: Support chipsets that can write to llcc regs

Message ID cover.1600151951.git.saiprakash.ranjan@codeaurora.org
Headers show
Series soc: qcom: llcc: Support chipsets that can write to llcc regs | expand

Message

Sai Prakash Ranjan Sept. 15, 2020, 6:55 a.m. UTC
Older chipsets may not be allowed to configure certain LLCC registers
as that is handled by the secure side software. However, this is not
the case for newer chipsets and they must configure these registers
according to the contents of the SCT table, while keeping in mind that
older targets may not have these capabilities. So add support to allow
such configuration of registers to enable capacity based allocation
and power collapse retention for capable chipsets.

Reason for choosing capacity based allocation rather than the default
way based allocation is because capacity based allocation allows more
finer grain partition and provides more flexibility in configuration.
As for the retention through power collapse, it has an advantage where
the cache hits are more when we wake up from power collapse although
it does burn more power but the exact power numbers are not known at
the moment.

Patch 1 is a cleanup to separate out llcc configuration to its own function.
Patch 2 adds support for chipsets capable of writing to llcc registers.

Changes in v5:
 * Move all config from qcom_llcc_cfg_program() (Stephen)
 * Minor code adjustments (Stephen)

Changes in v4:
 * Separate out llcc attribute config to its own function (Stephen)
 * Pass qcom_llcc_config instead of a new llcc_drvdata property (Doug)

Changes in v3:
 * Drop separate table and use existing qcom_llcc_config (Doug)
 * More descriptive commit msg (Doug)
 * Directly set the config instead of '|=' (Doug)

Changes in v2:
 * Fix build errors reported by kernel test robot.

Isaac J. Manjarres (1):
  soc: qcom: llcc: Support chipsets that can write to llcc

Sai Prakash Ranjan (1):
  soc: qcom: llcc: Move llcc configuration to its own function

 drivers/soc/qcom/llcc-qcom.c | 115 +++++++++++++++++++++++------------
 1 file changed, 75 insertions(+), 40 deletions(-)


base-commit: a1fb300d3fe5b038f5c436265c7265009016d234

Comments

Bjorn Andersson Sept. 15, 2020, 4:01 p.m. UTC | #1
On Tue 15 Sep 06:55 UTC 2020, Sai Prakash Ranjan wrote:

> Cleanup qcom_llcc_cfg_program() by moving llcc configuration
> to a separate function of its own. Also correct misspelled
> 'instance' caught by checkpatch.
> 
> Suggested-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

> ---
>  drivers/soc/qcom/llcc-qcom.c | 89 ++++++++++++++++++++----------------
>  1 file changed, 50 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
> index 429b5a60a1ba..14311060099d 100644
> --- a/drivers/soc/qcom/llcc-qcom.c
> +++ b/drivers/soc/qcom/llcc-qcom.c
> @@ -318,62 +318,73 @@ size_t llcc_get_slice_size(struct llcc_slice_desc *desc)
>  }
>  EXPORT_SYMBOL_GPL(llcc_get_slice_size);
>  
> -static int qcom_llcc_cfg_program(struct platform_device *pdev)
> +static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config)
>  {
> -	int i;
> +	int ret;
>  	u32 attr1_cfg;
>  	u32 attr0_cfg;
>  	u32 attr1_val;
>  	u32 attr0_val;
>  	u32 max_cap_cacheline;
> +	struct llcc_slice_desc desc;
> +
> +	attr1_val = config->cache_mode;
> +	attr1_val |= config->probe_target_ways << ATTR1_PROBE_TARGET_WAYS_SHIFT;
> +	attr1_val |= config->fixed_size << ATTR1_FIXED_SIZE_SHIFT;
> +	attr1_val |= config->priority << ATTR1_PRIORITY_SHIFT;
> +
> +	max_cap_cacheline = MAX_CAP_TO_BYTES(config->max_cap);
> +
> +	/*
> +	 * LLCC instances can vary for each target.
> +	 * The SW writes to broadcast register which gets propagated
> +	 * to each llcc instance (llcc0,.. llccN).
> +	 * Since the size of the memory is divided equally amongst the
> +	 * llcc instances, we need to configure the max cap accordingly.
> +	 */
> +	max_cap_cacheline = max_cap_cacheline / drv_data->num_banks;
> +	max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT;
> +	attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT;
> +
> +	attr1_cfg = LLCC_TRP_ATTR1_CFGn(config->slice_id);
> +
> +	ret = regmap_write(drv_data->bcast_regmap, attr1_cfg, attr1_val);
> +	if (ret)
> +		return ret;
> +
> +	attr0_val = config->res_ways & ATTR0_RES_WAYS_MASK;
> +	attr0_val |= config->bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
> +
> +	attr0_cfg = LLCC_TRP_ATTR0_CFGn(config->slice_id);
> +
> +	ret = regmap_write(drv_data->bcast_regmap, attr0_cfg, attr0_val);
> +	if (ret)
> +		return ret;
> +
> +	if (config->activate_on_init) {
> +		desc.slice_id = config->slice_id;
> +		ret = llcc_slice_activate(&desc);
> +	}
> +
> +	return ret;
> +}
> +
> +static int qcom_llcc_cfg_program(struct platform_device *pdev)
> +{
> +	int i;
>  	u32 sz;
>  	int ret = 0;
>  	const struct llcc_slice_config *llcc_table;
> -	struct llcc_slice_desc desc;
>  
>  	sz = drv_data->cfg_size;
>  	llcc_table = drv_data->cfg;
>  
>  	for (i = 0; i < sz; i++) {
> -		attr1_cfg = LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
> -		attr0_cfg = LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
> -
> -		attr1_val = llcc_table[i].cache_mode;
> -		attr1_val |= llcc_table[i].probe_target_ways <<
> -				ATTR1_PROBE_TARGET_WAYS_SHIFT;
> -		attr1_val |= llcc_table[i].fixed_size <<
> -				ATTR1_FIXED_SIZE_SHIFT;
> -		attr1_val |= llcc_table[i].priority <<
> -				ATTR1_PRIORITY_SHIFT;
> -
> -		max_cap_cacheline = MAX_CAP_TO_BYTES(llcc_table[i].max_cap);
> -
> -		/* LLCC instances can vary for each target.
> -		 * The SW writes to broadcast register which gets propagated
> -		 * to each llcc instace (llcc0,.. llccN).
> -		 * Since the size of the memory is divided equally amongst the
> -		 * llcc instances, we need to configure the max cap accordingly.
> -		 */
> -		max_cap_cacheline = max_cap_cacheline / drv_data->num_banks;
> -		max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT;
> -		attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT;
> -
> -		attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK;
> -		attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
> -
> -		ret = regmap_write(drv_data->bcast_regmap, attr1_cfg,
> -					attr1_val);
> +		ret = _qcom_llcc_cfg_program(&llcc_table[i]);
>  		if (ret)
>  			return ret;
> -		ret = regmap_write(drv_data->bcast_regmap, attr0_cfg,
> -					attr0_val);
> -		if (ret)
> -			return ret;
> -		if (llcc_table[i].activate_on_init) {
> -			desc.slice_id = llcc_table[i].slice_id;
> -			ret = llcc_slice_activate(&desc);
> -		}
>  	}
> +
>  	return ret;
>  }
>  
> -- 
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
Stephen Boyd Sept. 15, 2020, 4:10 p.m. UTC | #2
Quoting Sai Prakash Ranjan (2020-09-14 23:55:25)
> Cleanup qcom_llcc_cfg_program() by moving llcc configuration
> to a separate function of its own. Also correct misspelled
> 'instance' caught by checkpatch.
> 
> Suggested-by: Stephen Boyd <swboyd@chromium.org>
> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Stephen Boyd Sept. 15, 2020, 4:11 p.m. UTC | #3
Quoting Sai Prakash Ranjan (2020-09-14 23:55:26)
> From: "Isaac J. Manjarres" <isaacm@codeaurora.org>
> 
> Older chipsets may not be allowed to configure certain LLCC registers
> as that is handled by the secure side software. However, this is not
> the case for newer chipsets and they must configure these registers
> according to the contents of the SCT table, while keeping in mind that
> older targets may not have these capabilities. So add support to allow
> such configuration of registers to enable capacity based allocation
> and power collapse retention for capable chipsets.
> 
> Reason for choosing capacity based allocation rather than the default
> way based allocation is because capacity based allocation allows more
> finer grain partition and provides more flexibility in configuration.
> As for the retention through power collapse, it has an advantage where
> the cache hits are more when we wake up from power collapse although
> it does burn more power but the exact power numbers are not known at
> the moment.
> 
> Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
> Reviewed-by: Douglas Anderson <dianders@chromium.org>
> [saiprakash.ranjan@codeaurora.org: use existing config and reword commit msg]
> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Sai Prakash Ranjan Oct. 26, 2020, 12:33 p.m. UTC | #4
Hi Bjorn,

On 2020-09-15 12:25, Sai Prakash Ranjan wrote:
> Older chipsets may not be allowed to configure certain LLCC registers
> as that is handled by the secure side software. However, this is not
> the case for newer chipsets and they must configure these registers
> according to the contents of the SCT table, while keeping in mind that
> older targets may not have these capabilities. So add support to allow
> such configuration of registers to enable capacity based allocation
> and power collapse retention for capable chipsets.
> 
> Reason for choosing capacity based allocation rather than the default
> way based allocation is because capacity based allocation allows more
> finer grain partition and provides more flexibility in configuration.
> As for the retention through power collapse, it has an advantage where
> the cache hits are more when we wake up from power collapse although
> it does burn more power but the exact power numbers are not known at
> the moment.
> 


Gentle ping!

Thanks,
Sai