1 From 8c2a00c0129d6f718245f7a613c2bb28976b7973 Mon Sep 17 00:00:00 2001
2 From: Kumar Gala <galak@codeaurora.org>
3 Date: Tue, 21 Jan 2014 17:14:10 -0600
4 Subject: [PATCH 005/182] ARM: qcom: Split Qualcomm support into legacy and
7 Introduce a new mach-qcom that will support SoCs that intend to be
8 multiplatform compatible while keeping mach-msm to legacy SoC/board
9 support that will not transition over to multiplatform.
11 As part of this, we move support for MSM8X60, MSM8960 and MSM8974 over
14 Signed-off-by: Kumar Gala <galak@codeaurora.org>
17 arch/arm/Kconfig | 7 +-
18 arch/arm/Kconfig.debug | 2 +-
19 arch/arm/Makefile | 1 +
20 arch/arm/boot/dts/Makefile | 6 +-
21 arch/arm/mach-msm/Kconfig | 45 +------
22 arch/arm/mach-msm/Makefile | 6 -
23 arch/arm/mach-msm/board-dt.c | 41 ------
24 arch/arm/mach-msm/platsmp.c | 137 -------------------
25 arch/arm/mach-msm/scm-boot.c | 39 ------
26 arch/arm/mach-msm/scm-boot.h | 22 ---
27 arch/arm/mach-msm/scm.c | 299 -----------------------------------------
28 arch/arm/mach-msm/scm.h | 25 ----
29 arch/arm/mach-qcom/Kconfig | 33 +++++
30 arch/arm/mach-qcom/Makefile | 5 +
31 arch/arm/mach-qcom/board.c | 40 ++++++
32 arch/arm/mach-qcom/platsmp.c | 137 +++++++++++++++++++
33 arch/arm/mach-qcom/scm-boot.c | 39 ++++++
34 arch/arm/mach-qcom/scm-boot.h | 22 +++
35 arch/arm/mach-qcom/scm.c | 299 +++++++++++++++++++++++++++++++++++++++++
36 arch/arm/mach-qcom/scm.h | 25 ++++
37 21 files changed, 619 insertions(+), 619 deletions(-)
38 delete mode 100644 arch/arm/mach-msm/board-dt.c
39 delete mode 100644 arch/arm/mach-msm/platsmp.c
40 delete mode 100644 arch/arm/mach-msm/scm-boot.c
41 delete mode 100644 arch/arm/mach-msm/scm-boot.h
42 delete mode 100644 arch/arm/mach-msm/scm.c
43 delete mode 100644 arch/arm/mach-msm/scm.h
44 create mode 100644 arch/arm/mach-qcom/Kconfig
45 create mode 100644 arch/arm/mach-qcom/Makefile
46 create mode 100644 arch/arm/mach-qcom/board.c
47 create mode 100644 arch/arm/mach-qcom/platsmp.c
48 create mode 100644 arch/arm/mach-qcom/scm-boot.c
49 create mode 100644 arch/arm/mach-qcom/scm-boot.h
50 create mode 100644 arch/arm/mach-qcom/scm.c
51 create mode 100644 arch/arm/mach-qcom/scm.h
53 diff --git a/MAINTAINERS b/MAINTAINERS
54 index 900d98e..7d23402 100644
57 @@ -1168,6 +1168,14 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
58 W: http://www.arm.linux.org.uk/
62 +M: Kumar Gala <galak@codeaurora.org>
63 +M: David Brown <davidb@codeaurora.org>
64 +L: linux-arm-msm@vger.kernel.org
66 +F: arch/arm/mach-qcom/
67 +T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
69 ARM/RADISYS ENP2611 MACHINE SUPPORT
70 M: Lennert Buytenhek <kernel@wantstofly.org>
71 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
72 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
73 index 1594945..d02ce70 100644
74 --- a/arch/arm/Kconfig
75 +++ b/arch/arm/Kconfig
76 @@ -657,9 +657,8 @@ config ARCH_PXA
78 Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
84 + bool "Qualcomm MSM (non-multiplatform)"
85 select ARCH_REQUIRE_GPIOLIB
87 select GENERIC_CLOCKEVENTS
88 @@ -1005,6 +1004,8 @@ source "arch/arm/plat-pxa/Kconfig"
90 source "arch/arm/mach-mmp/Kconfig"
92 +source "arch/arm/mach-qcom/Kconfig"
94 source "arch/arm/mach-realview/Kconfig"
96 source "arch/arm/mach-rockchip/Kconfig"
97 diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
98 index 0531da8..4491c7b 100644
99 --- a/arch/arm/Kconfig.debug
100 +++ b/arch/arm/Kconfig.debug
101 @@ -956,7 +956,7 @@ config DEBUG_STI_UART
103 config DEBUG_MSM_UART
105 - depends on ARCH_MSM
106 + depends on ARCH_MSM || ARCH_QCOM
108 config DEBUG_LL_INCLUDE
110 diff --git a/arch/arm/Makefile b/arch/arm/Makefile
111 index 08a9ef5..51e5bed 100644
112 --- a/arch/arm/Makefile
113 +++ b/arch/arm/Makefile
114 @@ -180,6 +180,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2
115 machine-$(CONFIG_ARCH_ORION5X) += orion5x
116 machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell
117 machine-$(CONFIG_ARCH_PXA) += pxa
118 +machine-$(CONFIG_ARCH_QCOM) += qcom
119 machine-$(CONFIG_ARCH_REALVIEW) += realview
120 machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip
121 machine-$(CONFIG_ARCH_RPC) += rpc
122 diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
123 index 0320303..4a89023 100644
124 --- a/arch/arm/boot/dts/Makefile
125 +++ b/arch/arm/boot/dts/Makefile
126 @@ -119,9 +119,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
127 kirkwood-ts219-6282.dtb
128 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
129 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
130 -dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
131 - qcom-msm8960-cdp.dtb \
132 - qcom-apq8074-dragonboard.dtb
133 dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
134 armada-370-mirabox.dtb \
135 armada-370-netgear-rn102.dtb \
136 @@ -234,6 +231,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
138 dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
139 dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
140 +dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
141 + qcom-msm8960-cdp.dtb \
142 + qcom-apq8074-dragonboard.dtb
143 dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
144 ste-hrefprev60-stuib.dtb \
145 ste-hrefprev60-tvk.dtb \
146 diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
147 index 3c4eca7..a7f959e 100644
148 --- a/arch/arm/mach-msm/Kconfig
149 +++ b/arch/arm/mach-msm/Kconfig
155 - bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7
157 - select ARCH_REQUIRE_GPIOLIB
159 - select GENERIC_CLOCKEVENTS
161 - Support for Qualcomm's devicetree based MSM systems.
165 -menu "Qualcomm MSM SoC Selection"
166 - depends on ARCH_MSM_DT
169 - bool "Enable support for MSM8X60"
173 - select MSM_SCM if SMP
177 - bool "Enable support for MSM8960"
181 - select MSM_SCM if SMP
185 - bool "Enable support for MSM8974"
188 - select HAVE_ARM_ARCH_TIMER
190 - select MSM_SCM if SMP
195 prompt "Qualcomm MSM SoC Type"
196 default ARCH_MSM7X00A
197 - depends on ARCH_MSM_NODT
198 + depends on ARCH_MSM
201 bool "MSM7x00A / MSM7x01A"
202 @@ -99,7 +58,7 @@ config MSM_VIC
205 menu "Qualcomm MSM Board Type"
206 - depends on ARCH_MSM_NODT
207 + depends on ARCH_MSM
211 diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
212 index 04b1bee..27c078a 100644
213 --- a/arch/arm/mach-msm/Makefile
214 +++ b/arch/arm/mach-msm/Makefile
215 @@ -13,17 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
217 obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
218 obj-$(CONFIG_MSM_SMD) += last_radio_log.o
219 -obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
221 -CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
223 -obj-$(CONFIG_SMP) += platsmp.o
225 obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
226 obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
227 obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
228 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
229 obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
230 -obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
231 obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
232 obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
233 diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
234 deleted file mode 100644
235 index 1f11d93..0000000
236 --- a/arch/arm/mach-msm/board-dt.c
239 -/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved.
241 - * This program is free software; you can redistribute it and/or modify
242 - * it under the terms of the GNU General Public License version 2 and
243 - * only version 2 as published by the Free Software Foundation.
245 - * This program is distributed in the hope that it will be useful,
246 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
247 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
248 - * GNU General Public License for more details.
251 -#include <linux/init.h>
252 -#include <linux/of.h>
253 -#include <linux/of_platform.h>
255 -#include <asm/mach/arch.h>
256 -#include <asm/mach/map.h>
260 -static const char * const msm_dt_match[] __initconst = {
261 - "qcom,msm8660-fluid",
262 - "qcom,msm8660-surf",
263 - "qcom,msm8960-cdp",
267 -static const char * const apq8074_dt_match[] __initconst = {
268 - "qcom,apq8074-dragonboard",
272 -DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
273 - .smp = smp_ops(msm_smp_ops),
274 - .dt_compat = msm_dt_match,
277 -DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)")
278 - .dt_compat = apq8074_dt_match,
280 diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
281 deleted file mode 100644
282 index 251a91e..0000000
283 --- a/arch/arm/mach-msm/platsmp.c
287 - * Copyright (C) 2002 ARM Ltd.
288 - * All Rights Reserved
289 - * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
291 - * This program is free software; you can redistribute it and/or modify
292 - * it under the terms of the GNU General Public License version 2 as
293 - * published by the Free Software Foundation.
296 -#include <linux/init.h>
297 -#include <linux/errno.h>
298 -#include <linux/delay.h>
299 -#include <linux/device.h>
300 -#include <linux/smp.h>
301 -#include <linux/io.h>
303 -#include <asm/cputype.h>
304 -#include <asm/smp_plat.h>
306 -#include "scm-boot.h"
309 -#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
310 -#define SCSS_CPU1CORE_RESET 0xD80
311 -#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
313 -extern void secondary_startup(void);
315 -static DEFINE_SPINLOCK(boot_lock);
317 -#ifdef CONFIG_HOTPLUG_CPU
318 -static void __ref msm_cpu_die(unsigned int cpu)
324 -static inline int get_core_count(void)
326 - /* 1 + the PART[1:0] field of MIDR */
327 - return ((read_cpuid_id() >> 4) & 3) + 1;
330 -static void msm_secondary_init(unsigned int cpu)
333 - * Synchronise with the boot thread.
335 - spin_lock(&boot_lock);
336 - spin_unlock(&boot_lock);
339 -static void prepare_cold_cpu(unsigned int cpu)
342 - ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
343 - SCM_FLAG_COLDBOOT_CPU1);
345 - void __iomem *sc1_base_ptr;
346 - sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
347 - if (sc1_base_ptr) {
348 - writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
349 - writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
350 - writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
351 - iounmap(sc1_base_ptr);
354 - printk(KERN_DEBUG "Failed to set secondary core boot "
358 -static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
360 - static int cold_boot_done;
362 - /* Only need to bring cpu out of reset this way once */
363 - if (cold_boot_done == false) {
364 - prepare_cold_cpu(cpu);
365 - cold_boot_done = true;
369 - * set synchronisation state between this boot processor
370 - * and the secondary one
372 - spin_lock(&boot_lock);
375 - * Send the secondary CPU a soft interrupt, thereby causing
376 - * the boot monitor to read the system wide flags register,
377 - * and branch to the address found there.
379 - arch_send_wakeup_ipi_mask(cpumask_of(cpu));
382 - * now the secondary core is starting up let it run its
383 - * calibrations, then wait for it to finish
385 - spin_unlock(&boot_lock);
391 - * Initialise the CPU possible map early - this describes the CPUs
392 - * which may be present or become present in the system. The msm8x60
393 - * does not support the ARM SCU, so just set the possible cpu mask to
396 -static void __init msm_smp_init_cpus(void)
398 - unsigned int i, ncores = get_core_count();
400 - if (ncores > nr_cpu_ids) {
401 - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
402 - ncores, nr_cpu_ids);
403 - ncores = nr_cpu_ids;
406 - for (i = 0; i < ncores; i++)
407 - set_cpu_possible(i, true);
410 -static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
414 -struct smp_operations msm_smp_ops __initdata = {
415 - .smp_init_cpus = msm_smp_init_cpus,
416 - .smp_prepare_cpus = msm_smp_prepare_cpus,
417 - .smp_secondary_init = msm_secondary_init,
418 - .smp_boot_secondary = msm_boot_secondary,
419 -#ifdef CONFIG_HOTPLUG_CPU
420 - .cpu_die = msm_cpu_die,
423 diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-msm/scm-boot.c
424 deleted file mode 100644
425 index 45cee3e..0000000
426 --- a/arch/arm/mach-msm/scm-boot.c
429 -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
431 - * This program is free software; you can redistribute it and/or modify
432 - * it under the terms of the GNU General Public License version 2 and
433 - * only version 2 as published by the Free Software Foundation.
435 - * This program is distributed in the hope that it will be useful,
436 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
437 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
438 - * GNU General Public License for more details.
440 - * You should have received a copy of the GNU General Public License
441 - * along with this program; if not, write to the Free Software
442 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
446 -#include <linux/module.h>
447 -#include <linux/slab.h>
450 -#include "scm-boot.h"
453 - * Set the cold/warm boot address for one of the CPU cores.
455 -int scm_set_boot_addr(phys_addr_t addr, int flags)
458 - unsigned int flags;
464 - return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
465 - &cmd, sizeof(cmd), NULL, 0);
467 -EXPORT_SYMBOL(scm_set_boot_addr);
468 diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
469 deleted file mode 100644
470 index 7be32ff..0000000
471 --- a/arch/arm/mach-msm/scm-boot.h
474 -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
476 - * This program is free software; you can redistribute it and/or modify
477 - * it under the terms of the GNU General Public License version 2 and
478 - * only version 2 as published by the Free Software Foundation.
480 - * This program is distributed in the hope that it will be useful,
481 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
482 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
483 - * GNU General Public License for more details.
485 -#ifndef __MACH_SCM_BOOT_H
486 -#define __MACH_SCM_BOOT_H
488 -#define SCM_BOOT_ADDR 0x1
489 -#define SCM_FLAG_COLDBOOT_CPU1 0x1
490 -#define SCM_FLAG_WARMBOOT_CPU1 0x2
491 -#define SCM_FLAG_WARMBOOT_CPU0 0x4
493 -int scm_set_boot_addr(phys_addr_t addr, int flags);
496 diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
497 deleted file mode 100644
498 index c536fd6..0000000
499 --- a/arch/arm/mach-msm/scm.c
502 -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
504 - * This program is free software; you can redistribute it and/or modify
505 - * it under the terms of the GNU General Public License version 2 and
506 - * only version 2 as published by the Free Software Foundation.
508 - * This program is distributed in the hope that it will be useful,
509 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
510 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
511 - * GNU General Public License for more details.
513 - * You should have received a copy of the GNU General Public License
514 - * along with this program; if not, write to the Free Software
515 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
519 -#include <linux/slab.h>
520 -#include <linux/io.h>
521 -#include <linux/module.h>
522 -#include <linux/mutex.h>
523 -#include <linux/errno.h>
524 -#include <linux/err.h>
526 -#include <asm/cacheflush.h>
530 -/* Cache line size for msm8x60 */
531 -#define CACHELINESIZE 32
533 -#define SCM_ENOMEM -5
534 -#define SCM_EOPNOTSUPP -4
535 -#define SCM_EINVAL_ADDR -3
536 -#define SCM_EINVAL_ARG -2
537 -#define SCM_ERROR -1
538 -#define SCM_INTERRUPTED 1
540 -static DEFINE_MUTEX(scm_lock);
543 - * struct scm_command - one SCM command buffer
544 - * @len: total available memory for command and response
545 - * @buf_offset: start of command buffer
546 - * @resp_hdr_offset: start of response buffer
547 - * @id: command to be executed
548 - * @buf: buffer returned from scm_get_command_buffer()
550 - * An SCM command is laid out in memory as follows:
552 - * ------------------- <--- struct scm_command
553 - * | command header |
554 - * ------------------- <--- scm_get_command_buffer()
555 - * | command buffer |
556 - * ------------------- <--- struct scm_response and
557 - * | response header | scm_command_to_response()
558 - * ------------------- <--- scm_get_response_buffer()
559 - * | response buffer |
560 - * -------------------
562 - * There can be arbitrary padding between the headers and buffers so
563 - * you should always use the appropriate scm_get_*_buffer() routines
564 - * to access the buffers in a safe manner.
566 -struct scm_command {
569 - u32 resp_hdr_offset;
575 - * struct scm_response - one SCM response buffer
576 - * @len: total available memory for response
577 - * @buf_offset: start of response data relative to start of scm_response
578 - * @is_complete: indicates if the command has finished processing
580 -struct scm_response {
587 - * alloc_scm_command() - Allocate an SCM command
588 - * @cmd_size: size of the command buffer
589 - * @resp_size: size of the response buffer
591 - * Allocate an SCM command, including enough room for the command
592 - * and response headers as well as the command and response buffers.
594 - * Returns a valid &scm_command on success or %NULL if the allocation fails.
596 -static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
598 - struct scm_command *cmd;
599 - size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
602 - cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
605 - cmd->buf_offset = offsetof(struct scm_command, buf);
606 - cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
612 - * free_scm_command() - Free an SCM command
613 - * @cmd: command to free
615 - * Free an SCM command.
617 -static inline void free_scm_command(struct scm_command *cmd)
623 - * scm_command_to_response() - Get a pointer to a scm_response
626 - * Returns a pointer to a response for a command.
628 -static inline struct scm_response *scm_command_to_response(
629 - const struct scm_command *cmd)
631 - return (void *)cmd + cmd->resp_hdr_offset;
635 - * scm_get_command_buffer() - Get a pointer to a command buffer
638 - * Returns a pointer to the command buffer of a command.
640 -static inline void *scm_get_command_buffer(const struct scm_command *cmd)
642 - return (void *)cmd->buf;
646 - * scm_get_response_buffer() - Get a pointer to a response buffer
649 - * Returns a pointer to a response buffer of a response.
651 -static inline void *scm_get_response_buffer(const struct scm_response *rsp)
653 - return (void *)rsp + rsp->buf_offset;
656 -static int scm_remap_error(int err)
661 - case SCM_EINVAL_ADDR:
662 - case SCM_EINVAL_ARG:
664 - case SCM_EOPNOTSUPP:
665 - return -EOPNOTSUPP;
672 -static u32 smc(u32 cmd_addr)
675 - register u32 r0 asm("r0") = 1;
676 - register u32 r1 asm("r1") = (u32)&context_id;
677 - register u32 r2 asm("r2") = cmd_addr;
680 - __asmeq("%0", "r0")
681 - __asmeq("%1", "r0")
682 - __asmeq("%2", "r1")
683 - __asmeq("%3", "r2")
685 - ".arch_extension sec\n"
687 - "smc #0 @ switch to secure world\n"
689 - : "r" (r0), "r" (r1), "r" (r2)
691 - } while (r0 == SCM_INTERRUPTED);
696 -static int __scm_call(const struct scm_command *cmd)
699 - u32 cmd_addr = virt_to_phys(cmd);
702 - * Flush the entire cache here so callers don't have to remember
703 - * to flush the cache when passing physical addresses to the secure
704 - * side in the buffer.
707 - ret = smc(cmd_addr);
709 - ret = scm_remap_error(ret);
715 - * scm_call() - Send an SCM command
716 - * @svc_id: service identifier
717 - * @cmd_id: command identifier
718 - * @cmd_buf: command buffer
719 - * @cmd_len: length of the command buffer
720 - * @resp_buf: response buffer
721 - * @resp_len: length of the response buffer
723 - * Sends a command to the SCM and waits for the command to finish processing.
725 -int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
726 - void *resp_buf, size_t resp_len)
729 - struct scm_command *cmd;
730 - struct scm_response *rsp;
732 - cmd = alloc_scm_command(cmd_len, resp_len);
736 - cmd->id = (svc_id << 10) | cmd_id;
738 - memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
740 - mutex_lock(&scm_lock);
741 - ret = __scm_call(cmd);
742 - mutex_unlock(&scm_lock);
746 - rsp = scm_command_to_response(cmd);
748 - u32 start = (u32)rsp;
749 - u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
750 - start &= ~(CACHELINESIZE - 1);
751 - while (start < end) {
752 - asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
754 - start += CACHELINESIZE;
756 - } while (!rsp->is_complete);
759 - memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
761 - free_scm_command(cmd);
764 -EXPORT_SYMBOL(scm_call);
766 -u32 scm_get_version(void)
769 - static u32 version = -1;
770 - register u32 r0 asm("r0");
771 - register u32 r1 asm("r1");
776 - mutex_lock(&scm_lock);
779 - r1 = (u32)&context_id;
782 - __asmeq("%0", "r0")
783 - __asmeq("%1", "r1")
784 - __asmeq("%2", "r0")
785 - __asmeq("%3", "r1")
787 - ".arch_extension sec\n"
789 - "smc #0 @ switch to secure world\n"
790 - : "=r" (r0), "=r" (r1)
791 - : "r" (r0), "r" (r1)
793 - } while (r0 == SCM_INTERRUPTED);
796 - mutex_unlock(&scm_lock);
800 -EXPORT_SYMBOL(scm_get_version);
801 diff --git a/arch/arm/mach-msm/scm.h b/arch/arm/mach-msm/scm.h
802 deleted file mode 100644
803 index 00b31ea..0000000
804 --- a/arch/arm/mach-msm/scm.h
807 -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
809 - * This program is free software; you can redistribute it and/or modify
810 - * it under the terms of the GNU General Public License version 2 and
811 - * only version 2 as published by the Free Software Foundation.
813 - * This program is distributed in the hope that it will be useful,
814 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
815 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
816 - * GNU General Public License for more details.
818 -#ifndef __MACH_SCM_H
819 -#define __MACH_SCM_H
821 -#define SCM_SVC_BOOT 0x1
822 -#define SCM_SVC_PIL 0x2
824 -extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
825 - void *resp_buf, size_t resp_len);
827 -#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
829 -extern u32 scm_get_version(void);
832 diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
834 index 0000000..a028be2
836 +++ b/arch/arm/mach-qcom/Kconfig
839 + bool "Qualcomm Support" if ARCH_MULTI_V7
840 + select ARCH_REQUIRE_GPIOLIB
843 + select GENERIC_CLOCKEVENTS
845 + select QCOM_SCM if SMP
847 + Support for Qualcomm's devicetree based systems.
851 +menu "Qualcomm SoC Selection"
854 + bool "Enable support for MSM8X60"
858 + bool "Enable support for MSM8960"
862 + bool "Enable support for MSM8974"
863 + select HAVE_ARM_ARCH_TIMER
871 diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
873 index 0000000..8f756ae
875 +++ b/arch/arm/mach-qcom/Makefile
878 +obj-$(CONFIG_SMP) += platsmp.o
879 +obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
881 +CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
882 diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
884 index 0000000..4529f6b
886 +++ b/arch/arm/mach-qcom/board.c
888 +/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
890 + * This program is free software; you can redistribute it and/or modify
891 + * it under the terms of the GNU General Public License version 2 and
892 + * only version 2 as published by the Free Software Foundation.
894 + * This program is distributed in the hope that it will be useful,
895 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
896 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
897 + * GNU General Public License for more details.
900 +#include <linux/init.h>
901 +#include <linux/of.h>
902 +#include <linux/of_platform.h>
904 +#include <asm/mach/arch.h>
905 +#include <asm/mach/map.h>
907 +extern struct smp_operations msm_smp_ops;
909 +static const char * const qcom_dt_match[] __initconst = {
910 + "qcom,msm8660-surf",
911 + "qcom,msm8960-cdp",
915 +static const char * const apq8074_dt_match[] __initconst = {
916 + "qcom,apq8074-dragonboard",
920 +DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
921 + .smp = smp_ops(msm_smp_ops),
922 + .dt_compat = qcom_dt_match,
925 +DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
926 + .dt_compat = apq8074_dt_match,
928 diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
930 index 0000000..67823a7
932 +++ b/arch/arm/mach-qcom/platsmp.c
935 + * Copyright (C) 2002 ARM Ltd.
936 + * All Rights Reserved
937 + * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
938 + * Copyright (c) 2014 The Linux Foundation. All rights reserved.
940 + * This program is free software; you can redistribute it and/or modify
941 + * it under the terms of the GNU General Public License version 2 as
942 + * published by the Free Software Foundation.
945 +#include <linux/init.h>
946 +#include <linux/errno.h>
947 +#include <linux/delay.h>
948 +#include <linux/device.h>
949 +#include <linux/smp.h>
950 +#include <linux/io.h>
952 +#include <asm/cputype.h>
953 +#include <asm/smp_plat.h>
955 +#include "scm-boot.h"
957 +#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
958 +#define SCSS_CPU1CORE_RESET 0xD80
959 +#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
961 +extern void secondary_startup(void);
963 +static DEFINE_SPINLOCK(boot_lock);
965 +#ifdef CONFIG_HOTPLUG_CPU
966 +static void __ref msm_cpu_die(unsigned int cpu)
972 +static inline int get_core_count(void)
974 + /* 1 + the PART[1:0] field of MIDR */
975 + return ((read_cpuid_id() >> 4) & 3) + 1;
978 +static void msm_secondary_init(unsigned int cpu)
981 + * Synchronise with the boot thread.
983 + spin_lock(&boot_lock);
984 + spin_unlock(&boot_lock);
987 +static void prepare_cold_cpu(unsigned int cpu)
990 + ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
991 + SCM_FLAG_COLDBOOT_CPU1);
993 + void __iomem *sc1_base_ptr;
994 + sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
995 + if (sc1_base_ptr) {
996 + writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
997 + writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
998 + writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
999 + iounmap(sc1_base_ptr);
1002 + printk(KERN_DEBUG "Failed to set secondary core boot "
1006 +static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
1008 + static int cold_boot_done;
1010 + /* Only need to bring cpu out of reset this way once */
1011 + if (cold_boot_done == false) {
1012 + prepare_cold_cpu(cpu);
1013 + cold_boot_done = true;
1017 + * set synchronisation state between this boot processor
1018 + * and the secondary one
1020 + spin_lock(&boot_lock);
1023 + * Send the secondary CPU a soft interrupt, thereby causing
1024 + * the boot monitor to read the system wide flags register,
1025 + * and branch to the address found there.
1027 + arch_send_wakeup_ipi_mask(cpumask_of(cpu));
1030 + * now the secondary core is starting up let it run its
1031 + * calibrations, then wait for it to finish
1033 + spin_unlock(&boot_lock);
1039 + * Initialise the CPU possible map early - this describes the CPUs
1040 + * which may be present or become present in the system. The msm8x60
1041 + * does not support the ARM SCU, so just set the possible cpu mask to
1044 +static void __init msm_smp_init_cpus(void)
1046 + unsigned int i, ncores = get_core_count();
1048 + if (ncores > nr_cpu_ids) {
1049 + pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
1050 + ncores, nr_cpu_ids);
1051 + ncores = nr_cpu_ids;
1054 + for (i = 0; i < ncores; i++)
1055 + set_cpu_possible(i, true);
1058 +static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
1062 +struct smp_operations msm_smp_ops __initdata = {
1063 + .smp_init_cpus = msm_smp_init_cpus,
1064 + .smp_prepare_cpus = msm_smp_prepare_cpus,
1065 + .smp_secondary_init = msm_secondary_init,
1066 + .smp_boot_secondary = msm_boot_secondary,
1067 +#ifdef CONFIG_HOTPLUG_CPU
1068 + .cpu_die = msm_cpu_die,
1071 diff --git a/arch/arm/mach-qcom/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
1072 new file mode 100644
1073 index 0000000..45cee3e
1075 +++ b/arch/arm/mach-qcom/scm-boot.c
1077 +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
1079 + * This program is free software; you can redistribute it and/or modify
1080 + * it under the terms of the GNU General Public License version 2 and
1081 + * only version 2 as published by the Free Software Foundation.
1083 + * This program is distributed in the hope that it will be useful,
1084 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1085 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1086 + * GNU General Public License for more details.
1088 + * You should have received a copy of the GNU General Public License
1089 + * along with this program; if not, write to the Free Software
1090 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1091 + * 02110-1301, USA.
1094 +#include <linux/module.h>
1095 +#include <linux/slab.h>
1098 +#include "scm-boot.h"
1101 + * Set the cold/warm boot address for one of the CPU cores.
1103 +int scm_set_boot_addr(phys_addr_t addr, int flags)
1106 + unsigned int flags;
1111 + cmd.flags = flags;
1112 + return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
1113 + &cmd, sizeof(cmd), NULL, 0);
1115 +EXPORT_SYMBOL(scm_set_boot_addr);
1116 diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
1117 new file mode 100644
1118 index 0000000..7be32ff
1120 +++ b/arch/arm/mach-qcom/scm-boot.h
1122 +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
1124 + * This program is free software; you can redistribute it and/or modify
1125 + * it under the terms of the GNU General Public License version 2 and
1126 + * only version 2 as published by the Free Software Foundation.
1128 + * This program is distributed in the hope that it will be useful,
1129 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1130 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1131 + * GNU General Public License for more details.
1133 +#ifndef __MACH_SCM_BOOT_H
1134 +#define __MACH_SCM_BOOT_H
1136 +#define SCM_BOOT_ADDR 0x1
1137 +#define SCM_FLAG_COLDBOOT_CPU1 0x1
1138 +#define SCM_FLAG_WARMBOOT_CPU1 0x2
1139 +#define SCM_FLAG_WARMBOOT_CPU0 0x4
1141 +int scm_set_boot_addr(phys_addr_t addr, int flags);
1144 diff --git a/arch/arm/mach-qcom/scm.c b/arch/arm/mach-qcom/scm.c
1145 new file mode 100644
1146 index 0000000..c536fd6
1148 +++ b/arch/arm/mach-qcom/scm.c
1150 +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
1152 + * This program is free software; you can redistribute it and/or modify
1153 + * it under the terms of the GNU General Public License version 2 and
1154 + * only version 2 as published by the Free Software Foundation.
1156 + * This program is distributed in the hope that it will be useful,
1157 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1158 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1159 + * GNU General Public License for more details.
1161 + * You should have received a copy of the GNU General Public License
1162 + * along with this program; if not, write to the Free Software
1163 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1164 + * 02110-1301, USA.
1167 +#include <linux/slab.h>
1168 +#include <linux/io.h>
1169 +#include <linux/module.h>
1170 +#include <linux/mutex.h>
1171 +#include <linux/errno.h>
1172 +#include <linux/err.h>
1174 +#include <asm/cacheflush.h>
1178 +/* Cache line size for msm8x60 */
1179 +#define CACHELINESIZE 32
1181 +#define SCM_ENOMEM -5
1182 +#define SCM_EOPNOTSUPP -4
1183 +#define SCM_EINVAL_ADDR -3
1184 +#define SCM_EINVAL_ARG -2
1185 +#define SCM_ERROR -1
1186 +#define SCM_INTERRUPTED 1
1188 +static DEFINE_MUTEX(scm_lock);
1191 + * struct scm_command - one SCM command buffer
1192 + * @len: total available memory for command and response
1193 + * @buf_offset: start of command buffer
1194 + * @resp_hdr_offset: start of response buffer
1195 + * @id: command to be executed
1196 + * @buf: buffer returned from scm_get_command_buffer()
1198 + * An SCM command is laid out in memory as follows:
1200 + * ------------------- <--- struct scm_command
1201 + * | command header |
1202 + * ------------------- <--- scm_get_command_buffer()
1203 + * | command buffer |
1204 + * ------------------- <--- struct scm_response and
1205 + * | response header | scm_command_to_response()
1206 + * ------------------- <--- scm_get_response_buffer()
1207 + * | response buffer |
1208 + * -------------------
1210 + * There can be arbitrary padding between the headers and buffers so
1211 + * you should always use the appropriate scm_get_*_buffer() routines
1212 + * to access the buffers in a safe manner.
1214 +struct scm_command {
1217 + u32 resp_hdr_offset;
1223 + * struct scm_response - one SCM response buffer
1224 + * @len: total available memory for response
1225 + * @buf_offset: start of response data relative to start of scm_response
1226 + * @is_complete: indicates if the command has finished processing
1228 +struct scm_response {
1235 + * alloc_scm_command() - Allocate an SCM command
1236 + * @cmd_size: size of the command buffer
1237 + * @resp_size: size of the response buffer
1239 + * Allocate an SCM command, including enough room for the command
1240 + * and response headers as well as the command and response buffers.
1242 + * Returns a valid &scm_command on success or %NULL if the allocation fails.
1244 +static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
1246 + struct scm_command *cmd;
1247 + size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
1250 + cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
1253 + cmd->buf_offset = offsetof(struct scm_command, buf);
1254 + cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
1260 + * free_scm_command() - Free an SCM command
1261 + * @cmd: command to free
1263 + * Free an SCM command.
1265 +static inline void free_scm_command(struct scm_command *cmd)
1271 + * scm_command_to_response() - Get a pointer to a scm_response
1274 + * Returns a pointer to a response for a command.
1276 +static inline struct scm_response *scm_command_to_response(
1277 + const struct scm_command *cmd)
1279 + return (void *)cmd + cmd->resp_hdr_offset;
1283 + * scm_get_command_buffer() - Get a pointer to a command buffer
1286 + * Returns a pointer to the command buffer of a command.
1288 +static inline void *scm_get_command_buffer(const struct scm_command *cmd)
1290 + return (void *)cmd->buf;
1294 + * scm_get_response_buffer() - Get a pointer to a response buffer
1297 + * Returns a pointer to a response buffer of a response.
1299 +static inline void *scm_get_response_buffer(const struct scm_response *rsp)
1301 + return (void *)rsp + rsp->buf_offset;
1304 +static int scm_remap_error(int err)
1309 + case SCM_EINVAL_ADDR:
1310 + case SCM_EINVAL_ARG:
1312 + case SCM_EOPNOTSUPP:
1313 + return -EOPNOTSUPP;
1320 +static u32 smc(u32 cmd_addr)
1323 + register u32 r0 asm("r0") = 1;
1324 + register u32 r1 asm("r1") = (u32)&context_id;
1325 + register u32 r2 asm("r2") = cmd_addr;
1328 + __asmeq("%0", "r0")
1329 + __asmeq("%1", "r0")
1330 + __asmeq("%2", "r1")
1331 + __asmeq("%3", "r2")
1332 +#ifdef REQUIRES_SEC
1333 + ".arch_extension sec\n"
1335 + "smc #0 @ switch to secure world\n"
1337 + : "r" (r0), "r" (r1), "r" (r2)
1339 + } while (r0 == SCM_INTERRUPTED);
1344 +static int __scm_call(const struct scm_command *cmd)
1347 + u32 cmd_addr = virt_to_phys(cmd);
1350 + * Flush the entire cache here so callers don't have to remember
1351 + * to flush the cache when passing physical addresses to the secure
1352 + * side in the buffer.
1354 + flush_cache_all();
1355 + ret = smc(cmd_addr);
1357 + ret = scm_remap_error(ret);
1363 + * scm_call() - Send an SCM command
1364 + * @svc_id: service identifier
1365 + * @cmd_id: command identifier
1366 + * @cmd_buf: command buffer
1367 + * @cmd_len: length of the command buffer
1368 + * @resp_buf: response buffer
1369 + * @resp_len: length of the response buffer
1371 + * Sends a command to the SCM and waits for the command to finish processing.
1373 +int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
1374 + void *resp_buf, size_t resp_len)
1377 + struct scm_command *cmd;
1378 + struct scm_response *rsp;
1380 + cmd = alloc_scm_command(cmd_len, resp_len);
1384 + cmd->id = (svc_id << 10) | cmd_id;
1386 + memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
1388 + mutex_lock(&scm_lock);
1389 + ret = __scm_call(cmd);
1390 + mutex_unlock(&scm_lock);
1394 + rsp = scm_command_to_response(cmd);
1396 + u32 start = (u32)rsp;
1397 + u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
1398 + start &= ~(CACHELINESIZE - 1);
1399 + while (start < end) {
1400 + asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
1402 + start += CACHELINESIZE;
1404 + } while (!rsp->is_complete);
1407 + memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
1409 + free_scm_command(cmd);
1412 +EXPORT_SYMBOL(scm_call);
1414 +u32 scm_get_version(void)
1417 + static u32 version = -1;
1418 + register u32 r0 asm("r0");
1419 + register u32 r1 asm("r1");
1421 + if (version != -1)
1424 + mutex_lock(&scm_lock);
1427 + r1 = (u32)&context_id;
1430 + __asmeq("%0", "r0")
1431 + __asmeq("%1", "r1")
1432 + __asmeq("%2", "r0")
1433 + __asmeq("%3", "r1")
1434 +#ifdef REQUIRES_SEC
1435 + ".arch_extension sec\n"
1437 + "smc #0 @ switch to secure world\n"
1438 + : "=r" (r0), "=r" (r1)
1439 + : "r" (r0), "r" (r1)
1441 + } while (r0 == SCM_INTERRUPTED);
1444 + mutex_unlock(&scm_lock);
1448 +EXPORT_SYMBOL(scm_get_version);
1449 diff --git a/arch/arm/mach-qcom/scm.h b/arch/arm/mach-qcom/scm.h
1450 new file mode 100644
1451 index 0000000..00b31ea
1453 +++ b/arch/arm/mach-qcom/scm.h
1455 +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
1457 + * This program is free software; you can redistribute it and/or modify
1458 + * it under the terms of the GNU General Public License version 2 and
1459 + * only version 2 as published by the Free Software Foundation.
1461 + * This program is distributed in the hope that it will be useful,
1462 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1463 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1464 + * GNU General Public License for more details.
1466 +#ifndef __MACH_SCM_H
1467 +#define __MACH_SCM_H
1469 +#define SCM_SVC_BOOT 0x1
1470 +#define SCM_SVC_PIL 0x2
1472 +extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
1473 + void *resp_buf, size_t resp_len);
1475 +#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
1477 +extern u32 scm_get_version(void);