diff options
Diffstat (limited to 'drivers/soc/qcom/llcc-qcom.c')
-rw-r--r-- | drivers/soc/qcom/llcc-qcom.c | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index cbef0dea1d5d..37e11e501728 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -7,6 +7,7 @@ #include <linux/bitfield.h> #include <linux/bitmap.h> #include <linux/bitops.h> +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/io.h> #include <linux/kernel.h> @@ -150,6 +151,25 @@ enum llcc_reg_offset { LLCC_COMMON_STATUS0, }; +static const struct llcc_slice_config sa8775p_data[] = { + {LLCC_CPUSS, 1, 2048, 1, 0, 0x00FF, 0x0, 0, 0, 0, 1, 1, 0, 0}, + {LLCC_VIDSC0, 2, 512, 3, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_CPUSS1, 3, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_CPUHWT, 5, 512, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_AUDIO, 6, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 0, 0, 0, 0}, + {LLCC_CMPT, 10, 4096, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_GPUHTW, 11, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_GPU, 12, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 1, 0}, + {LLCC_MMUHWT, 13, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 0, 1, 0, 0}, + {LLCC_CMPTDMA, 15, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_DISP, 16, 4096, 2, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_VIDFW, 17, 3072, 1, 0, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_AUDHW, 22, 1024, 1, 1, 0x00FF, 0x0, 0, 0, 0, 0, 0, 0, 0}, + {LLCC_CVP, 28, 256, 3, 1, 0x00FF, 0x0, 0, 0, 0, 1, 0, 0, 0}, + {LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0xF0, 1, 0, 0, 1, 0, 0, 0}, + {LLCC_WRCACHE, 31, 512, 1, 1, 0x00FF, 0x0, 0, 0, 0, 0, 1, 0, 0}, +}; + static const struct llcc_slice_config sc7180_data[] = { { LLCC_CPUSS, 1, 256, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 1 }, { LLCC_MDM, 8, 128, 1, 0, 0xf, 0x0, 0, 0, 0, 1, 0 }, @@ -552,6 +572,16 @@ static const struct qcom_llcc_config qdu1000_cfg[] = { }, }; +static const struct qcom_llcc_config sa8775p_cfg[] = { + { + .sct_data = sa8775p_data, + .size = ARRAY_SIZE(sa8775p_data), + .need_llcc_cfg = true, + .reg_offset = llcc_v2_1_reg_offset, + .edac_reg_offset = &llcc_v2_1_edac_reg_offset, + }, +}; + static const struct qcom_llcc_config sc7180_cfg[] = { { .sct_data = sc7180_data, @@ -698,6 +728,11 @@ static const struct qcom_sct_config qdu1000_cfgs = { .num_config = ARRAY_SIZE(qdu1000_cfg), }; +static const struct qcom_sct_config sa8775p_cfgs = { + .llcc_config = sa8775p_cfg, + .num_config = ARRAY_SIZE(sa8775p_cfg), +}; + static const struct qcom_sct_config sc7180_cfgs = { .llcc_config = sc7180_cfg, .num_config = ARRAY_SIZE(sc7180_cfg), @@ -821,6 +856,7 @@ EXPORT_SYMBOL_GPL(llcc_slice_putd); static int llcc_update_act_ctrl(u32 sid, u32 act_ctrl_reg_val, u32 status) { + struct regmap *regmap; u32 act_ctrl_reg; u32 act_clear_reg; u32 status_reg; @@ -849,7 +885,8 @@ static int llcc_update_act_ctrl(u32 sid, return ret; if (drv_data->version >= LLCC_VERSION_4_1_0_0) { - ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg, + regmap = drv_data->bcast_and_regmap ?: drv_data->bcast_regmap; + ret = regmap_read_poll_timeout(regmap, status_reg, slice_status, (slice_status & ACT_COMPLETE), 0, LLCC_STATUS_READ_DELAY); if (ret) @@ -1258,16 +1295,13 @@ static int qcom_llcc_probe(struct platform_device *pdev) /* Initialize rest of LLCC bank regmaps */ for (i = 1; i < num_banks; i++) { - char *base = kasprintf(GFP_KERNEL, "llcc%d_base", i); + char *base __free(kfree) = kasprintf(GFP_KERNEL, "llcc%d_base", i); drv_data->regmaps[i] = qcom_llcc_init_mmio(pdev, i, base); if (IS_ERR(drv_data->regmaps[i])) { ret = PTR_ERR(drv_data->regmaps[i]); - kfree(base); goto err; } - - kfree(base); } drv_data->bcast_regmap = qcom_llcc_init_mmio(pdev, i, "llcc_broadcast_base"); @@ -1284,6 +1318,18 @@ static int qcom_llcc_probe(struct platform_device *pdev) drv_data->version = version; + /* Applicable only when drv_data->version >= 4.1 */ + if (drv_data->version >= LLCC_VERSION_4_1_0_0) { + drv_data->bcast_and_regmap = qcom_llcc_init_mmio(pdev, i + 1, "llcc_broadcast_and_base"); + if (IS_ERR(drv_data->bcast_and_regmap)) { + ret = PTR_ERR(drv_data->bcast_and_regmap); + if (ret == -EINVAL) + drv_data->bcast_and_regmap = NULL; + else + goto err; + } + } + llcc_cfg = cfg->sct_data; sz = cfg->size; @@ -1332,6 +1378,7 @@ err: static const struct of_device_id qcom_llcc_of_match[] = { { .compatible = "qcom,qdu1000-llcc", .data = &qdu1000_cfgs}, + { .compatible = "qcom,sa8775p-llcc", .data = &sa8775p_cfgs }, { .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfgs }, { .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfgs }, { .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfgs }, |