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

Commit 1f1fb52e authored by Liam Mark's avatar Liam Mark Committed by Isaac J. Manjarres
Browse files

soc: qcom: mem-offline: Set offlinable region based on minimum DDR sizes



Currently we use a percentage property value to determine the amount of
offlinable memory in the system.

However a percentage property doesn't support accurately configuring the
offlinable region sizes on targets with different amounts of DDR.
For example it is not possible to configure the system such that 4GB
targets won't have any offlinable region, 6GB targets will have a 1GB
offlinable region and 8GB targets having a 3GB offlinable region without
creating a separate DT files for each target.
Many customers want to be able to support different DDR sizes without
creating separate DT files for each target.

Replace the  mem-percent property with an offline-sizes property which
contains an array of offlinable memory region sizes to apply to targets
based on their DDR size.

Change-Id: I93210beec153ca0179c0087ce98afd4dfc22ea02
Signed-off-by: default avatarLiam Mark <lmark@codeaurora.org>
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent 1f5344a1
Loading
Loading
Loading
Loading
+39 −14
Original line number Diff line number Diff line
@@ -266,11 +266,13 @@ phys_addr_t bootloader_memory_limit;
static void __init update_memory_limit(void)
{
	unsigned long dt_root = of_get_flat_dt_root();
	unsigned long node, mp;
	const char *p;
	unsigned long node;
	unsigned long long ram_sz, sz;
	phys_addr_t end_addr, addr_aligned, offset;
	int ret;
	int len;
	const __be32 *prop;
	phys_addr_t min_ddr_sz = 0, offline_sz = 0;
	int t_len = (2 * dt_root_size_cells) * sizeof(__be32);

	ram_sz = memblock_phys_mem_size();
	node = of_get_flat_dt_subnode_by_name(dt_root, "mem-offline");
@@ -278,23 +280,46 @@ static void __init update_memory_limit(void)
		pr_err("mem-offine node not found in FDT\n");
		return;
	}
	p = of_get_flat_dt_prop(node, "mem-percent", NULL);
	if (!p) {
		pr_err("mem-offine: mem-percent property not found in FDT\n");

	prop = of_get_flat_dt_prop(node, "offline-sizes", &len);
	if (prop) {
		if (len % t_len != 0) {
			pr_err("mem-offline: invalid offline-sizes property\n");
			return;
		}

	ret = kstrtoul(p, 10, &mp);
	if (ret) {
		pr_err("mem-offine: kstrtoul failed\n");
		while (len > 0) {
			phys_addr_t tmp_min_ddr_sz = dt_mem_next_cell(
							dt_root_addr_cells,
							&prop);
			phys_addr_t tmp_offline_sz = dt_mem_next_cell(
							dt_root_size_cells,
							&prop);

			if (tmp_min_ddr_sz < ram_sz &&
			    tmp_min_ddr_sz > min_ddr_sz) {
				if (tmp_offline_sz < ram_sz) {
					min_ddr_sz = tmp_min_ddr_sz;
					offline_sz = tmp_offline_sz;
				} else {
					pr_info("mem-offline: invalid offline size:%pa\n",
						 &tmp_offline_sz);
				}
			}
			len -= t_len;
		}
	} else {
		pr_err("mem-offine: offline-sizes property not found in DT\n");
		return;
	}

	if (mp > 100) {
		pr_err("mem-offine: Invalid mem-percent DT property\n");
	if (offline_sz == 0) {
		pr_info("mem-offline: no memory to offline for DDR size:%llu\n",
			ram_sz);
		return;
	}
	sz = ram_sz - ((ram_sz * mp) / 100);

	sz = ram_sz - offline_sz;
	memory_limit = (phys_addr_t)sz;
	end_addr = memblock_max_addr(memory_limit);
	addr_aligned = ALIGN(end_addr, MIN_MEMORY_BLOCK_SIZE);
+1 −1
Original line number Diff line number Diff line
@@ -473,7 +473,7 @@ static ssize_t allocated_bytes_show(struct device *dev,
		&NODE_DATA(numa_node_id())->node_zones[ZONE_MOVABLE];
	unsigned long used, block_sz = memory_block_size_bytes();

	if (mem->state != MEM_ONLINE)
	if (!populated_zone(movable_zone) || mem->state != MEM_ONLINE)
		return snprintf(buf, 100, "0\n");

	block_id = base_memory_block_id(mem->start_section_nr);