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

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

Merge "drivers: soc: qcom: pm: Add legacy PM and Warmboot set address API support"

parents b785a983 92d0c40a
Loading
Loading
Loading
Loading
+80 −16
Original line number Diff line number Diff line
@@ -19,13 +19,13 @@
#include <linux/pm_qos.h>
#include <linux/of_platform.h>
#include <linux/smp.h>
#include <linux/remote_spinlock.h>
#include <linux/msm_remote_spinlock.h>
#include <linux/dma-mapping.h>
#include <linux/coresight-cti.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/cpu_pm.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <soc/qcom/spm.h>
#include <soc/qcom/pm-legacy.h>
#include <soc/qcom/rpm-notifier.h>
@@ -48,10 +48,22 @@
#include <soc/qcom/minidump.h>

#define SCLK_HZ (32768)
#define SCM_HANDOFF_LOCK_ID "S:7"
#define PSCI_POWER_STATE(reset) (reset << 30)
#define PSCI_AFFINITY_LEVEL(lvl) ((lvl & 0x3) << 24)
static remote_spinlock_t scm_handoff_lock;
#define MUTEX_NUM_PID 128
#define MUTEX_TID_START MUTEX_NUM_PID
#define SCM_HANDOFF_LOCK_ID 7

/* sfpb implementation for hardware spinlock usage */
static phys_addr_t reg_base;
static uint32_t reg_size;
static uint32_t lock_size;

static void __iomem *hw_mutex_reg_base;

struct mutex_reg {
	uint32_t regaddr;
};

enum {
	MSM_LPM_LVL_DBG_SUSPEND_LIMITS = BIT(0),
@@ -1278,13 +1290,38 @@ static const struct platform_suspend_ops lpm_suspend_ops = {
	.wake = lpm_suspend_wake,
};

static int init_hw_mutex(struct device_node *node)
{
	struct resource r;
	int rc;
	static uint32_t lock_count;

	rc = of_address_to_resource(node, 0, &r);
	if (rc) {
		pr_err("Failed to get resource\n");
		return 1;
	}

	rc = of_property_read_u32(node, "qcom,num-locks", &lock_count);
	if (rc) {
		pr_err("Failed to get num-locks property\n");
		return 1;
	}

	reg_base = r.start;
	reg_size = (uint32_t)(resource_size(&r));
	lock_size = reg_size / lock_count;

	return 0;
}

static int lpm_probe(struct platform_device *pdev)
{
	int ret;
	int size;
	struct kobject *module_kobj = NULL;
	struct md_region md_entry;

	struct device_node *node;
	get_online_cpus();
	lpm_root_node = lpm_of_parse_cluster(pdev);

@@ -1305,14 +1342,6 @@ static int lpm_probe(struct platform_device *pdev)
	 */
	suspend_set_ops(&lpm_suspend_ops);
	hrtimer_init(&lpm_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);

	ret = remote_spin_lock_init(&scm_handoff_lock, SCM_HANDOFF_LOCK_ID);
	if (ret) {
		pr_err("%s: Failed initializing scm_handoff_lock (%d)\n",
			__func__, ret);
		put_online_cpus();
		return ret;
	}
	size = num_dbg_elements * sizeof(struct lpm_debug);
	lpm_debug = dma_alloc_coherent(&pdev->dev, size,
			&lpm_debug_phys, GFP_KERNEL);
@@ -1354,6 +1383,28 @@ static int lpm_probe(struct platform_device *pdev)
	if (msm_minidump_add_region(&md_entry))
		pr_info("Failed to add lpm_debug in Minidump\n");

	node = of_find_node_by_name(NULL, "qcom,ipc-spinlock");
	if (!node) {
		pr_err("Failed to find ipc-spinlock node\n");
		ret = -ENODEV;
		goto failed;
	}

	if (init_hw_mutex(node)) {
		ret = -EINVAL;
		of_node_put(node);
		goto failed;
	}

	hw_mutex_reg_base = ioremap(reg_base, reg_size);
	if (!hw_mutex_reg_base) {
		pr_err("ioremap failed\n");
		ret = -ENOMEM;
		of_node_put(node);
		goto failed;
	}
	of_node_put(node);

	return 0;
failed:
	free_cluster_node(lpm_root_node);
@@ -1389,11 +1440,24 @@ static int __init lpm_levels_module_init(void)
}
late_initcall(lpm_levels_module_init);

static void mutex_reg_write(uint32_t tid)
{
	struct mutex_reg *lock;

	lock = hw_mutex_reg_base + (SCM_HANDOFF_LOCK_ID * lock_size);
	do {
		writel_relaxed(tid, lock);
		/* barrier for proper semantics */
		smp_mb();
	} while (readl_relaxed(lock) != tid);
}


enum msm_pm_l2_scm_flag lpm_cpu_pre_pc_cb(unsigned int cpu)
{
	struct lpm_cluster *cluster = per_cpu(cpu_cluster, cpu);
	enum msm_pm_l2_scm_flag retflag = MSM_SCM_L2_ON;

