Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

soc: qcom: llcc: Add regmap for Broadcast_AND region

Until SM8450, there was only one broadcast region (Broadcast_OR)
used to broadcast write and check for status bit 0.
>From SM8450 onwards another broadcast region (Broadcast_AND) has been
added which checks for status bit 1. This hasn't been updated and
Broadcast_OR region was wrongly being used to check for status bit 1 all
along.

Hence define new regmap structure for Broadcast_AND region and initialize
this regmap when HW block version is greater than 4.1, otherwise
initialize as a NULL pointer for backwards compatibility.
Switch from broadcast_OR to broadcast_AND region (when defined in DT)
for checking status bit 1 as Broadcast_OR region checks only for bit 0.

Signed-off-by: Unnathi Chalicheemala <quic_uchalich@quicinc.com>
Reviewed-by: Bjorn Andersson <quic_bjorande@quicinc.com>
Link: https://lore.kernel.org/r/9cf19928a67eaa577ae0f02de5bf86276be34ea2.1717014052.git.quic_uchalich@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Unnathi Chalicheemala and committed by
Bjorn Andersson
055afc34 c190f390

+18 -2
+15 -1
drivers/soc/qcom/llcc-qcom.c
··· 855 855 static int llcc_update_act_ctrl(u32 sid, 856 856 u32 act_ctrl_reg_val, u32 status) 857 857 { 858 + struct regmap *regmap; 858 859 u32 act_ctrl_reg; 859 860 u32 act_clear_reg; 860 861 u32 status_reg; ··· 884 883 return ret; 885 884 886 885 if (drv_data->version >= LLCC_VERSION_4_1_0_0) { 887 - ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg, 886 + regmap = drv_data->bcast_and_regmap ?: drv_data->bcast_regmap; 887 + ret = regmap_read_poll_timeout(regmap, status_reg, 888 888 slice_status, (slice_status & ACT_COMPLETE), 889 889 0, LLCC_STATUS_READ_DELAY); 890 890 if (ret) ··· 1319 1317 goto err; 1320 1318 1321 1319 drv_data->version = version; 1320 + 1321 + /* Applicable only when drv_data->version >= 4.1 */ 1322 + if (drv_data->version >= LLCC_VERSION_4_1_0_0) { 1323 + drv_data->bcast_and_regmap = qcom_llcc_init_mmio(pdev, i + 1, "llcc_broadcast_and_base"); 1324 + if (IS_ERR(drv_data->bcast_and_regmap)) { 1325 + ret = PTR_ERR(drv_data->bcast_and_regmap); 1326 + if (ret == -EINVAL) 1327 + drv_data->bcast_and_regmap = NULL; 1328 + else 1329 + goto err; 1330 + } 1331 + } 1322 1332 1323 1333 llcc_cfg = cfg->sct_data; 1324 1334 sz = cfg->size;
+3 -1
include/linux/soc/qcom/llcc-qcom.h
··· 115 115 /** 116 116 * struct llcc_drv_data - Data associated with the llcc driver 117 117 * @regmaps: regmaps associated with the llcc device 118 - * @bcast_regmap: regmap associated with llcc broadcast offset 118 + * @bcast_regmap: regmap associated with llcc broadcast OR offset 119 + * @bcast_and_regmap: regmap associated with llcc broadcast AND offset 119 120 * @cfg: pointer to the data structure for slice configuration 120 121 * @edac_reg_offset: Offset of the LLCC EDAC registers 121 122 * @lock: mutex associated with each slice ··· 130 129 struct llcc_drv_data { 131 130 struct regmap **regmaps; 132 131 struct regmap *bcast_regmap; 132 + struct regmap *bcast_and_regmap; 133 133 const struct llcc_slice_config *cfg; 134 134 const struct llcc_edac_reg_offset *edac_reg_offset; 135 135 struct mutex lock;