interconnect: qcom: icc-rpm: Program SMD RPM auxiliary QoS ports

Some SMD RPM interconnect nodes own two QoS ports. Currently, the code
only takes care of one, leaving some endpoints partially unconfigured.

Keep qos_port as the primary port and describe the optional second port
with aux_qos_port.

Assisted-by: LLM
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://patch.msgid.link/20260909-topic-icc_rpm_smd_qol-v1-4-6dc5b5e97626@oss.qualcomm.com
Signed-off-by: Georgi Djakov <djakov@kernel.org>
This commit is contained in:
Konrad Dybcio 2026-09-09 18:41:57 +02:00 committed by Georgi Djakov
parent b2079a6b8e
commit ddbacca26d
2 changed files with 73 additions and 11 deletions

View File

@ -58,15 +58,32 @@ static int qcom_icc_set_qnoc_qos(struct icc_node *src)
struct qcom_icc_qos *qos = &qn->qos;
int rc;
rc = regmap_update_bits(qp->regmap,
qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->qos_port),
QNOC_QOS_MCTL_DFLT_PRIO_MASK,
qos->areq_prio << QNOC_QOS_MCTL_DFLT_PRIO_SHIFT);
if (rc)
return rc;
rc = regmap_update_bits(qp->regmap,
qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->qos_port),
QNOC_QOS_MCTL_DFLT_PRIO_MASK,
qos->areq_prio << QNOC_QOS_MCTL_DFLT_PRIO_SHIFT);
QNOC_QOS_MCTL_URGFWD_EN_MASK,
!!qos->urg_fwd_en << QNOC_QOS_MCTL_URGFWD_EN_SHIFT);
if (rc)
return rc;
if (!qos->aux_qos_port)
return 0;
rc = regmap_update_bits(qp->regmap,
qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->aux_qos_port),
QNOC_QOS_MCTL_DFLT_PRIO_MASK,
qos->areq_prio << QNOC_QOS_MCTL_DFLT_PRIO_SHIFT);
if (rc)
return rc;
return regmap_update_bits(qp->regmap,
qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->qos_port),
qp->qos_offset + QNOC_QOS_MCTL_LOWn_ADDR(qos->aux_qos_port),
QNOC_QOS_MCTL_URGFWD_EN_MASK,
!!qos->urg_fwd_en << QNOC_QOS_MCTL_URGFWD_EN_SHIFT);
}
@ -75,8 +92,9 @@ static int qcom_icc_bimc_set_qos_health(struct qcom_icc_provider *qp,
struct qcom_icc_qos *qos,
int regnum)
{
u32 val;
u32 mask;
u32 val;
int ret;
val = qos->prio_level;
mask = M_BKE_HEALTH_CFG_PRIOLVL_MASK;
@ -90,8 +108,17 @@ static int qcom_icc_bimc_set_qos_health(struct qcom_icc_provider *qp,
mask |= M_BKE_HEALTH_CFG_LIMITCMDS_MASK;
}
ret = regmap_update_bits(qp->regmap,
qp->qos_offset + M_BKE_HEALTH_CFG_ADDR(regnum, qos->qos_port),
mask, val);
if (ret)
return ret;
if (!qos->aux_qos_port)
return 0;
return regmap_update_bits(qp->regmap,
qp->qos_offset + M_BKE_HEALTH_CFG_ADDR(regnum, qos->qos_port),
qp->qos_offset + M_BKE_HEALTH_CFG_ADDR(regnum, qos->aux_qos_port),
mask, val);
}
@ -102,7 +129,7 @@ static int qcom_icc_set_bimc_qos(struct icc_node *src)
struct icc_provider *provider;
u32 mode = NOC_QOS_MODE_BYPASS;
u32 val = 0;
int i, rc = 0;
int i, rc;
qn = src->data;
provider = src->provider;
@ -116,8 +143,7 @@ static int qcom_icc_set_bimc_qos(struct icc_node *src)
*/
if (mode != NOC_QOS_MODE_BYPASS) {
for (i = 3; i >= 0; i--) {
rc = qcom_icc_bimc_set_qos_health(qp,
&qn->qos, i);
rc = qcom_icc_bimc_set_qos_health(qp, &qn->qos, i);
if (rc)
return rc;
}
@ -126,8 +152,17 @@ static int qcom_icc_set_bimc_qos(struct icc_node *src)
val = 1;
}
rc = regmap_update_bits(qp->regmap,
qp->qos_offset + M_BKE_EN_ADDR(qn->qos.qos_port),
M_BKE_EN_EN_BMASK, val);
if (rc)
return rc;
if (!qn->qos.aux_qos_port)
return 0;
return regmap_update_bits(qp->regmap,
qp->qos_offset + M_BKE_EN_ADDR(qn->qos.qos_port),
qp->qos_offset + M_BKE_EN_ADDR(qn->qos.aux_qos_port),
M_BKE_EN_EN_BMASK, val);
}
@ -145,8 +180,24 @@ static int qcom_icc_noc_set_qos_priority(struct qcom_icc_provider *qp,
if (rc)
return rc;
rc = regmap_update_bits(qp->regmap,
qp->qos_offset + NOC_QOS_PRIORITYn_ADDR(qos->qos_port),
NOC_QOS_PRIORITY_P0_MASK, qos->prio_level);
if (rc)
return rc;
if (!qos->aux_qos_port)
return 0;
val = qos->areq_prio << NOC_QOS_PRIORITY_P1_SHIFT;
rc = regmap_update_bits(qp->regmap,
qp->qos_offset + NOC_QOS_PRIORITYn_ADDR(qos->aux_qos_port),
NOC_QOS_PRIORITY_P1_MASK, val);
if (rc)
return rc;
return regmap_update_bits(qp->regmap,
qp->qos_offset + NOC_QOS_PRIORITYn_ADDR(qos->qos_port),
qp->qos_offset + NOC_QOS_PRIORITYn_ADDR(qos->aux_qos_port),
NOC_QOS_PRIORITY_P0_MASK, qos->prio_level);
}
@ -182,8 +233,17 @@ static int qcom_icc_set_noc_qos(struct icc_node *src)
/* How did we get here? */
}
rc = regmap_update_bits(qp->regmap,
qp->qos_offset + NOC_QOS_MODEn_ADDR(qn->qos.qos_port),
NOC_QOS_MODEn_MASK, mode);
if (rc)
return rc;
if (!qn->qos.aux_qos_port)
return 0;
return regmap_update_bits(qp->regmap,
qp->qos_offset + NOC_QOS_MODEn_ADDR(qn->qos.qos_port),
qp->qos_offset + NOC_QOS_MODEn_ADDR(qn->qos.aux_qos_port),
NOC_QOS_MODEn_MASK, mode);
}

View File

@ -77,6 +77,7 @@ struct qcom_icc_provider {
* @ap_owned: indicates if the node is owned by the AP or by the RPM
* @qos_mode: default qos mode for this node
* @qos_port: qos port number for finding qos registers of this node
* @aux_qos_port: optional QoS port in addition to @qos_port. Zero means "none".
* @urg_fwd_en: enable urgent forwarding
*/
struct qcom_icc_qos {
@ -86,6 +87,7 @@ struct qcom_icc_qos {
bool ap_owned;
int qos_mode;
int qos_port;
u16 aux_qos_port;
bool urg_fwd_en;
};