qcom: llcc/edac: Fix the base address used for accessing LLCC banks
[platform/kernel/linux-starfive.git] / drivers / soc / qcom / llcc-qcom.c
index d4cba3b..85219b5 100644 (file)
@@ -50,8 +50,6 @@
 #define LLCC_TRP_WRSC_EN              0x21f20
 #define LLCC_TRP_WRSC_CACHEABLE_EN    0x21f2c
 
-#define BANK_OFFSET_STRIDE           0x80000
-
 #define LLCC_VERSION_2_0_0_0          0x02000000
 #define LLCC_VERSION_2_1_0_0          0x02010000
 
@@ -749,8 +747,8 @@ static int qcom_llcc_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
-               const char *name)
+static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, u8 index,
+                                         const char *name)
 {
        void __iomem *base;
        struct regmap_config llcc_regmap_config = {
@@ -760,7 +758,7 @@ static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev,
                .fast_io = true,
        };
 
-       base = devm_platform_ioremap_resource_byname(pdev, name);
+       base = devm_platform_ioremap_resource(pdev, index);
        if (IS_ERR(base))
                return ERR_CAST(base);
 
@@ -778,6 +776,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
        const struct llcc_slice_config *llcc_cfg;
        u32 sz;
        u32 version;
+       struct regmap *regmap;
 
        drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
        if (!drv_data) {
@@ -785,21 +784,51 @@ static int qcom_llcc_probe(struct platform_device *pdev)
                goto err;
        }
 
-       drv_data->regmap = qcom_llcc_init_mmio(pdev, "llcc_base");
-       if (IS_ERR(drv_data->regmap)) {
-               ret = PTR_ERR(drv_data->regmap);
+       /* Initialize the first LLCC bank regmap */
+       regmap = qcom_llcc_init_mmio(pdev, 0, "llcc0_base");
+       if (IS_ERR(regmap)) {
+               ret = PTR_ERR(regmap);
                goto err;
        }
 
-       drv_data->bcast_regmap =
-               qcom_llcc_init_mmio(pdev, "llcc_broadcast_base");
+       cfg = of_device_get_match_data(&pdev->dev);
+
+       ret = regmap_read(regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], &num_banks);
+       if (ret)
+               goto err;
+
+       num_banks &= LLCC_LB_CNT_MASK;
+       num_banks >>= LLCC_LB_CNT_SHIFT;
+       drv_data->num_banks = num_banks;
+
+       drv_data->regmaps = devm_kcalloc(dev, num_banks, sizeof(*drv_data->regmaps), GFP_KERNEL);
+       if (!drv_data->regmaps) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       drv_data->regmaps[0] = regmap;
+
+       /* Initialize rest of LLCC bank regmaps */
+       for (i = 1; i < num_banks; i++) {
+               char *base = 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");
        if (IS_ERR(drv_data->bcast_regmap)) {
                ret = PTR_ERR(drv_data->bcast_regmap);
                goto err;
        }
 
-       cfg = of_device_get_match_data(&pdev->dev);
-
        /* Extract version of the IP */
        ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO],
                          &version);
@@ -808,15 +837,6 @@ static int qcom_llcc_probe(struct platform_device *pdev)
 
        drv_data->version = version;
 
-       ret = regmap_read(drv_data->regmap, cfg->reg_offset[LLCC_COMMON_STATUS0],
-                         &num_banks);
-       if (ret)
-               goto err;
-
-       num_banks &= LLCC_LB_CNT_MASK;
-       num_banks >>= LLCC_LB_CNT_SHIFT;
-       drv_data->num_banks = num_banks;
-
        llcc_cfg = cfg->sct_data;
        sz = cfg->size;
 
@@ -824,16 +844,6 @@ static int qcom_llcc_probe(struct platform_device *pdev)
                if (llcc_cfg[i].slice_id > drv_data->max_slices)
                        drv_data->max_slices = llcc_cfg[i].slice_id;
 
-       drv_data->offsets = devm_kcalloc(dev, num_banks, sizeof(u32),
-                                                       GFP_KERNEL);
-       if (!drv_data->offsets) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       for (i = 0; i < num_banks; i++)
-               drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
-
        drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices,
                                              GFP_KERNEL);
        if (!drv_data->bitmap) {