mirror of https://gitee.com/openkylin/linux.git
Some suspend improvements enabling the possibility to wakeup
from usbphy events and a rework of how cpu cores are brought uü and down, as it was possible to produce lockups when hammering the cpu hotplug functions. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABCAAGBQJVp7v5AAoJEPOmecmc0R2BIjsIAI/siza1l62HuNCuj96ntlJA 77jBO2zV0ZfRd/3CPHwkuDajla4KifQXDUcy1UAXhAuyieki3qfUDkurlurV9xK8 OaTRdc0hc6kbU3C6q+biXkRURtGDXH1fqF+t8gXUbyxv+dZ5NMWbZAXxb0SwvjpY m7tpOdoVgTQIp3SiFCo6gVw7aXJcRkm9QLdj05hVMsMOWxu9TkmKrGo7aHTN0A4w aTEtOLd8e89YMkcW4Eg0fkasTEKeV1ni30yxmld0hTPi0pPrsBbWRBCp4lltGrVS kYl1kIZQk3RURcO3H/Tz0lEWhaUaQYmQqRg8Q+vBIQA6GILOLzwziYGLljigy7g= =+S6z -----END PGP SIGNATURE----- Merge tag 'v4.3-rockchip32-soc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into next/soc Merge "Rockchip soc changes for 4.3, part1" from Heiko Stuebner: Some suspend improvements enabling the possibility to wakeup from usbphy events and a rework of how cpu cores are brought up and down, as it was possible to produce lockups when hammering the cpu hotplug functions. * tag 'v4.3-rockchip32-soc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip: ARM: rockchip: fix broken build ARM: rockchip: remove some useless macro in pm.h ARM: rockchip: add support holding 24Mhz osc during suspend ARM: rockchip: fix the SMP code style ARM: rockchip: ensure CPU to enter WFI/WFE state ARM: rockchip: fix the CPU soft reset ARM: rockchip: restore dapswjdp after suspend Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
d7030a08f6
|
@ -72,29 +72,22 @@ static struct reset_control *rockchip_get_core_reset(int cpu)
|
|||
static int pmu_set_power_domain(int pd, bool on)
|
||||
{
|
||||
u32 val = (on) ? 0 : BIT(pd);
|
||||
struct reset_control *rstc = rockchip_get_core_reset(pd);
|
||||
int ret;
|
||||
|
||||
if (IS_ERR(rstc) && read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
|
||||
pr_err("%s: could not get reset control for core %d\n",
|
||||
__func__, pd);
|
||||
return PTR_ERR(rstc);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to soft reset the cpu when we turn off the cpu power domain,
|
||||
* or else the active processors might be stalled when the individual
|
||||
* processor is powered down.
|
||||
*/
|
||||
if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
|
||||
struct reset_control *rstc = rockchip_get_core_reset(pd);
|
||||
|
||||
if (IS_ERR(rstc)) {
|
||||
pr_err("%s: could not get reset control for core %d\n",
|
||||
__func__, pd);
|
||||
return PTR_ERR(rstc);
|
||||
}
|
||||
|
||||
if (on)
|
||||
reset_control_deassert(rstc);
|
||||
else
|
||||
reset_control_assert(rstc);
|
||||
|
||||
reset_control_put(rstc);
|
||||
}
|
||||
if (!IS_ERR(rstc) && !on)
|
||||
reset_control_assert(rstc);
|
||||
|
||||
ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val);
|
||||
if (ret < 0) {
|
||||
|
@ -107,11 +100,17 @@ static int pmu_set_power_domain(int pd, bool on)
|
|||
ret = pmu_power_domain_is_on(pd);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: could not read power domain state\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ERR(rstc)) {
|
||||
if (on)
|
||||
reset_control_deassert(rstc);
|
||||
reset_control_put(rstc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -130,7 +129,7 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||
|
||||
if (cpu >= ncores) {
|
||||
pr_err("%s: cpu %d outside maximum number of cpus %d\n",
|
||||
__func__, cpu, ncores);
|
||||
__func__, cpu, ncores);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
@ -140,14 +139,19 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||
return ret;
|
||||
|
||||
if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
|
||||
/* We communicate with the bootrom to active the cpus other
|
||||
/*
|
||||
* We communicate with the bootrom to active the cpus other
|
||||
* than cpu0, after a blob of initialize code, they will
|
||||
* stay at wfe state, once they are actived, they will check
|
||||
* the mailbox:
|
||||
* sram_base_addr + 4: 0xdeadbeaf
|
||||
* sram_base_addr + 8: start address for pc
|
||||
* */
|
||||
udelay(10);
|
||||
* The cpu0 need to wait the other cpus other than cpu0 entering
|
||||
* the wfe state.The wait time is affected by many aspects.
|
||||
* (e.g: cpu frequency, bootrom frequency, sram frequency, ...)
|
||||
*/
|
||||
mdelay(1); /* ensure the cpus other than cpu0 to startup */
|
||||
|
||||
writel(virt_to_phys(secondary_startup), sram_base_addr + 8);
|
||||
writel(0xDEADBEAF, sram_base_addr + 4);
|
||||
dsb_sev();
|
||||
|
@ -317,6 +321,13 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
|
|||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static int rockchip_cpu_kill(unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
* We need a delay here to ensure that the dying CPU can finish
|
||||
* executing v7_coherency_exit() and reach the WFI/WFE state
|
||||
* prior to having the power domain disabled.
|
||||
*/
|
||||
mdelay(1);
|
||||
|
||||
pmu_set_power_domain(0 + cpu, false);
|
||||
return 1;
|
||||
}
|
||||
|
@ -324,7 +335,7 @@ static int rockchip_cpu_kill(unsigned int cpu)
|
|||
static void rockchip_cpu_die(unsigned int cpu)
|
||||
{
|
||||
v7_exit_coherency_flush(louis);
|
||||
while(1)
|
||||
while (1)
|
||||
cpu_do_idle();
|
||||
}
|
||||
#endif
|
||||
|
@ -337,4 +348,5 @@ static struct smp_operations rockchip_smp_ops __initdata = {
|
|||
.cpu_die = rockchip_cpu_die,
|
||||
#endif
|
||||
};
|
||||
|
||||
CPU_METHOD_OF_DECLARE(rk3066_smp, "rockchip,rk3066-smp", &rockchip_smp_ops);
|
||||
|
|
|
@ -45,9 +45,11 @@ static phys_addr_t rk3288_bootram_phy;
|
|||
|
||||
static struct regmap *pmu_regmap;
|
||||
static struct regmap *sgrf_regmap;
|
||||
static struct regmap *grf_regmap;
|
||||
|
||||
static u32 rk3288_pmu_pwr_mode_con;
|
||||
static u32 rk3288_sgrf_soc_con0;
|
||||
static u32 rk3288_sgrf_cpu_con0;
|
||||
|
||||
static inline u32 rk3288_l2_config(void)
|
||||
{
|
||||
|
@ -66,10 +68,37 @@ static void rk3288_config_bootdata(void)
|
|||
rkpm_bootdata_l2ctlr = rk3288_l2_config();
|
||||
}
|
||||
|
||||
#define GRF_UOC0_CON0 0x320
|
||||
#define GRF_UOC1_CON0 0x334
|
||||
#define GRF_UOC2_CON0 0x348
|
||||
#define GRF_SIDDQ BIT(13)
|
||||
|
||||
static bool rk3288_slp_disable_osc(void)
|
||||
{
|
||||
static const u32 reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0,
|
||||
GRF_UOC2_CON0 };
|
||||
u32 reg, i;
|
||||
|
||||
/*
|
||||
* if any usb phy is still on(GRF_SIDDQ==0), that means we need the
|
||||
* function of usb wakeup, so do not switch to 32khz, since the usb phy
|
||||
* clk does not connect to 32khz osc
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(reg_offset); i++) {
|
||||
regmap_read(grf_regmap, reg_offset[i], ®);
|
||||
if (!(reg & GRF_SIDDQ))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rk3288_slp_mode_set(int level)
|
||||
{
|
||||
u32 mode_set, mode_set1;
|
||||
bool osc_switch_to_32k = rk3288_slp_disable_osc();
|
||||
|
||||
regmap_read(sgrf_regmap, RK3288_SGRF_CPU_CON0, &rk3288_sgrf_cpu_con0);
|
||||
regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
|
||||
|
||||
regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
|
||||
|
@ -107,11 +136,13 @@ static void rk3288_slp_mode_set(int level)
|
|||
|
||||
if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
|
||||
/* arm off, logic deep sleep */
|
||||
mode_set |= BIT(PMU_BUS_PD_EN) |
|
||||
mode_set |= BIT(PMU_BUS_PD_EN) | BIT(PMU_PMU_USE_LF) |
|
||||
BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) |
|
||||
BIT(PMU_OSC_24M_DIS) | BIT(PMU_PMU_USE_LF) |
|
||||
BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN);
|
||||
|
||||
if (osc_switch_to_32k)
|
||||
mode_set |= BIT(PMU_OSC_24M_DIS);
|
||||
|
||||
mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
|
||||
BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
|
||||
} else {
|
||||
|
@ -129,6 +160,9 @@ static void rk3288_slp_mode_set(int level)
|
|||
|
||||
static void rk3288_slp_mode_set_resume(void)
|
||||
{
|
||||
regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0,
|
||||
rk3288_sgrf_cpu_con0 | SGRF_DAPDEVICEEN_WRITE);
|
||||
|
||||
regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON,
|
||||
rk3288_pmu_pwr_mode_con);
|
||||
|
||||
|
@ -193,6 +227,13 @@ static int rk3288_suspend_init(struct device_node *np)
|
|||
return PTR_ERR(pmu_regmap);
|
||||
}
|
||||
|
||||
grf_regmap = syscon_regmap_lookup_by_compatible(
|
||||
"rockchip,rk3288-grf");
|
||||
if (IS_ERR(grf_regmap)) {
|
||||
pr_err("%s: could not find grf regmap\n", __func__);
|
||||
return PTR_ERR(pmu_regmap);
|
||||
}
|
||||
|
||||
sram_np = of_find_compatible_node(NULL, NULL,
|
||||
"rockchip,rk3288-pmu-sram");
|
||||
if (!sram_np) {
|
||||
|
|
|
@ -59,13 +59,6 @@ static inline void rockchip_suspend_init(void)
|
|||
#define SGRF_DAPDEVICEEN BIT(0)
|
||||
#define SGRF_DAPDEVICEEN_WRITE BIT(16)
|
||||
|
||||
#define RK3288_CRU_MODE_CON 0x50
|
||||
#define RK3288_CRU_SEL0_CON 0x60
|
||||
#define RK3288_CRU_SEL1_CON 0x64
|
||||
#define RK3288_CRU_SEL10_CON 0x88
|
||||
#define RK3288_CRU_SEL33_CON 0xe4
|
||||
#define RK3288_CRU_SEL37_CON 0xf4
|
||||
|
||||
/* PMU_WAKEUP_CFG1 bits */
|
||||
#define PMU_ARMINT_WAKEUP_EN BIT(0)
|
||||
|
||||
|
|
Loading…
Reference in New Issue