[PATCH 5/6] soc: qcom: qpace: Add LLCC slice support

From: Georgi Djakov

Date: Wed Sep 30 2026 - 13:29:36 EST


QPaCE can use dedicated LLCC slices for compression and decompression, but
the driver currently does not request or enable them. This leaves platforms
with QPaCE LLCC support running without the intended cache allocation.

Add the QPaCE LLCC slice IDs and make the driver request and activate the
slices.

Signed-off-by: Georgi Djakov <georgi.djakov@xxxxxxxxxxxxxxxx>
---
drivers/soc/qcom/qpace.c | 58 ++++++++++++++++++++++++++++--
include/linux/soc/qcom/llcc-qcom.h | 2 ++
2 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/qcom/qpace.c b/drivers/soc/qcom/qpace.c
index f5b21ffbcbff..86a935ae2ca9 100644
--- a/drivers/soc/qcom/qpace.c
+++ b/drivers/soc/qcom/qpace.c
@@ -18,6 +18,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_qos.h>
+#include <linux/soc/qcom/llcc-qcom.h>
#include <linux/soc/qcom/qpace.h>
#include <linux/workqueue.h>

@@ -42,6 +43,8 @@ struct qpace_priv {

struct icc_path *interconnect;
struct pm_qos_request qos_req;
+ struct llcc_slice_desc *llc_comp;
+ struct llcc_slice_desc *llc_decomp;

int active_rings;
struct completion no_active_refs;
@@ -660,9 +663,35 @@ static int qpace_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "failed to map QPaCE registers\n");

+ priv->llc_comp = llcc_slice_getd(LLCC_QPACE_COMPRESSION);
+ if (IS_ERR(priv->llc_comp))
+ return dev_err_probe(dev, PTR_ERR(priv->llc_comp),
+ "failed to get compression LLCC slice\n");
+
+ priv->llc_decomp = llcc_slice_getd(LLCC_QPACE_DECOMPRESSION);
+ if (IS_ERR(priv->llc_decomp)) {
+ ret = dev_err_probe(dev, PTR_ERR(priv->llc_decomp),
+ "failed to get decompression LLCC slice\n");
+ priv->llc_decomp = NULL;
+ goto llc_put_comp;
+ }
+
+ ret = llcc_slice_activate(priv->llc_comp);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to activate compression LLCC slice\n");
+ goto llc_put_decomp;
+ }
+
+ ret = llcc_slice_activate(priv->llc_decomp);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to activate decompression LLCC slice\n");
+ goto llc_deactivate_comp;
+ }
ret = qpace_power_on(dev);
- if (ret)
- return dev_err_probe(dev, ret, "failed to power on QPaCE\n");
+ if (ret) {
+ dev_err(dev, "failed to power on QPaCE\n");
+ goto llc_deactivate_decomp;
+ }

/* Get QPaCE HW version. */
qpace_priv->hw_version = qpace_read_gen(qpace_priv, QPACE_CORE_HW_VERSION_OFFSET);
@@ -691,6 +720,14 @@ static int qpace_probe(struct platform_device *pdev)

power_off:
qpace_power_off(dev);
+llc_deactivate_decomp:
+ llcc_slice_deactivate(priv->llc_decomp);
+llc_deactivate_comp:
+ llcc_slice_deactivate(priv->llc_comp);
+llc_put_decomp:
+ llcc_slice_putd(priv->llc_decomp);
+llc_put_comp:
+ llcc_slice_putd(priv->llc_comp);

return ret;
}
@@ -708,6 +745,10 @@ static void qpace_remove(struct platform_device *pdev)
/* No callers remain; tear down the hardware. */
cancel_work_sync(&qpace_priv->disable_work);
qpace_power_off(&pdev->dev);
+ llcc_slice_deactivate(qpace_priv->llc_decomp);
+ llcc_slice_deactivate(qpace_priv->llc_comp);
+ llcc_slice_putd(qpace_priv->llc_decomp);
+ llcc_slice_putd(qpace_priv->llc_comp);
}

static const struct of_device_id qpace_match_table[] = {
@@ -729,6 +770,9 @@ static int qpace_suspend(struct device *dev)
return -EBUSY;
}

+ llcc_slice_deactivate(qpace_priv->llc_comp);
+ llcc_slice_deactivate(qpace_priv->llc_decomp);
+
mutex_unlock(&qpace_ref_lock);
return 0;
}
@@ -746,6 +790,16 @@ static int qpace_resume(struct device *dev)
if (ret)
goto out_unlock;

+ ret = llcc_slice_activate(qpace_priv->llc_comp);
+ if (ret)
+ goto out_unlock;
+
+ ret = llcc_slice_activate(qpace_priv->llc_decomp);
+ if (ret) {
+ llcc_slice_deactivate(qpace_priv->llc_comp);
+ goto out_unlock;
+ }
+
program_urg_command_contexts_v2();
program_decomp_core_cfg();

diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index 713cb0221b14..feddbebf1183 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -85,6 +85,8 @@
#define LLCC_CAM_IPE_STROV 92
#define LLCC_CAM_OFE_STROV 93
#define LLCC_CPUSS_HEU 94
+#define LLCC_QPACE_COMPRESSION 95
+#define LLCC_QPACE_DECOMPRESSION 96
#define LLCC_PCIE_TCU 97
#define LLCC_GPUHTW_LITTLE 98
#define LLCC_MDM_PNG_FIXED 100