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

Commit 15d6df37 authored by Lina Iyer's avatar Lina Iyer
Browse files

drivers: soc: qcom: handle system sleep activities



When all the CPUs in the Apps processor subsystem are powered off, the
system may also reduce its bandwidth and shared resource requirements.

The resource requests are sent through the TCS mailbox controller in the
RSC of the APSS subsystem. When notified, the next wakeup timer value is
written to the RSC to be setup in the always-on domain timer. The
sleep/wake requests also need to be written to the TCS mailbox
controller in the RSC inorder to save power. This driver handles the
last few steps when entering system sleep.

Change-Id: I0135a5bae47e228f15fdd1993ddbe8b74ce6e2bb
Signed-off-by: default avatarLina Iyer <ilina@codeaurora.org>
parent d7194ffe
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
SYSTEM PM

System PM device is a virtual device that handles all CPU subsystem low power
mode activties. When entering core shutdown, resource state that were requested
from the processor may be relinquished and set to idle and restored when the
cores are brought out of sleep.

PROPERTIES

- compatible:
	Usage: required
	Value type: <string>
	Definition: must be "qcom,system-pm".

-mboxes:
	Usage: optional
	Value type: <phandle>
	Definition: phandle the TCS mailbox controller for the CPU subsystem.
	This property is generally set only for SoCs that use RPMH communication
	through a mailbox controller.

EXAMPLE

	system_pm {
		compatible = "qcom,system-pm";
		mboxes = <&apps_rsc 0>;
	};

+4 −0
Original line number Diff line number Diff line
@@ -286,6 +286,10 @@ config QTI_RPMH_API
	bool "QTI RPMH (h/w accelerators) Communication API"
	select MAILBOX
	select QTI_RPMH_MBOX
	select QTI_SYSTEM_PM
	help
	  This option enables RPMH hardware communication for making shared
	  resource requests on Qualcomm Technologies Inc SoCs.

config QTI_SYSTEM_PM
	bool
+1 −0
Original line number Diff line number Diff line
@@ -31,3 +31,4 @@ obj-$(CONFIG_MSM_GLINK_SPI_XPRT) += glink_spi_xprt.o
obj-$(CONFIG_TRACER_PKT) += tracer_pkt.o
obj-$(CONFIG_QCOM_BUS_SCALING) += msm_bus/
obj-$(CONFIG_QTI_RPMH_API) += rpmh.o
obj-$(CONFIG_QTI_SYSTEM_PM) += system_pm.o
+87 −0
Original line number Diff line number Diff line
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/kernel.h>
#include <linux/platform_device.h>

#include <soc/qcom/rpmh.h>

#define PDC_TIME_VALID_SHIFT	31
#define PDC_TIME_UPPER_MASK	0xFFFFFF

static struct rpmh_client *rpmh_client;

static int setup_wakeup(uint64_t sleep_val)
{
	struct tcs_cmd cmd[3] = { { 0 } };

	cmd[0].data = sleep_val & 0xFFFFFFFF;
	cmd[1].data = (sleep_val >> 32) & PDC_TIME_UPPER_MASK;
	cmd[1].data |= 1 << PDC_TIME_VALID_SHIFT;

	return rpmh_write_control(rpmh_client, cmd, ARRAY_SIZE(cmd));
}

/**
 * system_sleep_enter() - Activties done when entering system low power modes
 *
 * @sleep_val: The qtimer value for the next wakeup time
 *
 * Returns 0 for success or error values from writing the timer value in the
 * hardware block.
 */
int system_sleep_enter(uint64_t sleep_val)
{
	int ret;

	if (IS_ERR_OR_NULL(rpmh_client))
		return -EFAULT;

	ret = rpmh_flush(rpmh_client);
	if (ret)
		return ret;

	return setup_wakeup(sleep_val);
}
EXPORT_SYMBOL(system_sleep_enter);

/**
 * system_sleep_exit() - Activities done when exiting system low power modes
 */
void system_sleep_exit(void)
{
}
EXPORT_SYMBOL(system_sleep_exit);

static int sys_pm_probe(struct platform_device *pdev)
{
	rpmh_client = rpmh_get_byindex(pdev, 0);
	if (IS_ERR_OR_NULL(rpmh_client))
		return PTR_ERR(rpmh_client);

	return 0;
}

static const struct of_device_id sys_pm_drv_match[] = {
	{ .compatible = "qcom,system-pm", },
	{ }
};

static struct platform_driver sys_pm_driver = {
	.probe = sys_pm_probe,
	.driver = {
		.name = KBUILD_MODNAME,
		.of_match_table = sys_pm_drv_match,
	},
};
builtin_platform_driver(sys_pm_driver);
+28 −0
Original line number Diff line number Diff line
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#ifndef __SOC_QCOM_SYS_PM_H__
#define __SOC_QCOM_SYS_PM_H__

#ifdef CONFIG_QTI_SYSTEM_PM
int system_sleep_enter(uint64_t sleep_val);

void system_sleep_exit(void);
#else
static inline int system_sleep_enter(uint64_t sleep_val)
{ return -ENODEV; }

static inline void system_sleep_exit(void)
{ }
#endif /* CONFIG_QTI_SYSTEM_PM */

#endif /* __SOC_QCOM_SYS_PM_H__ */