Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  arch/arm/mach-sti/platsmp.c
  4 *
  5 * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
  6 *		http://www.st.com
  7 *
  8 * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
  9 *
 10 *  Copyright (C) 2002 ARM Ltd.
 11 *  All Rights Reserved
 12 */
 13#include <linux/init.h>
 14#include <linux/errno.h>
 15#include <linux/delay.h>
 16#include <linux/smp.h>
 17#include <linux/io.h>
 18#include <linux/of.h>
 19#include <linux/of_address.h>
 20#include <linux/memblock.h>
 21
 22#include <asm/cacheflush.h>
 23#include <asm/smp_plat.h>
 24#include <asm/smp_scu.h>
 25
 26#include "smp.h"
 27
 28static u32 __iomem *cpu_strt_ptr;
 29
 30static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle)
 31{
 32	unsigned long entry_pa = __pa_symbol(secondary_startup);
 33
 34	/*
 35	 * Secondary CPU is initialised and started by a U-BOOTROM firmware.
 36	 * Secondary CPU is spinning and waiting for a write at cpu_strt_ptr.
 37	 * Writing secondary_startup address at cpu_strt_ptr makes it to
 38	 * jump directly to secondary_startup().
 39	 */
 40	__raw_writel(entry_pa, cpu_strt_ptr);
 41
 42	/* wmb so that data is actually written before cache flush is done */
 43	smp_wmb();
 44	sync_cache_w(cpu_strt_ptr);
 45
 46	return 0;
 47}
 48
 49static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
 50{
 51	struct device_node *np;
 52	void __iomem *scu_base;
 53	u32 release_phys;
 54	int cpu;
 55
 56	np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
 57
 58	if (np) {
 59		scu_base = of_iomap(np, 0);
 60		scu_enable(scu_base);
 61		of_node_put(np);
 62	}
 63
 64	if (max_cpus <= 1)
 65		return;
 66
 67	for_each_possible_cpu(cpu) {
 68
 69		np = of_get_cpu_node(cpu, NULL);
 70
 71		if (!np)
 72			continue;
 73
 74		if (of_property_read_u32(np, "cpu-release-addr",
 75						&release_phys)) {
 76			pr_err("CPU %d: missing or invalid cpu-release-addr "
 77				"property\n", cpu);
 78			continue;
 79		}
 80
 81		/*
 82		 * cpu-release-addr is usually configured in SBC DMEM but can
 83		 * also be in RAM.
 84		 */
 85
 86		if (!memblock_is_memory(release_phys))
 87			cpu_strt_ptr =
 88				ioremap(release_phys, sizeof(release_phys));
 89		else
 90			cpu_strt_ptr =
 91				(u32 __iomem *)phys_to_virt(release_phys);
 92
 93		set_cpu_possible(cpu, true);
 94	}
 95}
 96
 97const struct smp_operations sti_smp_ops __initconst = {
 98	.smp_prepare_cpus	= sti_smp_prepare_cpus,
 99	.smp_boot_secondary	= sti_boot_secondary,
100};
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  arch/arm/mach-sti/platsmp.c
  4 *
  5 * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
  6 *		http://www.st.com
  7 *
  8 * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
  9 *
 10 *  Copyright (C) 2002 ARM Ltd.
 11 *  All Rights Reserved
 12 */
 13#include <linux/init.h>
 14#include <linux/errno.h>
 15#include <linux/delay.h>
 16#include <linux/smp.h>
 17#include <linux/io.h>
 18#include <linux/of.h>
 19#include <linux/of_address.h>
 20#include <linux/memblock.h>
 21
 22#include <asm/cacheflush.h>
 23#include <asm/smp_plat.h>
 24#include <asm/smp_scu.h>
 25
 26#include "smp.h"
 27
 28static u32 __iomem *cpu_strt_ptr;
 29
 30static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle)
 31{
 32	unsigned long entry_pa = __pa_symbol(secondary_startup);
 33
 34	/*
 35	 * Secondary CPU is initialised and started by a U-BOOTROM firmware.
 36	 * Secondary CPU is spinning and waiting for a write at cpu_strt_ptr.
 37	 * Writing secondary_startup address at cpu_strt_ptr makes it to
 38	 * jump directly to secondary_startup().
 39	 */
 40	__raw_writel(entry_pa, cpu_strt_ptr);
 41
 42	/* wmb so that data is actually written before cache flush is done */
 43	smp_wmb();
 44	sync_cache_w(cpu_strt_ptr);
 45
 46	return 0;
 47}
 48
 49static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
 50{
 51	struct device_node *np;
 52	void __iomem *scu_base;
 53	u32 release_phys;
 54	int cpu;
 55
 56	np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
 57
 58	if (np) {
 59		scu_base = of_iomap(np, 0);
 60		scu_enable(scu_base);
 61		of_node_put(np);
 62	}
 63
 64	if (max_cpus <= 1)
 65		return;
 66
 67	for_each_possible_cpu(cpu) {
 68
 69		np = of_get_cpu_node(cpu, NULL);
 70
 71		if (!np)
 72			continue;
 73
 74		if (of_property_read_u32(np, "cpu-release-addr",
 75						&release_phys)) {
 76			pr_err("CPU %d: missing or invalid cpu-release-addr "
 77				"property\n", cpu);
 78			continue;
 79		}
 80
 81		/*
 82		 * cpu-release-addr is usually configured in SBC DMEM but can
 83		 * also be in RAM.
 84		 */
 85
 86		if (!memblock_is_memory(release_phys))
 87			cpu_strt_ptr =
 88				ioremap(release_phys, sizeof(release_phys));
 89		else
 90			cpu_strt_ptr =
 91				(u32 __iomem *)phys_to_virt(release_phys);
 92
 93		set_cpu_possible(cpu, true);
 94	}
 95}
 96
 97const struct smp_operations sti_smp_ops __initconst = {
 98	.smp_prepare_cpus	= sti_smp_prepare_cpus,
 99	.smp_boot_secondary	= sti_boot_secondary,
100};