blob: 0fc068a6216f50258f316ff9f97230d4649610a4 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/io.h>
15
16#include <mach/msm_iomap.h>
17#include <mach/scm-io.h>
18
19#define SCM_IO_READ ((((0x5 << 10) | 0x1) << 12) | (0x2 << 8) | 0x1)
20#define SCM_IO_WRITE ((((0x5 << 10) | 0x2) << 12) | (0x2 << 8) | 0x2)
21
22#define BETWEEN(p, st, sz) ((p) >= (void __iomem *)(st) && \
23 (p) < ((void __iomem *)(st) + (sz)))
24#define XLATE(p, pst, vst) ((u32)((p) - (vst)) + (pst))
25
26static u32 __secure_readl(u32 addr)
27{
28 u32 context_id;
29 register u32 r0 asm("r0") = SCM_IO_READ;
30 register u32 r1 asm("r1") = (u32)&context_id;
31 register u32 r2 asm("r2") = addr;
32 asm(
33 __asmeq("%0", "r0")
34 __asmeq("%1", "r0")
35 __asmeq("%2", "r1")
36 __asmeq("%3", "r2")
37 "smc #0 @ switch to secure world\n"
38 : "=r" (r0)
39 : "r" (r0), "r" (r1), "r" (r2)
40 );
41 __iormb();
42 return r0;
43}
44
45u32 secure_readl(void __iomem *c)
46{
47 if (BETWEEN(c, MSM_MMSS_CLK_CTL_BASE, MSM_MMSS_CLK_CTL_SIZE))
48 return __secure_readl(XLATE(c, MSM_MMSS_CLK_CTL_PHYS,
49 MSM_MMSS_CLK_CTL_BASE));
50 else if (BETWEEN(c, MSM_TCSR_BASE, MSM_TCSR_SIZE))
51 return __secure_readl(XLATE(c, MSM_TCSR_PHYS, MSM_TCSR_BASE));
52 return readl(c);
53}
54EXPORT_SYMBOL(secure_readl);
55
56static void __secure_writel(u32 v, u32 addr)
57{
58 u32 context_id;
59 register u32 r0 asm("r0") = SCM_IO_WRITE;
60 register u32 r1 asm("r1") = (u32)&context_id;
61 register u32 r2 asm("r2") = addr;
62 register u32 r3 asm("r3") = v;
63
64 __iowmb();
65 asm(
66 __asmeq("%0", "r0")
67 __asmeq("%1", "r1")
68 __asmeq("%2", "r2")
69 __asmeq("%3", "r3")
70 "smc #0 @ switch to secure world\n"
71 : /* No return value */
72 : "r" (r0), "r" (r1), "r" (r2), "r" (r3)
73 );
74}
75
76void secure_writel(u32 v, void __iomem *c)
77{
78 if (BETWEEN(c, MSM_MMSS_CLK_CTL_BASE, MSM_MMSS_CLK_CTL_SIZE))
79 __secure_writel(v, XLATE(c, MSM_MMSS_CLK_CTL_PHYS,
80 MSM_MMSS_CLK_CTL_BASE));
81 else if (BETWEEN(c, MSM_TCSR_BASE, MSM_TCSR_SIZE))
82 __secure_writel(v, XLATE(c, MSM_TCSR_PHYS, MSM_TCSR_BASE));
83 else
84 writel(v, c);
85}
86EXPORT_SYMBOL(secure_writel);