arch/arm/mach-bcm/platsmp-brcmstb.c

Source file repositories/reference/linux-study-clean/arch/arm/mach-bcm/platsmp-brcmstb.c

File Facts

System
Linux kernel
Corpus path
arch/arm/mach-bcm/platsmp-brcmstb.c
Extension
.c
Size
8535 bytes
Lines
364
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

static inline void per_cpu_sw_state_wr(u32 cpu, int val) { }
#endif

static void __iomem *pwr_ctrl_get_base(u32 cpu)
{
	void __iomem *base = cpubiuctrl_block + cpu0_pwr_zone_ctrl_reg;
	base += (cpu_logical_map(cpu) * 4);
	return base;
}

static u32 pwr_ctrl_rd(u32 cpu)
{
	void __iomem *base = pwr_ctrl_get_base(cpu);
	return readl_relaxed(base);
}

static void pwr_ctrl_set(unsigned int cpu, u32 val, u32 mask)
{
	void __iomem *base = pwr_ctrl_get_base(cpu);
	writel((readl(base) & mask) | val, base);
}

static void pwr_ctrl_clr(unsigned int cpu, u32 val, u32 mask)
{
	void __iomem *base = pwr_ctrl_get_base(cpu);
	writel((readl(base) & mask) & ~val, base);
}

#define POLL_TMOUT_MS 500
static int pwr_ctrl_wait_tmout(unsigned int cpu, u32 set, u32 mask)
{
	const unsigned long timeo = jiffies + msecs_to_jiffies(POLL_TMOUT_MS);
	u32 tmp;

	do {
		tmp = pwr_ctrl_rd(cpu) & mask;
		if (!set == !tmp)
			return 0;
	} while (time_before(jiffies, timeo));

	tmp = pwr_ctrl_rd(cpu) & mask;
	if (!set == !tmp)
		return 0;

	return -ETIMEDOUT;
}

static void cpu_rst_cfg_set(u32 cpu, int set)
{
	u32 val;
	val = readl_relaxed(cpubiuctrl_block + cpu_rst_cfg_reg);
	if (set)
		val |= BIT(cpu_logical_map(cpu));
	else
		val &= ~BIT(cpu_logical_map(cpu));
	writel_relaxed(val, cpubiuctrl_block + cpu_rst_cfg_reg);
}

static void cpu_set_boot_addr(u32 cpu, unsigned long boot_addr)
{
	const int reg_ofs = cpu_logical_map(cpu) * 8;
	writel_relaxed(0, hif_cont_block + hif_cont_reg + reg_ofs);
	writel_relaxed(boot_addr, hif_cont_block + hif_cont_reg + 4 + reg_ofs);
}

static void brcmstb_cpu_boot(u32 cpu)
{
	/* Mark this CPU as "up" */
	per_cpu_sw_state_wr(cpu, 1);

	/*
	 * Set the reset vector to point to the secondary_startup
	 * routine
	 */
	cpu_set_boot_addr(cpu, __pa_symbol(secondary_startup));

	/* Unhalt the cpu */
	cpu_rst_cfg_set(cpu, 0);
}

static void brcmstb_cpu_power_on(u32 cpu)
{
	/*
	 * The secondary cores power was cut, so we must go through
	 * power-on initialization.
	 */
	pwr_ctrl_set(cpu, ZONE_MAN_ISO_CNTL_MASK, 0xffffff00);
	pwr_ctrl_set(cpu, ZONE_MANUAL_CONTROL_MASK, -1);
	pwr_ctrl_set(cpu, ZONE_RESERVED_1_MASK, -1);

Annotation

Implementation Notes