Merge "drivers: qcom: rpmh-rsc: write PDC data"
This commit is contained in:
commit
3cbfdc6285
@ -84,6 +84,7 @@ struct rpmh_ctrlr {
|
||||
* Resource State Coordinator controller (RSC)
|
||||
*
|
||||
* @name: controller identifier
|
||||
* @base: start address of the RSC's DRV registers
|
||||
* @tcs_base: start address of the TCS registers in this controller
|
||||
* @id: instance id in the controller (Direct Resource Voter)
|
||||
* @in_solver_mode: Controller is in solver mode
|
||||
@ -95,6 +96,7 @@ struct rpmh_ctrlr {
|
||||
*/
|
||||
struct rsc_drv {
|
||||
const char *name;
|
||||
void __iomem *base;
|
||||
void __iomem *tcs_base;
|
||||
int id;
|
||||
bool in_solver_mode;
|
||||
@ -111,6 +113,7 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv,
|
||||
int rpmh_rsc_invalidate(struct rsc_drv *drv);
|
||||
void rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable);
|
||||
bool rpmh_rsc_ctrlr_is_idle(struct rsc_drv *drv);
|
||||
int rpmh_rsc_write_pdc_data(struct rsc_drv *drv, const struct tcs_request *msg);
|
||||
|
||||
void rpmh_tx_done(const struct tcs_request *msg, int r);
|
||||
|
||||
|
@ -60,6 +60,11 @@
|
||||
#define CMD_STATUS_ISSUED BIT(8)
|
||||
#define CMD_STATUS_COMPL BIT(16)
|
||||
|
||||
/* PDC wakeup */
|
||||
#define RSC_PDC_DATA_SIZE 2
|
||||
#define RSC_PDC_DRV_DATA 0x38
|
||||
#define RSC_PDC_DATA_OFFSET 0x08
|
||||
|
||||
static u32 read_tcs_reg(struct rsc_drv *drv, int reg, int tcs_id, int cmd_id)
|
||||
{
|
||||
return readl_relaxed(drv->tcs_base + reg + RSC_DRV_TCS_OFFSET * tcs_id +
|
||||
@ -600,6 +605,25 @@ void rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable)
|
||||
spin_unlock(&drv->lock);
|
||||
}
|
||||
|
||||
int rpmh_rsc_write_pdc_data(struct rsc_drv *drv, const struct tcs_request *msg)
|
||||
{
|
||||
int i;
|
||||
void __iomem *addr = drv->base + RSC_PDC_DRV_DATA;
|
||||
|
||||
if (!msg || !msg->cmds || msg->num_cmds != RSC_PDC_DATA_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < msg->num_cmds; i++) {
|
||||
/* Only data is write capable */
|
||||
writel_relaxed(msg->cmds[i].data, addr);
|
||||
trace_rpmh_send_msg(drv, RSC_PDC_DRV_DATA, i, 0,
|
||||
&msg->cmds[i]);
|
||||
addr += RSC_PDC_DATA_OFFSET;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rpmh_probe_tcs_config(struct platform_device *pdev,
|
||||
struct rsc_drv *drv)
|
||||
{
|
||||
@ -612,21 +636,20 @@ static int rpmh_probe_tcs_config(struct platform_device *pdev,
|
||||
int i, ret, n, st = 0;
|
||||
struct tcs_group *tcs;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
char drv_id[10] = {0};
|
||||
|
||||
snprintf(drv_id, ARRAY_SIZE(drv_id), "drv-%d", drv->id);
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, drv_id);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
drv->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(drv->base))
|
||||
return PTR_ERR(drv->base);
|
||||
|
||||
ret = of_property_read_u32(dn, "qcom,tcs-offset", &offset);
|
||||
if (ret)
|
||||
return ret;
|
||||
drv->tcs_base = base + offset;
|
||||
drv->tcs_base = drv->base + offset;
|
||||
|
||||
config = readl_relaxed(base + DRV_PRNT_CHLD_CONFIG);
|
||||
config = readl_relaxed(drv->base + DRV_PRNT_CHLD_CONFIG);
|
||||
|
||||
max_tcs = config;
|
||||
max_tcs &= DRV_NUM_TCS_MASK << (DRV_NUM_TCS_SHIFT * drv->id);
|
||||
|
@ -470,6 +470,34 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state,
|
||||
}
|
||||
EXPORT_SYMBOL(rpmh_write_batch);
|
||||
|
||||
/**
|
||||
* rpmh_write_pdc_data: Write PDC data to the controller
|
||||
*
|
||||
* @dev: the device making the request
|
||||
* @cmd: The payload data
|
||||
* @n: The number of elements in payload
|
||||
*
|
||||
* Write PDC data to the controller. The messages are always sent async.
|
||||
*
|
||||
* May be called from atomic contexts.
|
||||
*/
|
||||
int rpmh_write_pdc_data(const struct device *dev,
|
||||
const struct tcs_cmd *cmd, u32 n)
|
||||
{
|
||||
DEFINE_RPMH_MSG_ONSTACK(dev, 0, NULL, rpm_msg);
|
||||
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
||||
|
||||
if (!n || n > MAX_RPMH_PAYLOAD)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(rpm_msg.cmd, cmd, n * sizeof(*cmd));
|
||||
rpm_msg.msg.num_cmds = n;
|
||||
rpm_msg.msg.wait_for_compl = false;
|
||||
|
||||
return rpmh_rsc_write_pdc_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg);
|
||||
}
|
||||
EXPORT_SYMBOL(rpmh_write_pdc_data);
|
||||
|
||||
static int is_req_valid(struct cache_req *req)
|
||||
{
|
||||
return (req->sleep_val != UINT_MAX &&
|
||||
|
@ -26,6 +26,9 @@ int rpmh_mode_solver_set(const struct device *dev, bool enable);
|
||||
|
||||
int rpmh_ctrlr_idle(const struct device *dev);
|
||||
|
||||
int rpmh_write_pdc_data(const struct device *dev,
|
||||
const struct tcs_cmd *cmd, u32 n);
|
||||
|
||||
#else
|
||||
|
||||
static inline int rpmh_write(const struct device *dev, enum rpmh_state state,
|
||||
@ -54,6 +57,9 @@ static inline int rpmh_mode_solver_set(const struct device *dev, bool enable)
|
||||
static inline int rpmh_ctrlr_idle(const struct device *dev)
|
||||
{ return -ENODEV; }
|
||||
|
||||
static inline int rpmh_write_pdc_data(const struct device *dev,
|
||||
const struct tcs_cmd *cmd, u32 n)
|
||||
{ return -ENODEV; }
|
||||
#endif /* CONFIG_QCOM_RPMH */
|
||||
|
||||
#endif /* __SOC_QCOM_RPMH_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user