Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8ccd462 authored by Lina Iyer's avatar Lina Iyer
Browse files

drivers: qcom: rpmh-rsc: write PDC data



The Power Domain Controller can be programmed to wakeup the RSC and
setup the resources back in the active state, before the processor is
woken up by a timer interrupt. The wakeup value from the timer hardware
can be copied to the PDC which has its own timer and is in an always-on
power domain. Programming the wakeup value is done through a separate
register on the RSC.

Change-Id: Ic68d03c0dd800fd05d3b565fc33a3a56e9186682
Signed-off-by: default avatarLina Iyer <ilina@codeaurora.org>
Signed-off-by: default avatarRaju P.L.S.S.S.N <rplsssn@codeaurora.org>
parent a316de8e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -87,6 +87,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)
 * @num_tcs:    number of TCSes in this DRV
@@ -97,6 +98,7 @@ struct rpmh_ctrlr {
 */
struct rsc_drv {
	const char *name;
	void __iomem *base;
	void __iomem *tcs_base;
	int id;
	int num_tcs;
@@ -111,6 +113,7 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv,
			     const struct tcs_request *msg);
int rpmh_rsc_invalidate(struct rsc_drv *drv);
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);

+29 −6
Original line number Diff line number Diff line
@@ -61,6 +61,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 +
@@ -570,6 +575,25 @@ int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg)
	return tcs_ctrl_write(drv, msg);
}

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)
{
@@ -582,21 +606,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);