diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-10 14:56:23 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-10 14:56:23 -0800 | 
| commit | 56e0464980febfa50432a070261579415c72664e (patch) | |
| tree | ec4753abd2562c317ed5f33b81c156b319456fd5 /arch/arm/mach-mediatek | |
| parent | a5e1d715a8d0696961d99d31d869aa522f1cad5a (diff) | |
| parent | b1e4006aeda8c8784029de17d47987c21ea75f6d (diff) | |
| download | linux-56e0464980febfa50432a070261579415c72664e.tar.bz2 | |
Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates from Olof Johansson:
 "New and/or improved SoC support for this release:
  Marvell Berlin:
     - Enable standard DT-based cpufreq
     - Add CPU hotplug support
  Freescale:
     - Ethernet init for i.MX7D
     - Suspend/resume support for i.MX6UL
  Allwinner:
     - Support for R8 chipset (used on NTC's $9 C.H.I.P board)
  Mediatek:
     - SMP support for some platforms
  Uniphier:
     - L2 support
     - Cleaned up SMP support, etc.
  plus a handful of other patches around above functionality, and a few
  other smaller changes"
* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (42 commits)
  ARM: uniphier: rework SMP operations to use trampoline code
  ARM: uniphier: add outer cache support
  Documentation: EXYNOS: Update bootloader interface on exynos542x
  ARM: mvebu: add broken-idle option
  ARM: orion5x: use mac_pton() helper
  ARM: at91: pm: at91_pm_suspend_in_sram() must be 8-byte aligned
  ARM: sunxi: Add R8 support
  ARM: digicolor: select pinctrl/gpio driver
  arm: berlin: add CPU hotplug support
  arm: berlin: use non-self-cleared reset register to reset cpu
  ARM: mediatek: add smp bringup code
  ARM: mediatek: enable gpt6 on boot up to make arch timer working
  soc: mediatek: Fix random hang up issue while kernel init
  soc: ti: qmss: make acc queue support optional in the driver
  soc: ti: add firmware file name as part of the driver
  Documentation: dt: soc: Add description for knav qmss driver
  ARM: S3C64XX: Use PWM lookup table for mach-smartq
  ARM: S3C64XX: Use PWM lookup table for mach-hmt
  ARM: S3C64XX: Use PWM lookup table for mach-crag6410
  ARM: S3C64XX: Use PWM lookup table for smdk6410
  ...
Diffstat (limited to 'arch/arm/mach-mediatek')
| -rw-r--r-- | arch/arm/mach-mediatek/Makefile | 3 | ||||
| -rw-r--r-- | arch/arm/mach-mediatek/mediatek.c | 27 | ||||
| -rw-r--r-- | arch/arm/mach-mediatek/platsmp.c | 141 | 
3 files changed, 171 insertions, 0 deletions
| diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile index 43e619f56172..21164605b83f 100644 --- a/arch/arm/mach-mediatek/Makefile +++ b/arch/arm/mach-mediatek/Makefile @@ -1 +1,4 @@ +ifeq ($(CONFIG_SMP),y) +obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o +endif  obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c index a9549005097e..d019a080a559 100644 --- a/arch/arm/mach-mediatek/mediatek.c +++ b/arch/arm/mach-mediatek/mediatek.c @@ -16,6 +16,32 @@   */  #include <linux/init.h>  #include <asm/mach/arch.h> +#include <linux/of.h> +#include <linux/clk-provider.h> +#include <linux/clocksource.h> + + +#define GPT6_CON_MT65xx 0x10008060 +#define GPT_ENABLE      0x31 + +static void __init mediatek_timer_init(void) +{ +	void __iomem *gpt_base; + +	if (of_machine_is_compatible("mediatek,mt6589") || +	    of_machine_is_compatible("mediatek,mt8135") || +	    of_machine_is_compatible("mediatek,mt8127")) { +		/* turn on GPT6 which ungates arch timer clocks */ +		gpt_base = ioremap(GPT6_CON_MT65xx, 0x04); + +		/* enable clock and set to free-run */ +		writel(GPT_ENABLE, gpt_base); +		iounmap(gpt_base); +	} + +	of_clk_init(NULL); +	clocksource_probe(); +};  static const char * const mediatek_board_dt_compat[] = {  	"mediatek,mt6589", @@ -27,4 +53,5 @@ static const char * const mediatek_board_dt_compat[] = {  DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)")  	.dt_compat	= mediatek_board_dt_compat, +	.init_time	= mediatek_timer_init,  MACHINE_END diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c new file mode 100644 index 000000000000..8141f3f8afed --- /dev/null +++ b/arch/arm/mach-mediatek/platsmp.c @@ -0,0 +1,141 @@ +/* + * arch/arm/mach-mediatek/platsmp.c + * + * Copyright (c) 2014 Mediatek Inc. + * Author: Shunli Wang <shunli.wang@mediatek.com> + *         Yingjoe Chen <yingjoe.chen@mediatek.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + */ +#include <linux/io.h> +#include <linux/memblock.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/string.h> +#include <linux/threads.h> + +#define MTK_MAX_CPU		8 +#define MTK_SMP_REG_SIZE	0x1000 + +struct mtk_smp_boot_info { +	unsigned long smp_base; +	unsigned int jump_reg; +	unsigned int core_keys[MTK_MAX_CPU - 1]; +	unsigned int core_regs[MTK_MAX_CPU - 1]; +}; + +static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = { +	0x80002000, 0x3fc, +	{ 0x534c4131, 0x4c415332, 0x41534c33 }, +	{ 0x3f8, 0x3f8, 0x3f8 }, +}; + +static const struct mtk_smp_boot_info mtk_mt6589_boot = { +	0x10002000, 0x34, +	{ 0x534c4131, 0x4c415332, 0x41534c33 }, +	{ 0x38, 0x3c, 0x40 }, +}; + +static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { +	{ .compatible   = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot }, +	{ .compatible   = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot }, +}; + +static const struct of_device_id mtk_smp_boot_infos[] __initconst = { +	{ .compatible   = "mediatek,mt6589", .data = &mtk_mt6589_boot }, +}; + +static void __iomem *mtk_smp_base; +static const struct mtk_smp_boot_info *mtk_smp_info; + +static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ +	if (!mtk_smp_base) +		return -EINVAL; + +	if (!mtk_smp_info->core_keys[cpu-1]) +		return -EINVAL; + +	writel_relaxed(mtk_smp_info->core_keys[cpu-1], +		mtk_smp_base + mtk_smp_info->core_regs[cpu-1]); + +	arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + +	return 0; +} + +static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone) +{ +	int i, num; +	const struct of_device_id *infos; + +	if (trustzone) { +		num = ARRAY_SIZE(mtk_tz_smp_boot_infos); +		infos = mtk_tz_smp_boot_infos; +	} else { +		num = ARRAY_SIZE(mtk_smp_boot_infos); +		infos = mtk_smp_boot_infos; +	} + +	/* Find smp boot info for this SoC */ +	for (i = 0; i < num; i++) { +		if (of_machine_is_compatible(infos[i].compatible)) { +			mtk_smp_info = infos[i].data; +			break; +		} +	} + +	if (!mtk_smp_info) { +		pr_err("%s: Device is not supported\n", __func__); +		return; +	} + +	if (trustzone) { +		/* smp_base(trustzone-bootinfo) is reserved by device tree */ +		mtk_smp_base = phys_to_virt(mtk_smp_info->smp_base); +	} else { +		mtk_smp_base = ioremap(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE); +		if (!mtk_smp_base) { +			pr_err("%s: Can't remap %lx\n", __func__, +				mtk_smp_info->smp_base); +			return; +		} +	} + +	/* +	 * write the address of slave startup address into the system-wide +	 * jump register +	 */ +	writel_relaxed(virt_to_phys(secondary_startup_arm), +			mtk_smp_base + mtk_smp_info->jump_reg); +} + +static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus) +{ +	__mtk_smp_prepare_cpus(max_cpus, 1); +} + +static void __init mtk_smp_prepare_cpus(unsigned int max_cpus) +{ +	__mtk_smp_prepare_cpus(max_cpus, 0); +} + +static struct smp_operations mt81xx_tz_smp_ops __initdata = { +	.smp_prepare_cpus = mtk_tz_smp_prepare_cpus, +	.smp_boot_secondary = mtk_boot_secondary, +}; +CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops); + +static struct smp_operations mt6589_smp_ops __initdata = { +	.smp_prepare_cpus = mtk_smp_prepare_cpus, +	.smp_boot_secondary = mtk_boot_secondary, +}; +CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops); |