blob: 81f5330fe81d90f335914264bd28243076a5cc27 [file] [log] [blame]
Stephen Boyd25c4a0b2011-09-20 00:12:36 -07001/* Copyright (c) 2012, 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
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/elf.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/delay.h>
20
21#include <mach/msm_iomap.h>
22
23#include "peripheral-loader.h"
24#include "scm-pas.h"
25
26#define PPSS_RESET (MSM_CLK_CTL_BASE + 0x2594)
27#define PPSS_RESET_PROC_RESET 0x2
28#define PPSS_RESET_RESET 0x1
29#define PPSS_PROC_CLK_CTL (MSM_CLK_CTL_BASE + 0x2588)
30#define CLK_BRANCH_ENA 0x10
31#define PPSS_HCLK_CTL (MSM_CLK_CTL_BASE + 0x2580)
32#define CLK_HALT_DFAB_STATE (MSM_CLK_CTL_BASE + 0x2FC8)
33
34static int init_image_dsps(struct pil_desc *pil, const u8 *metadata,
35 size_t size)
36{
37 /* Bring memory and bus interface out of reset */
38 writel_relaxed(PPSS_RESET_PROC_RESET, PPSS_RESET);
39 writel_relaxed(CLK_BRANCH_ENA, PPSS_HCLK_CTL);
40 mb();
41 return 0;
42}
43
44static int reset_dsps(struct pil_desc *pil)
45{
46 writel_relaxed(CLK_BRANCH_ENA, PPSS_PROC_CLK_CTL);
47 while (readl_relaxed(CLK_HALT_DFAB_STATE) & BIT(18))
48 cpu_relax();
49 /* Bring DSPS out of reset */
50 writel_relaxed(0x0, PPSS_RESET);
51 return 0;
52}
53
54static int shutdown_dsps(struct pil_desc *pil)
55{
56 writel_relaxed(PPSS_RESET_PROC_RESET | PPSS_RESET_RESET, PPSS_RESET);
57 usleep_range(1000, 2000);
58 writel_relaxed(PPSS_RESET_PROC_RESET, PPSS_RESET);
59 writel_relaxed(0x0, PPSS_PROC_CLK_CTL);
60 return 0;
61}
62
63struct pil_reset_ops pil_dsps_ops = {
64 .init_image = init_image_dsps,
65 .auth_and_reset = reset_dsps,
66 .shutdown = shutdown_dsps,
67};
68
69static int init_image_dsps_trusted(struct pil_desc *pil, const u8 *metadata,
70 size_t size)
71{
72 return pas_init_image(PAS_DSPS, metadata, size);
73}
74
75static int reset_dsps_trusted(struct pil_desc *pil)
76{
77 return pas_auth_and_reset(PAS_DSPS);
78}
79
80static int shutdown_dsps_trusted(struct pil_desc *pil)
81{
82 return pas_shutdown(PAS_DSPS);
83}
84
85struct pil_reset_ops pil_dsps_ops_trusted = {
86 .init_image = init_image_dsps_trusted,
87 .auth_and_reset = reset_dsps_trusted,
88 .shutdown = shutdown_dsps_trusted,
89};
90
91static int __devinit pil_dsps_driver_probe(struct platform_device *pdev)
92{
93 struct pil_desc *desc;
94 struct pil_device *pil;
95
96 desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
97 if (!desc)
98 return -ENOMEM;
99
100 desc->name = pdev->dev.platform_data;
101 desc->dev = &pdev->dev;
102 desc->owner = THIS_MODULE;
103 if (pas_supported(PAS_DSPS) > 0) {
104 desc->ops = &pil_dsps_ops_trusted;
105 dev_info(&pdev->dev, "using secure boot\n");
106 } else {
107 desc->ops = &pil_dsps_ops;
108 dev_info(&pdev->dev, "using non-secure boot\n");
109 }
110 pil = msm_pil_register(desc);
111 if (IS_ERR(pil))
112 return PTR_ERR(pil);
113 platform_set_drvdata(pdev, pil);
114 return 0;
115}
116
117static int __devexit pil_dsps_driver_exit(struct platform_device *pdev)
118{
119 struct pil_device *pil = platform_get_drvdata(pdev);
120 msm_pil_unregister(pil);
121 return 0;
122}
123
124static struct platform_driver pil_dsps_driver = {
125 .probe = pil_dsps_driver_probe,
126 .remove = __devexit_p(pil_dsps_driver_exit),
127 .driver = {
128 .name = "pil_dsps",
129 .owner = THIS_MODULE,
130 },
131};
132
133static int __init pil_dsps_init(void)
134{
135 return platform_driver_register(&pil_dsps_driver);
136}
137module_init(pil_dsps_init);
138
139static void __exit pil_dsps_exit(void)
140{
141 platform_driver_unregister(&pil_dsps_driver);
142}
143module_exit(pil_dsps_exit);
144
145MODULE_DESCRIPTION("Support for booting sensors (DSPS) images");
146MODULE_LICENSE("GPL v2");