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

Commit ea6de31b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: mem-offline: add pasr support for rpm-smd based targets"

parents 816c62cb 2561f74c
Loading
Loading
Loading
Loading
+52 −3
Original line number Original line Diff line number Diff line
@@ -19,7 +19,9 @@
#include <linux/mailbox/qmp.h>
#include <linux/mailbox/qmp.h>
#include <asm/tlbflush.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#include <asm/cacheflush.h>
#include <soc/qcom/rpm-smd.h>


#define RPM_DDR_REQ 0x726464
#define AOP_MSG_ADDR_MASK		0xffffffff
#define AOP_MSG_ADDR_MASK		0xffffffff
#define AOP_MSG_ADDR_HIGH_SHIFT		32
#define AOP_MSG_ADDR_HIGH_SHIFT		32
#define MAX_LEN				96
#define MAX_LEN				96
@@ -28,6 +30,7 @@ static unsigned long start_section_nr, end_section_nr;
static struct kobject *kobj;
static struct kobject *kobj;
static unsigned int sections_per_block;
static unsigned int sections_per_block;
static u32 offline_granule;
static u32 offline_granule;
static bool is_rpm_controller;
#define MODULE_CLASS_NAME	"mem-offline"
#define MODULE_CLASS_NAME	"mem-offline"


struct section_stat {
struct section_stat {
@@ -55,6 +58,15 @@ static struct mem_offline_mailbox {
	struct mbox_chan *mbox;
	struct mbox_chan *mbox;
} mailbox;
} mailbox;


struct memory_refresh_request {
	u64 start;	/* Lower bit signifies action
			 * 0 - disable self-refresh
			 * 1 - enable self-refresh
			 * upper bits are for base address
			 */
	u32 size;	/* size of memory region */
};

static struct section_stat *mem_info;
static struct section_stat *mem_info;


static void clear_pgtable_mapping(phys_addr_t start, phys_addr_t end)
static void clear_pgtable_mapping(phys_addr_t start, phys_addr_t end)
@@ -151,6 +163,25 @@ static void record_stat(unsigned long sec, ktime_t delay, int mode)
	mem_info[blk_nr].resident_since = 0;
	mem_info[blk_nr].resident_since = 0;
}
}


static int mem_region_refresh_control(unsigned long pfn,
				      unsigned long nr_pages,
				      bool enable)
{
	struct memory_refresh_request mem_req;
	struct msm_rpm_kvp rpm_kvp;

	mem_req.start = enable;
	mem_req.start |= pfn << PAGE_SHIFT;
	mem_req.size = nr_pages * PAGE_SIZE;

	rpm_kvp.key = RPM_DDR_REQ;
	rpm_kvp.data = (void *)&mem_req;
	rpm_kvp.length = sizeof(mem_req);

	return msm_rpm_send_message(MSM_RPM_CTX_ACTIVE_SET, RPM_DDR_REQ, 0,
				    &rpm_kvp, 1);
}

static int aop_send_msg(unsigned long addr, bool online)
static int aop_send_msg(unsigned long addr, bool online)
{
{
	struct qmp_pkt pkt;
	struct qmp_pkt pkt;
@@ -195,9 +226,16 @@ static int send_msg(struct memory_notify *mn, bool online, int count)
	start = section_nr_to_pfn(base_sec_nr);
	start = section_nr_to_pfn(base_sec_nr);


	for (i = 0; i < count; ++i) {
	for (i = 0; i < count; ++i) {
		if (is_rpm_controller)
			ret = mem_region_refresh_control(start,
						 segment_size >> PAGE_SHIFT,
						 online);
		else
			ret = aop_send_msg(__pfn_to_phys(start), online);
			ret = aop_send_msg(__pfn_to_phys(start), online);

		if (ret) {
		if (ret) {
			pr_err("PASR: AOP %s request addr:0x%llx failed\n",
			pr_err("PASR: %s %s request addr:0x%llx failed\n",
			       is_rpm_controller ? "RPM" : "AOP",
			       online ? "online" : "offline",
			       online ? "online" : "offline",
			       __pfn_to_phys(start));
			       __pfn_to_phys(start));
			goto undo;
			goto undo;
@@ -212,7 +250,13 @@ static int send_msg(struct memory_notify *mn, bool online, int count)
	while (i-- > 0) {
	while (i-- > 0) {
		int ret;
		int ret;


		if (is_rpm_controller)
			ret = mem_region_refresh_control(start,
						 segment_size >> PAGE_SHIFT,
						 !online);
		else
			ret = aop_send_msg(__pfn_to_phys(start), !online);
			ret = aop_send_msg(__pfn_to_phys(start), !online);

		if (ret)
		if (ret)
			panic("Failed to completely online/offline a hotpluggable segment. A quasi state of memblock can cause randomn system failures.");
			panic("Failed to completely online/offline a hotpluggable segment. A quasi state of memblock can cause randomn system failures.");
		start = __phys_to_pfn(__pfn_to_phys(start) + segment_size);
		start = __phys_to_pfn(__pfn_to_phys(start) + segment_size);
@@ -671,6 +715,11 @@ static int mem_parse_dt(struct platform_device *pdev)
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (!of_find_property(node, "mboxes", NULL)) {
		is_rpm_controller = true;
		return 0;
	}

	mailbox.cl.dev = &pdev->dev;
	mailbox.cl.dev = &pdev->dev;
	mailbox.cl.tx_block = true;
	mailbox.cl.tx_block = true;
	mailbox.cl.tx_tout = 1000;
	mailbox.cl.tx_tout = 1000;