android_kernel_xiaomi_sm8350/drivers/soc/qcom/pm-boot.c
Raja Mallik 92d0c40a5c drivers: soc: qcom: pm: Add legacy PM and Warmboot set address API support
Add legacy msm pm sleep mode support for MDM9607 target.

Add warmboot set address support for multi cluster cpu's.

Snapshot is taken from msm-4.9 kernel version @ commit 078db469522464
("soc: qcom: bgrsb: Increase time out for RSB channel opening").

Change-Id: Ibfc56254c47cfc1465aff5559b8846072f66041a
Signed-off-by: Raghavendra Kakarla <rkakarla@codeaurora.org>
Signed-off-by: Haribabu Gattem <haribabu@codeaurora.org>
Signed-off-by: Raja Mallik <rmallik@codeaurora.org>
Signed-off-by: Tushar Nimkar <tnimkar@codeaurora.org>
2021-03-15 10:12:16 -07:00

72 lines
1.9 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2011-2014, 2016, 2018-2019, 2021 The Linux Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <asm/cacheflush.h>
#include <asm/cputype.h>
#include <asm/smp_plat.h>
#include <linux/qcom_scm.h>
#include "pm-boot.h"
#include "idle.h"
#define CPU_INDEX(cluster, cpu) (cluster * MAX_CPUS_PER_CLUSTER + cpu)
#define SCM_FLAG_WARMBOOT_MC 0x04
static void (*msm_pm_boot_before_pc)(unsigned int cpu, unsigned long entry);
static void (*msm_pm_boot_after_pc)(unsigned int cpu);
static int msm_pm_tz_boot_init(void)
{
phys_addr_t warmboot_addr = msm_pm_boot_entry;
return qcom_scm_set_warm_boot_addr_mc(warmboot_addr, ~0U, ~0U, ~0U,
SCM_FLAG_WARMBOOT_MC);
}
static void msm_pm_write_boot_vector(unsigned int cpu, unsigned long address)
{
uint32_t clust_id = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 1);
uint32_t cpu_id = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0);
unsigned long *start_address;
unsigned long *end_address;
if (clust_id >= MAX_NUM_CLUSTER || cpu_id >= MAX_CPUS_PER_CLUSTER)
WARN_ON(cpu);
msm_pm_boot_vector[CPU_INDEX(clust_id, cpu_id)] = address;
start_address = &msm_pm_boot_vector[CPU_INDEX(clust_id, cpu_id)];
end_address = &msm_pm_boot_vector[CPU_INDEX(clust_id, cpu_id + 1)];
}
static void msm_pm_config_tz_before_pc(unsigned int cpu,
unsigned long entry)
{
msm_pm_write_boot_vector(cpu, entry);
}
void msm_pm_boot_config_before_pc(unsigned int cpu, unsigned long entry)
{
if (msm_pm_boot_before_pc)
msm_pm_boot_before_pc(cpu, entry);
}
void msm_pm_boot_config_after_pc(unsigned int cpu)
{
if (msm_pm_boot_after_pc)
msm_pm_boot_after_pc(cpu);
}
static int __init msm_pm_boot_init(void)
{
int ret = 0;
ret = msm_pm_tz_boot_init();
msm_pm_boot_before_pc = msm_pm_config_tz_before_pc;
msm_pm_boot_after_pc = NULL;
return ret;
}
late_initcall(msm_pm_boot_init);