From 8f8f5ba4da25c1e35afac652109a44e38c435af2 Mon Sep 17 00:00:00 2001 From: Venkata Narendra Kumar Gutta Date: Wed, 5 Dec 2018 17:01:57 -0800 Subject: [PATCH] drivers: llcc: Support targets that can write to llcc registers For older targets, it is possible that they are not allowed to configure certain llcc registers, as that is handled by the secure side. However, this is not the case for newer targets, and as such, 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. Allow configuration of registers to enable capacity based allocation and power collapse retention for capable targets. Squashed commit: drivers: llcc: Check the return value after write Check the return value after writing to power collapse and capacity based allocation registers. Change-Id: I2106f98812a9369f1fdb7e20453741f1375c0a58 Signed-off-by: Isaac J. Manjarres [vgutta@codeaurora.org: Resolved trivial merge conflicts] Signed-off-by: Venkata Narendra Kumar Gutta [rananta@codeaurora.org: Resolved trivial merge conflicts] Signed-off-by: Raghavendra Rao Ananta --- drivers/soc/qcom/llcc-slice.c | 39 +++++++++++++++++++++++++++--- include/linux/soc/qcom/llcc-qcom.h | 1 + 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c index 9090ea12eaf3..f405f34790cb 100644 --- a/drivers/soc/qcom/llcc-slice.c +++ b/drivers/soc/qcom/llcc-slice.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * */ @@ -44,7 +44,13 @@ #define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n) #define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n) -#define BANK_OFFSET_STRIDE 0x80000 +#define LLCC_TRP_WRSC_EN 0x21F20 +#define LLCC_WRSC_SCID_EN(n) BIT(n) + +#define LLCC_TRP_PCB_ACT 0x21F04 +#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21F00 + +#define BANK_OFFSET_STRIDE 0x80000 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; @@ -251,9 +257,13 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev) u32 attr0_val; u32 max_cap_cacheline; u32 sz; + u32 pcb = 0; + u32 cad = 0; int ret = 0; const struct llcc_slice_config *llcc_table; struct llcc_slice_desc desc; + bool cap_based_alloc_and_pwr_collapse = + drv_data->cap_based_alloc_and_pwr_collapse; sz = drv_data->cfg_size; llcc_table = drv_data->cfg; @@ -293,6 +303,23 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev) attr0_val); if (ret) return ret; + + if (cap_based_alloc_and_pwr_collapse) { + cad |= llcc_table[i].dis_cap_alloc << + llcc_table[i].slice_id; + ret = regmap_write(drv_data->bcast_regmap, + LLCC_TRP_SCID_DIS_CAP_ALLOC, cad); + if (ret) + return ret; + + pcb |= llcc_table[i].retain_on_pc << + llcc_table[i].slice_id; + ret = regmap_write(drv_data->bcast_regmap, + LLCC_TRP_PCB_ACT, pcb); + if (ret) + return ret; + } + if (llcc_table[i].activate_on_init) { desc.slice_id = llcc_table[i].slice_id; ret = llcc_slice_activate(&desc); @@ -373,6 +400,10 @@ int qcom_llcc_probe(struct platform_device *pdev, goto err; } + drv_data->cap_based_alloc_and_pwr_collapse = + of_property_read_bool(pdev->dev.of_node, + "cap-based-alloc-and-pwr-collapse"); + for (i = 0; i < num_banks; i++) drv_data->offsets[i] = i * BANK_OFFSET_STRIDE; @@ -390,8 +421,10 @@ int qcom_llcc_probe(struct platform_device *pdev, platform_set_drvdata(pdev, drv_data); ret = qcom_llcc_cfg_program(pdev); - if (ret) + if (ret) { + pr_err("llcc configuration failed!!\n"); goto err; + } drv_data->ecc_irq = platform_get_irq(pdev, 0); if (drv_data->ecc_irq >= 0) { diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index eb71a50b8afc..ec76d70ba593 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -91,6 +91,7 @@ struct llcc_drv_data { unsigned long *bitmap; u32 *offsets; int ecc_irq; + bool cap_based_alloc_and_pwr_collapse; }; /**