	uint32_t tid;
	/*
	 * No need to acquire the lock if probe isn't completed yet
	 * In the event of the hotplug happening before lpm probe, we want to
@@ -1434,8 +1498,8 @@ enum msm_pm_l2_scm_flag lpm_cpu_pre_pc_cb(unsigned int cpu)
	update_debug_pc_event(PRE_PC_CB, retflag, 0xdeadbeef, 0xdeadbeef,
			0xdeadbeef);
	trace_pre_pc_cb(retflag);
	remote_spin_lock_rlock_id(&scm_handoff_lock,
				  REMOTE_SPINLOCK_TID_START + cpu);
	tid = MUTEX_TID_START + cpu;
	mutex_reg_write(tid);
	spin_unlock(&cluster->sync_lock);
	return retflag;
}
+16 −0
Original line number Diff line number Diff line
@@ -509,6 +509,22 @@ config QCOM_SMD_RPM
	  Say M here if you want to include support for the Qualcomm RPM as a
	  module. This will build a module called "qcom-smd-rpm".

config MSM_SPM
        bool "Driver support for SPM and AVS wrapper hardware"
        help
          Enables the support for SPM and AVS wrapper hardware on MSMs. SPM
          hardware is used to manage the processor power during sleep. The
          driver allows configuring SPM to allow different low power modes for
          both core and L2.

config MSM_L2_SPM
        bool "SPM support for L2 cache"
        help
          Enable SPM driver support for L2 cache. Some MSM chipsets allow
          control of L2 cache low power mode with a Subsystem Power manager.
          Enabling this driver allows configuring L2 SPM for low power modes
          on supported chipsets.

config QCOM_MEMORY_DUMP_V2
	tristate "QCOM Memory Dump V2 Support"
	help
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ obj-$(CONFIG_QCOM_SOC_SLEEP_STATS) += soc_sleep_stats.o
obj-$(CONFIG_MSM_BOOT_STATS) += boot_stats.o
obj-$(CONFIG_QCOM_SMD_RPM)	+= smd-rpm.o
obj-$(CONFIG_QCOM_SMEM) +=	smem.o
obj-$(CONFIG_MSM_PM_LEGACY) += pm-boot.o msm-pm.o
obj-$(CONFIG_MSM_SPM) += msm-spm.o spm_devices.o
obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
obj-$(CONFIG_QCOM_SMP2P)	+= smp2p.o
obj-$(CONFIG_QCOM_SUBSYSTEM_SLEEP_STATS) += subsystem_sleep_stats.o
+21 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */

/*
 * Copyright (c) 2007-2009,2012-2014, 2018-2019, 2021 The Linux Foundation.
 */

#ifndef _ARCH_ARM_MACH_MSM_IDLE_H_
#define _ARCH_ARM_MACH_MSM_IDLE_H_

#define MAX_CPUS_PER_CLUSTER	4
#define MAX_NUM_CLUSTER	4

#ifndef __ASSEMBLY__
#if defined(CONFIG_CPU_V7) || defined(CONFIG_ARM64)
extern unsigned long msm_pm_boot_vector[MAX_NUM_CLUSTER * MAX_CPUS_PER_CLUSTER];
void msm_pm_boot_entry(void);
#else
static inline void msm_pm_boot_entry(void) {}
#endif
#endif
#endif
+819 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading