cregit-Linux how code gets into the kernel

Release 4.11 arch/arm/mach-hisi/hotplug.c

/*
 * Copyright (c) 2013 Linaro Ltd.
 * Copyright (c) 2013 Hisilicon Limited.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 */

#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include "core.h"

/* Sysctrl registers in Hi3620 SoC */

#define SCISOEN				0xc0

#define SCISODIS			0xc4

#define SCPERPWREN			0xd0

#define SCPERPWRDIS			0xd4

#define SCCPUCOREEN			0xf4

#define SCCPUCOREDIS			0xf8

#define SCPERCTRL0			0x200

#define SCCPURSTEN			0x410

#define SCCPURSTDIS			0x414

/*
 * bit definition in SCISOEN/SCPERPWREN/...
 *
 * CPU2_ISO_CTRL        (1 << 5)
 * CPU3_ISO_CTRL        (1 << 6)
 * ...
 */

#define CPU2_ISO_CTRL			(1 << 5)

/*
 * bit definition in SCPERCTRL0
 *
 * CPU0_WFI_MASK_CFG    (1 << 28)
 * CPU1_WFI_MASK_CFG    (1 << 29)
 * ...
 */

#define CPU0_WFI_MASK_CFG		(1 << 28)

/*
 * bit definition in SCCPURSTEN/...
 *
 * CPU0_SRST_REQ_EN     (1 << 0)
 * CPU1_SRST_REQ_EN     (1 << 1)
 * ...
 */

#define CPU0_HPM_SRST_REQ_EN		(1 << 22)

#define CPU0_DBG_SRST_REQ_EN		(1 << 12)

#define CPU0_NEON_SRST_REQ_EN		(1 << 4)

#define CPU0_SRST_REQ_EN		(1 << 0)


#define HIX5HD2_PERI_CRG20		0x50

#define CRG20_CPU1_RESET		(1 << 17)


#define HIX5HD2_PERI_PMC0		0x1000

#define PMC0_CPU1_WAIT_MTCOMS_ACK	(1 << 8)

#define PMC0_CPU1_PMC_ENABLE		(1 << 7)

#define PMC0_CPU1_POWERDOWN		(1 << 3)


#define HIP01_PERI9                    0x50

#define PERI9_CPU1_RESET               (1 << 1)

enum {
	
HI3620_CTRL,
	
ERROR_CTRL,
};


static void __iomem *ctrl_base;

static int id;


static void set_cpu_hi3620(int cpu, bool enable) { u32 val = 0; if (enable) { /* MTCMOS set */ if ((cpu == 2) || (cpu == 3)) writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), ctrl_base + SCPERPWREN); udelay(100); /* Enable core */ writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREEN); /* unreset */ val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN | CPU0_SRST_REQ_EN; writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS); /* reset */ val |= CPU0_HPM_SRST_REQ_EN; writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN); /* ISO disable */ if ((cpu == 2) || (cpu == 3)) writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), ctrl_base + SCISODIS); udelay(1); /* WFI Mask */ val = readl_relaxed(ctrl_base + SCPERCTRL0); val &= ~(CPU0_WFI_MASK_CFG << cpu); writel_relaxed(val, ctrl_base + SCPERCTRL0); /* Unreset */ val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN | CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN; writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS); } else { /* wfi mask */ val = readl_relaxed(ctrl_base + SCPERCTRL0); val |= (CPU0_WFI_MASK_CFG << cpu); writel_relaxed(val, ctrl_base + SCPERCTRL0); /* disable core*/ writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREDIS); if ((cpu == 2) || (cpu == 3)) { /* iso enable */ writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), ctrl_base + SCISOEN); udelay(1); } /* reset */ val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN | CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN; writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN); if ((cpu == 2) || (cpu == 3)) { /* MTCMOS unset */ writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), ctrl_base + SCPERPWRDIS); udelay(100); } } }

Contributors

PersonTokensPropCommitsCommitProp
Zhangfei Gao329100.00%1100.00%
Total329100.00%1100.00%


static int hi3xxx_hotplug_init(void) { struct device_node *node; node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); if (node) { ctrl_base = of_iomap(node, 0); id = HI3620_CTRL; return 0; } id = ERROR_CTRL; return -ENOENT; }

Contributors

PersonTokensPropCommitsCommitProp
Zhangfei Gao54100.00%1100.00%
Total54100.00%1100.00%


void hi3xxx_set_cpu(int cpu, bool enable) { if (!ctrl_base) { if (hi3xxx_hotplug_init() < 0) return; } if (id == HI3620_CTRL) set_cpu_hi3620(cpu, enable); }

Contributors

PersonTokensPropCommitsCommitProp
Zhangfei Gao39100.00%1100.00%
Total39100.00%1100.00%


static bool hix5hd2_hotplug_init(void) { struct device_node *np; np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl"); if (np) { ctrl_base = of_iomap(np, 0); return true; } return false; }

Contributors

PersonTokensPropCommitsCommitProp
Haifeng Yan45100.00%1100.00%
Total45100.00%1100.00%


void hix5hd2_set_cpu(int cpu, bool enable) { u32 val = 0; if (!ctrl_base) if (!hix5hd2_hotplug_init()) BUG(); if (enable) { /* power on cpu1 */ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_PMC0); val &= ~(PMC0_CPU1_WAIT_MTCOMS_ACK | PMC0_CPU1_POWERDOWN); val |= PMC0_CPU1_PMC_ENABLE; writel_relaxed(val, ctrl_base + HIX5HD2_PERI_PMC0); /* unreset */ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_CRG20); val &= ~CRG20_CPU1_RESET; writel_relaxed(val, ctrl_base + HIX5HD2_PERI_CRG20); } else { /* power down cpu1 */ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_PMC0); val |= PMC0_CPU1_PMC_ENABLE | PMC0_CPU1_POWERDOWN; val &= ~PMC0_CPU1_WAIT_MTCOMS_ACK; writel_relaxed(val, ctrl_base + HIX5HD2_PERI_PMC0); /* reset */ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_CRG20); val |= CRG20_CPU1_RESET; writel_relaxed(val, ctrl_base + HIX5HD2_PERI_CRG20); } }

Contributors

PersonTokensPropCommitsCommitProp
Haifeng Yan148100.00%1100.00%
Total148100.00%1100.00%


void hip01_set_cpu(int cpu, bool enable) { unsigned int temp; struct device_node *np; if (!ctrl_base) { np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl"); if (np) ctrl_base = of_iomap(np, 0); else BUG(); } if (enable) { /* reset on CPU1 */ temp = readl_relaxed(ctrl_base + HIP01_PERI9); temp |= PERI9_CPU1_RESET; writel_relaxed(temp, ctrl_base + HIP01_PERI9); udelay(50); /* unreset on CPU1 */ temp = readl_relaxed(ctrl_base + HIP01_PERI9); temp &= ~PERI9_CPU1_RESET; writel_relaxed(temp, ctrl_base + HIP01_PERI9); } }

Contributors

PersonTokensPropCommitsCommitProp
Wang Long113100.00%1100.00%
Total113100.00%1100.00%


static inline void cpu_enter_lowpower(void) { unsigned int v; flush_cache_all(); /* * Turn off coherency and L1 D-cache */ asm volatile( " mrc p15, 0, %0, c1, c0, 1\n" " bic %0, %0, #0x40\n" " mcr p15, 0, %0, c1, c0, 1\n" " mrc p15, 0, %0, c1, c0, 0\n" " bic %0, %0, #0x04\n" " mcr p15, 0, %0, c1, c0, 0\n" : "=&r" (v) : "r" (0) : "cc"); }

Contributors

PersonTokensPropCommitsCommitProp
Zhangfei Gao20100.00%1100.00%
Total20100.00%1100.00%

#ifdef CONFIG_HOTPLUG_CPU
void hi3xxx_cpu_die(unsigned int cpu) { cpu_enter_lowpower(); hi3xxx_set_cpu_jump(cpu, phys_to_virt(0)); cpu_do_idle(); /* We should have never returned from idle */ panic("cpu %d unexpectedly exit from shutdown\n", cpu); }

Contributors

PersonTokensPropCommitsCommitProp
Zhangfei Gao33100.00%1100.00%
Total33100.00%1100.00%


int hi3xxx_cpu_kill(unsigned int cpu) { unsigned long timeout = jiffies + msecs_to_jiffies(50); while (hi3xxx_get_cpu_jump(cpu)) if (time_after(jiffies, timeout)) return 0; hi3xxx_set_cpu(cpu, false); return 1; }

Contributors

PersonTokensPropCommitsCommitProp
Zhangfei Gao49100.00%1100.00%
Total49100.00%1100.00%


void hix5hd2_cpu_die(unsigned int cpu) { flush_cache_all(); hix5hd2_set_cpu(cpu, false); }

Contributors

PersonTokensPropCommitsCommitProp
Haifeng Yan19100.00%1100.00%
Total19100.00%1100.00%

#endif

Overall Contributors

PersonTokensPropCommitsCommitProp
Zhangfei Gao63063.51%125.00%
Haifeng Yan23623.79%125.00%
Wang Long12112.20%125.00%
Arnd Bergmann50.50%125.00%
Total992100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.