aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>2018-09-12 14:06:32 -0400
committerAndy Gross <andy.gross@linaro.org>2018-09-13 16:53:51 -0400
commit7f9c136216c745099f36a4e0c3b2e63eedeb442f (patch)
tree9669e6d26c7aa64e486279f98fb4ac2e5b1ed23c
parent5b394b2ddf0347bef56e50c69a58773c94343ff3 (diff)
soc: qcom: Add broadcast base for Last Level Cache Controller (LLCC)
Currently, broadcast base is set to end of the LLCC banks, which may not be correct always. As the number of banks may vary for each chipset and the broadcast base could be at a different address as well. This info depends on the chipset, so get the broadcast base info from the device tree (DT). Add broadcast base in LLCC driver and use this for broadcast writes. Signed-off-by: Venkata Narendra Kumar Gutta <vnkgutta@codeaurora.org> Reviewed-by: Evan Green <evgreen@chromium.org> Signed-off-by: Andy Gross <andy.gross@linaro.org>
-rw-r--r--drivers/soc/qcom/llcc-slice.c55
-rw-r--r--include/linux/soc/qcom/llcc-qcom.h4
2 files changed, 35 insertions, 24 deletions
diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c
index 54063a31132f..08e3d388e153 100644
--- a/drivers/soc/qcom/llcc-slice.c
+++ b/drivers/soc/qcom/llcc-slice.c
@@ -106,22 +106,24 @@ static int llcc_update_act_ctrl(u32 sid,
106 u32 slice_status; 106 u32 slice_status;
107 int ret; 107 int ret;
108 108
109 act_ctrl_reg = drv_data->bcast_off + LLCC_TRP_ACT_CTRLn(sid); 109 act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid);
110 status_reg = drv_data->bcast_off + LLCC_TRP_STATUSn(sid); 110 status_reg = LLCC_TRP_STATUSn(sid);
111 111
112 /* Set the ACTIVE trigger */ 112 /* Set the ACTIVE trigger */
113 act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG; 113 act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG;
114 ret = regmap_write(drv_data->regmap, act_ctrl_reg, act_ctrl_reg_val); 114 ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
115 act_ctrl_reg_val);
115 if (ret) 116 if (ret)
116 return ret; 117 return ret;
117 118
118 /* Clear the ACTIVE trigger */ 119 /* Clear the ACTIVE trigger */
119 act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG; 120 act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG;
120 ret = regmap_write(drv_data->regmap, act_ctrl_reg, act_ctrl_reg_val); 121 ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg,
122 act_ctrl_reg_val);
121 if (ret) 123 if (ret)
122 return ret; 124 return ret;
123 125
124 ret = regmap_read_poll_timeout(drv_data->regmap, status_reg, 126 ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg,
125 slice_status, !(slice_status & status), 127 slice_status, !(slice_status & status),
126 0, LLCC_STATUS_READ_DELAY); 128 0, LLCC_STATUS_READ_DELAY);
127 return ret; 129 return ret;
@@ -226,16 +228,13 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev)
226 int ret; 228 int ret;
227 const struct llcc_slice_config *llcc_table; 229 const struct llcc_slice_config *llcc_table;
228 struct llcc_slice_desc desc; 230 struct llcc_slice_desc desc;
229 u32 bcast_off = drv_data->bcast_off;
230 231
231 sz = drv_data->cfg_size; 232 sz = drv_data->cfg_size;
232 llcc_table = drv_data->cfg; 233 llcc_table = drv_data->cfg;
233 234
234 for (i = 0; i < sz; i++) { 235 for (i = 0; i < sz; i++) {
235 attr1_cfg = bcast_off + 236 attr1_cfg = LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id);
236 LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id); 237 attr0_cfg = LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
237 attr0_cfg = bcast_off +
238 LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id);
239 238
240 attr1_val = llcc_table[i].cache_mode; 239 attr1_val = llcc_table[i].cache_mode;
241 attr1_val |= llcc_table[i].probe_target_ways << 240 attr1_val |= llcc_table[i].probe_target_ways <<
@@ -260,10 +259,12 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev)
260 attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK; 259 attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK;
261 attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT; 260 attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT;
262 261
263 ret = regmap_write(drv_data->regmap, attr1_cfg, attr1_val); 262 ret = regmap_write(drv_data->bcast_regmap, attr1_cfg,
263 attr1_val);
264 if (ret) 264 if (ret)
265 return ret; 265 return ret;
266 ret = regmap_write(drv_data->regmap, attr0_cfg, attr0_val); 266 ret = regmap_write(drv_data->bcast_regmap, attr0_cfg,
267 attr0_val);
267 if (ret) 268 if (ret)
268 return ret; 269 return ret;
269 if (llcc_table[i].activate_on_init) { 270 if (llcc_table[i].activate_on_init) {
@@ -279,24 +280,36 @@ int qcom_llcc_probe(struct platform_device *pdev,
279{ 280{
280 u32 num_banks; 281 u32 num_banks;
281 struct device *dev = &pdev->dev; 282 struct device *dev = &pdev->dev;
282 struct resource *res; 283 struct resource *llcc_banks_res, *llcc_bcast_res;
283 void __iomem *base; 284 void __iomem *llcc_banks_base, *llcc_bcast_base;
284 int ret, i; 285 int ret, i;
285 286
286 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); 287 drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
287 if (!drv_data) 288 if (!drv_data)
288 return -ENOMEM; 289 return -ENOMEM;
289 290
290 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 291 llcc_banks_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
291 base = devm_ioremap_resource(&pdev->dev, res); 292 "llcc_base");
292 if (IS_ERR(base)) 293 llcc_banks_base = devm_ioremap_resource(&pdev->dev, llcc_banks_res);
293 return PTR_ERR(base); 294 if (IS_ERR(llcc_banks_base))
295 return PTR_ERR(llcc_banks_base);
294 296
295 drv_data->regmap = devm_regmap_init_mmio(dev, base, 297 drv_data->regmap = devm_regmap_init_mmio(dev, llcc_banks_base,
296 &llcc_regmap_config); 298 &llcc_regmap_config);
297 if (IS_ERR(drv_data->regmap)) 299 if (IS_ERR(drv_data->regmap))
298 return PTR_ERR(drv_data->regmap); 300 return PTR_ERR(drv_data->regmap);
299 301
302 llcc_bcast_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
303 "llcc_broadcast_base");
304 llcc_bcast_base = devm_ioremap_resource(&pdev->dev, llcc_bcast_res);
305 if (IS_ERR(llcc_bcast_base))
306 return PTR_ERR(llcc_bcast_base);
307
308 drv_data->bcast_regmap = devm_regmap_init_mmio(dev, llcc_bcast_base,
309 &llcc_regmap_config);
310 if (IS_ERR(drv_data->bcast_regmap))
311 return PTR_ERR(drv_data->bcast_regmap);
312
300 ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0, 313 ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
301 &num_banks); 314 &num_banks);
302 if (ret) 315 if (ret)
@@ -318,8 +331,6 @@ int qcom_llcc_probe(struct platform_device *pdev,
318 for (i = 0; i < num_banks; i++) 331 for (i = 0; i < num_banks; i++)
319 drv_data->offsets[i] = i * BANK_OFFSET_STRIDE; 332 drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
320 333
321 drv_data->bcast_off = num_banks * BANK_OFFSET_STRIDE;
322
323 drv_data->bitmap = devm_kcalloc(dev, 334 drv_data->bitmap = devm_kcalloc(dev,
324 BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long), 335 BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long),
325 GFP_KERNEL); 336 GFP_KERNEL);
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index 7e3b9c605ab2..c681e795b587 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -70,22 +70,22 @@ struct llcc_slice_config {
70/** 70/**
71 * llcc_drv_data - Data associated with the llcc driver 71 * llcc_drv_data - Data associated with the llcc driver
72 * @regmap: regmap associated with the llcc device 72 * @regmap: regmap associated with the llcc device
73 * @bcast_regmap: regmap associated with llcc broadcast offset
73 * @cfg: pointer to the data structure for slice configuration 74 * @cfg: pointer to the data structure for slice configuration
74 * @lock: mutex associated with each slice 75 * @lock: mutex associated with each slice
75 * @cfg_size: size of the config data table 76 * @cfg_size: size of the config data table
76 * @max_slices: max slices as read from device tree 77 * @max_slices: max slices as read from device tree
77 * @bcast_off: Offset of the broadcast bank
78 * @num_banks: Number of llcc banks 78 * @num_banks: Number of llcc banks
79 * @bitmap: Bit map to track the active slice ids 79 * @bitmap: Bit map to track the active slice ids
80 * @offsets: Pointer to the bank offsets array 80 * @offsets: Pointer to the bank offsets array
81 */ 81 */
82struct llcc_drv_data { 82struct llcc_drv_data {
83 struct regmap *regmap; 83 struct regmap *regmap;
84 struct regmap *bcast_regmap;
84 const struct llcc_slice_config *cfg; 85 const struct llcc_slice_config *cfg;
85 struct mutex lock; 86 struct mutex lock;
86 u32 cfg_size; 87 u32 cfg_size;
87 u32 max_slices; 88 u32 max_slices;
88 u32 bcast_off;
89 u32 num_banks; 89 u32 num_banks;
90 unsigned long *bitmap; 90 unsigned long *bitmap;
91 u32 *offsets; 91 u32 *offsets;