soc: qcom: rpmh-rsc: Enhance check for VRM in-flight request
commit f592cc5794747b81e53b53dd6e80219ee25f0611 upstream.
Each RPMh VRM accelerator resource has 3 or 4 contiguous 4-byte aligned
addresses associated with it. These control voltage, enable state, mode,
and in legacy targets, voltage headroom. The current in-flight request
checking logic looks for exact address matches. Requests for different
addresses of the same RPMh resource as thus not detected as in-flight.
Add new cmd-db API cmd_db_match_resource_addr() to enhance the in-flight
request check for VRM requests by ignoring the address offset.
This ensures that only one request is allowed to be in-flight for a given
VRM resource. This is needed to avoid scenarios where request commands are
carried out by RPMh hardware out-of-order leading to LDO regulator
over-current protection triggering.
Fixes: 658628e7ef
("drivers: qcom: rpmh-rsc: add RPMH controller for QCOM SoCs")
Cc: stable@vger.kernel.org
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Tested-by: Elliot Berman <quic_eberman@quicinc.com> # sm8650-qrd
Signed-off-by: Maulik Shah <quic_mkshah@quicinc.com>
Link: https://lore.kernel.org/r/20240215-rpmh-rsc-fixes-v4-1-9cbddfcba05b@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
2226b145af
Коммит
83c4aba920
|
@ -1,6 +1,10 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. */
|
/*
|
||||||
|
* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/bitfield.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -17,6 +21,8 @@
|
||||||
#define MAX_SLV_ID 8
|
#define MAX_SLV_ID 8
|
||||||
#define SLAVE_ID_MASK 0x7
|
#define SLAVE_ID_MASK 0x7
|
||||||
#define SLAVE_ID_SHIFT 16
|
#define SLAVE_ID_SHIFT 16
|
||||||
|
#define SLAVE_ID(addr) FIELD_GET(GENMASK(19, 16), addr)
|
||||||
|
#define VRM_ADDR(addr) FIELD_GET(GENMASK(19, 4), addr)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct entry_header: header for each entry in cmddb
|
* struct entry_header: header for each entry in cmddb
|
||||||
|
@ -216,6 +222,30 @@ const void *cmd_db_read_aux_data(const char *id, size_t *len)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cmd_db_read_aux_data);
|
EXPORT_SYMBOL(cmd_db_read_aux_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cmd_db_match_resource_addr() - Compare if both Resource addresses are same
|
||||||
|
*
|
||||||
|
* @addr1: Resource address to compare
|
||||||
|
* @addr2: Resource address to compare
|
||||||
|
*
|
||||||
|
* Return: true if two addresses refer to the same resource, false otherwise
|
||||||
|
*/
|
||||||
|
bool cmd_db_match_resource_addr(u32 addr1, u32 addr2)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Each RPMh VRM accelerator resource has 3 or 4 contiguous 4-byte
|
||||||
|
* aligned addresses associated with it. Ignore the offset to check
|
||||||
|
* for VRM requests.
|
||||||
|
*/
|
||||||
|
if (addr1 == addr2)
|
||||||
|
return true;
|
||||||
|
else if (SLAVE_ID(addr1) == CMD_DB_HW_VRM && VRM_ADDR(addr1) == VRM_ADDR(addr2))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(cmd_db_match_resource_addr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cmd_db_read_slave_id - Get the slave ID for a given resource address
|
* cmd_db_read_slave_id - Get the slave ID for a given resource address
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "%s " fmt, KBUILD_MODNAME
|
#define pr_fmt(fmt) "%s " fmt, KBUILD_MODNAME
|
||||||
|
@ -519,7 +520,7 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
|
||||||
for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) {
|
for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) {
|
||||||
addr = read_tcs_cmd(drv, RSC_DRV_CMD_ADDR, i, j);
|
addr = read_tcs_cmd(drv, RSC_DRV_CMD_ADDR, i, j);
|
||||||
for (k = 0; k < msg->num_cmds; k++) {
|
for (k = 0; k < msg->num_cmds; k++) {
|
||||||
if (addr == msg->cmds[k].addr)
|
if (cmd_db_match_resource_addr(msg->cmds[k].addr, addr))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */
|
/*
|
||||||
|
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __QCOM_COMMAND_DB_H__
|
#ifndef __QCOM_COMMAND_DB_H__
|
||||||
#define __QCOM_COMMAND_DB_H__
|
#define __QCOM_COMMAND_DB_H__
|
||||||
|
@ -21,6 +24,8 @@ u32 cmd_db_read_addr(const char *resource_id);
|
||||||
|
|
||||||
const void *cmd_db_read_aux_data(const char *resource_id, size_t *len);
|
const void *cmd_db_read_aux_data(const char *resource_id, size_t *len);
|
||||||
|
|
||||||
|
bool cmd_db_match_resource_addr(u32 addr1, u32 addr2);
|
||||||
|
|
||||||
enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id);
|
enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id);
|
||||||
|
|
||||||
int cmd_db_ready(void);
|
int cmd_db_ready(void);
|
||||||
|
@ -31,6 +36,9 @@ static inline u32 cmd_db_read_addr(const char *resource_id)
|
||||||
static inline const void *cmd_db_read_aux_data(const char *resource_id, size_t *len)
|
static inline const void *cmd_db_read_aux_data(const char *resource_id, size_t *len)
|
||||||
{ return ERR_PTR(-ENODEV); }
|
{ return ERR_PTR(-ENODEV); }
|
||||||
|
|
||||||
|
static inline bool cmd_db_match_resource_addr(u32 addr1, u32 addr2)
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
static inline enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id)
|
static inline enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id)
|
||||||
{ return -ENODEV; }
|
{ return -ENODEV; }
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче